一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語(yǔ)言|JavaScript|易語(yǔ)言|vb.net|

服務(wù)器之家 - 編程語(yǔ)言 - ASP.NET教程 - ASP.NET WebAPi(selfhost)實(shí)現(xiàn)文件同步或異步上傳

ASP.NET WebAPi(selfhost)實(shí)現(xiàn)文件同步或異步上傳

2020-03-28 13:18JeffckyWang ASP.NET教程

這篇文章主要介紹了ASP.NET WebAPi(selfhost)實(shí)現(xiàn)文件同步或異步上傳,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

前言
前面我們講過(guò)利用AngularJs上傳到WebAPi中進(jìn)行處理,同時(shí)我們?cè)贛VC系列中講過(guò)文件上傳,本文結(jié)合MVC+WebAPi來(lái)進(jìn)行文件的同步或者異步上傳,順便回顧下css和js,MVC作為客戶端,而WebAPi利用不依賴于IIS的selfhost模式作為服務(wù)端來(lái)接收客戶端的文件且其過(guò)程用Ajax來(lái)實(shí)現(xiàn),下面我們一起來(lái)看看。

同步上傳

多余的話不用講,我們直接看頁(yè)面。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<div class="container">
 <div>
  @if (ViewBag.Success != null)
  {
   <div class="alert alert-danger" role="alert">
    <strong>成功啦 !</strong> 成功上傳. <a href="@ViewBag.Success" target="_blank">open file</a>
   </div>
  }
  else if (ViewBag.Failed != null)
  {
   <div class="alert alert-danger" role="alert">
    <strong>失敗啦 !</strong> @ViewBag.Failed
   </div>
  }
 </div>
 @using (Html.BeginForm("SyncUpload", "Home", FormMethod.Post, new { role = "form", enctype = "multipart/form-data", @style = "margin-top:50px;" }))
 {
  <div class="form-group">
   <input type="file" id="file" name="file" />
  </div>
  <input type="submit" value="Submit" class="btn btn-primary" />
 }
</div>

上述我們直接上傳后通過(guò)上傳的狀態(tài)來(lái)顯示查看上傳文件路徑并訪問(wèn),就是這么簡(jiǎn)單。下面我們來(lái)MVC后臺(tái)邏輯

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
[HttpPost]
public ActionResult SyncUpload(HttpPostedFileBase file)
{
 using (var client = new HttpClient())
 {
  using (var content = new MultipartFormDataContent())
  {
   byte[] Bytes = new byte[file.InputStream.Length + 1];
   file.InputStream.Read(Bytes, 0, Bytes.Length);
   var fileContent = new ByteArrayContent(Bytes);
          //設(shè)置請(qǐng)求頭中的附件為文件名稱,以便在WebAPi中進(jìn)行獲取
   fileContent.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment") { FileName = file.FileName };
   content.Add(fileContent);
   var requestUri = "http://localhost:8084/api/upload/post";
   var result = client.PostAsync(requestUri, content).Result;
   if (result.StatusCode == System.Net.HttpStatusCode.Created)
   {
            //獲取到上傳文件地址,并渲染到視圖中進(jìn)行訪問(wèn)
    var m = result.Content.ReadAsStringAsync().Result;
    var list = JsonConvert.DeserializeObject<List<string>>(m);
    ViewBag.Success = list.FirstOrDefault();
 
   }
   else
   {
    ViewBag.Failed = "上傳失敗啦,狀態(tài)碼:" + result.StatusCode + ",原因:" + result.ReasonPhrase + ",錯(cuò)誤信息:" + result.Content.ToString();
   }
  }
 }
 return View();
}

注意:上述將獲取到文件字節(jié)流數(shù)組需要傳遞給 MultipartFormDataContent ,要不然傳遞到WebAPi時(shí)會(huì)獲取不到文件數(shù)據(jù)。

到這里為止在MVC中操作就已經(jīng)完畢,此時(shí)我們來(lái)看看在WebAPi中需要完成哪些操作。

(1)首先肯定需要判斷上傳的數(shù)據(jù)是否是MimeType類型。

?
1
2
3
4
if (!Request.Content.IsMimeMultipartContent())
{
 throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}

(2)我們肯定是需要重新生成一個(gè)文件名稱以免重復(fù),利用Guid或者Date或者其他。

?
1
2
string name = item.Headers.ContentDisposition.FileName.Replace("\"", "");
string newFileName = Guid.NewGuid().ToString("N") + Path.GetExtension(name);

(3)我們需要利用此類 MultipartFileStreamProvider 設(shè)置上傳路徑并將文件寫入到這個(gè)里面。

?
1
2
var provider = new MultipartFileStreamProvider(rootPath);
var task = Request.Content.ReadAsMultipartAsync(provider).....

(4) 返回上傳文件地址。

  return Request.CreateResponse(HttpStatusCode.Created, JsonConvert.SerializeObject(savedFilePath));
分步驟解析了這么多,組裝代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
public Task<HttpResponseMessage> Post()
{
 List<string> savedFilePath = new List<string>();
 if (!Request.Content.IsMimeMultipartContent())
 {
  throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
 }
 var substringBin = AppDomain.CurrentDomain.BaseDirectory.IndexOf("bin");
 var path = AppDomain.CurrentDomain.BaseDirectory.Substring(0, substringBin);
 string rootPath = path + "upload";
 var provider = new MultipartFileStreamProvider(rootPath);
 var task = Request.Content.ReadAsMultipartAsync(provider).
  ContinueWith<HttpResponseMessage>(t =>
  {
   if (t.IsCanceled || t.IsFaulted)
   {
    Request.CreateErrorResponse(HttpStatusCode.InternalServerError, t.Exception);
   }
   foreach (MultipartFileData item in provider.FileData)
   {
    try
    {
     string name = item.Headers.ContentDisposition.FileName.Replace("\"", "");
     string newFileName = Guid.NewGuid().ToString("N") + Path.GetExtension(name);
     File.Move(item.LocalFileName, Path.Combine(rootPath, newFileName));
               //Request.RequestUri.PathAndQury為需要去掉域名的后面地址
               //如上述請(qǐng)求為http://localhost:80824/api/upload/post,這就為api/upload/post
               //Request.RequestUri.AbsoluteUri則為http://localhost:8084/api/upload/post
     Uri baseuri = new Uri(Request.RequestUri.AbsoluteUri.Replace(Request.RequestUri.PathAndQuery, string.Empty));
     string fileRelativePath = rootPath +"\\"+ newFileName;
     Uri fileFullPath = new Uri(baseuri, fileRelativePath);
     savedFilePath.Add(fileFullPath.ToString());
    }
    catch (Exception ex)
    {
     string message = ex.Message;
    }
   }
 
   return Request.CreateResponse(HttpStatusCode.Created, JsonConvert.SerializeObject(savedFilePath));
  });
 return task;
}

注意:上述item.LocalFileName為 E:\Documents\Visual Studio 2013\Projects\WebAPiReturnHtml\WebAPiReturnHtml\upload\BodyPart_fa01ff79-4a5b-40f6-887f-ab514ec6636f ,因?yàn)榇藭r(shí)我們重新命名了文件名稱,所以需要將該文件移動(dòng)到我們重新命名的文件地址。

整個(gè)過(guò)程就是這么簡(jiǎn)單,下面我們來(lái)看看演示結(jié)果。

ASP.NET WebAPi(selfhost)實(shí)現(xiàn)文件同步或異步上傳

此時(shí)居然出錯(cuò)了,有點(diǎn)耐人尋味,在服務(wù)端是返回如下的Json字符串

 

復(fù)制代碼 代碼如下:
List<string> savedFilePath = new List<string>();

 

此時(shí)進(jìn)行反序列化時(shí)居然出錯(cuò),再來(lái)看看頁(yè)面上的錯(cuò)誤信息:

ASP.NET WebAPi(selfhost)實(shí)現(xiàn)文件同步或異步上傳

無(wú)法將字符串轉(zhuǎn)換為L(zhǎng)ist<string>,這不是一一對(duì)應(yīng)的么,好吧,我來(lái)看看返回的字符串到底是怎樣的,【當(dāng)將鼠標(biāo)放上去】時(shí)查看的如下:

ASP.NET WebAPi(selfhost)實(shí)現(xiàn)文件同步或異步上傳

【當(dāng)將點(diǎn)擊查看】時(shí)結(jié)果如下:

ASP.NET WebAPi(selfhost)實(shí)現(xiàn)文件同步或異步上傳

由上知點(diǎn)擊查看按鈕時(shí)返回的才是正確的json,到了這里我們發(fā)現(xiàn)Json.NET序列化時(shí)也是有問(wèn)題的,于是乎在進(jìn)行反序列化時(shí)將返回的字符串需要進(jìn)行一下處理轉(zhuǎn)換成正確的json字符串來(lái)再來(lái)進(jìn)行反序列化,修改如下:     

?
1
2
3
4
5
var m = result.Content.ReadAsStringAsync().Result;
    m = m.TrimStart('\"');
    m = m.TrimEnd('\"');
    m = m.Replace("\\", "");
    var list = JsonConvert.DeserializeObject<List<string>>(m);

ASP.NET WebAPi(selfhost)實(shí)現(xiàn)文件同步或異步上傳

最終在頁(yè)面顯示如下:

ASP.NET WebAPi(selfhost)實(shí)現(xiàn)文件同步或異步上傳

到這里我們的同步上傳告一段落了,這里面利用Json.NET進(jìn)行反序列化時(shí)居然出錯(cuò)問(wèn)題,第一次遇到Json.NET反序列化時(shí)的問(wèn)題,比較奇葩,費(fèi)解。

異步上傳

所謂的異步上傳不過(guò)是利用Ajax進(jìn)行上傳,這里也就是為了復(fù)習(xí)下腳本或者Razor視圖,下面的內(nèi)容只是將視圖進(jìn)行了修改而已,對(duì)于異步上傳我利用了jquery.form.js中的異步api,請(qǐng)看如下代碼:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script src="~/Scripts/jquery.form.js"></script>
<script src="~/Scripts/bootstrap.min.js"></script>
<link href="~/Content/bootstrap.min.css" rel="stylesheet" />
 
<div class="container" style="margin-top:30px">
 <div id="success" style="display:none;">
  <div class="alert alert-danger" role="alert">
   <strong>上傳成功</strong><span style="margin-right:50px;"></span><a href="" target="_blank" id="linkAddr">文件訪問(wèn)地址</a>
  </div>
 </div>
 
 <div id="fail" style="display:none;">
  <div class="alert alert-danger" role="alert">
   <strong>上傳失敗</strong>
  </div>
 </div>
 
</div>
@using (Ajax.BeginForm("AsyncUpload", "Home", new AjaxOptions() { HttpMethod = "POST" }, new { enctype = "multipart/form-data",@style="margin-top:10px;" }))
{
 <div class="form-group">
  <input type="file" name="file" id="fu1" />
 </div>
 <div class="form-group">
  <input type="submit" class="btn btn-primary" value="上傳" />
 </div>
 
}
 
 
<div class="form-group">
 <div class="progress" id="progress" style="display:none;">
  <div class="progress-bar">0%</div>
 </div>
 <div id="status"></div>
</div>
 
 
<style>
 .progress {
  position: relative;
  width: 400px;
  border: 1px solid #ddd;
  padding: 1px;
 }
 
 .progress-bar {
  width: 0px;
  height: 40px;
  background-color: #57be65;
 }
</style>
 
<script>
 (function () {
  var bar = $('.progress-bar');
  var percent = $('.progress-bar');
  $('form').ajaxForm({
   beforeSend: function () {
    $("#progress").show();
    var percentValue = '0%';
    bar.width(percentValue);
    percent.html(percentValue);
   },
   uploadProgress: function (event, position, total, percentComplete) {
    var percentValue = percentComplete + '%';
    bar.width(percentValue);
    percent.html(percentValue);
   },
   success: function (d) {
    var percentValue = '100%';
    bar.width(percentValue);
    percent.html(percentValue);
    $('#fu1').val('');
   },
   complete: function (xhr) {
    if (xhr.responseText != null) {
     $("#linkAddr").prop("href", xhr.responseText);
     $("#success").show();
    }
    else {
     $("#fail").show();
    }
   }
  });
 })();
</script>

我們截圖看下其中上傳過(guò)程

上傳中:

ASP.NET WebAPi(selfhost)實(shí)現(xiàn)文件同步或異步上傳

上傳完成:

ASP.NET WebAPi(selfhost)實(shí)現(xiàn)文件同步或異步上傳

當(dāng)然這里的100%不過(guò)是針對(duì)小文件的實(shí)時(shí)上傳,如果是大文件肯定不是實(shí)時(shí)的,利用其它組件來(lái)實(shí)現(xiàn)更加合適,這里我只是學(xué)習(xí)學(xué)習(xí)僅此而已。

注意:這里還需重申一遍,之前在MVC上傳已經(jīng)敘述過(guò),MVC默認(rèn)的上傳文件是有限制的,所以超過(guò)其限制,則無(wú)法上傳,需要進(jìn)行如下設(shè)置

(1)在IIS 5和IIS 6中,默認(rèn)文件上傳的最大為4兆,當(dāng)上傳的文件大小超過(guò)4兆時(shí),則會(huì)得到錯(cuò)誤信息,但是我們通過(guò)如下來(lái)設(shè)置文件大小。

?
1
2
3
<system.web>
 <httpRuntime maxRequestLength="2147483647" executionTimeout="100000" />
</system.web>

(2)在IIS 7+,默認(rèn)文件上傳的最大為28.6兆,當(dāng)超過(guò)其默認(rèn)設(shè)置大小,同樣會(huì)得到錯(cuò)誤信息,但是我們卻可以通過(guò)如下來(lái)設(shè)置文件上傳大?。ㄍ瑫r(shí)也要進(jìn)行如上設(shè)置)。

?
1
2
3
4
5
6
7
<system.webServer>
 <security>
  <requestFiltering>
   <requestLimits maxAllowedContentLength="2147483647" />
  </requestFiltering>
 </security>
</system.webServer>

總結(jié)

本節(jié)我們學(xué)習(xí)了如何將MVC和WebAPi隔離開來(lái)來(lái)進(jìn)行上傳,同時(shí)我們也發(fā)現(xiàn)在反序列化時(shí)Json.NET有一定問(wèn)題,特此記錄下,當(dāng)發(fā)現(xiàn)一一對(duì)應(yīng)時(shí)反序列化返回的Json字符串不是標(biāo)準(zhǔn)的Json字符串,我們對(duì)返回的Json字符串需要作出如下處理才行(也許還有其他方案)。               

?
1
2
3
4
var jsonString = "返回的json字符串";
jsonString = jsonString.TrimStart('\"');
jsonString = jsonString.TrimEnd('\"');
jsonString = jsonString.Replace("\\", "");

接下來(lái)會(huì)準(zhǔn)備系統(tǒng)學(xué)習(xí)下SQL Server和Oracle,循序漸進(jìn),你說(shuō)呢!休息,休息!

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持服務(wù)器之家。

原文鏈接:http://www.cnblogs.com/CreateMyself/p/6035339.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 久久精品热在线观看85 | 被教官揉了一晚上的奶小说 | 成人久久网站 | 性一交一乱一伧老太 | 国产精品嫩草影院在线看 | 成人涩涩屋福利视频 | 激情综合 | 国产午夜精品久久久久 | 2019理论韩国理论中文 | 国产拍拍视频一二三四区 | 日韩毛片大全免费高清 | 亚洲欧美国产在线 | 大伊人青草狠狠久久 | 亚洲男人天堂影院 | 久久电影精品久久99久久 | 欧美洲大黑香蕉在线视频 | 欧美白虎逼| 思思99热久久精品在2019线 | 国产午夜免费 | 亚洲福利电影一区二区? | 女医学护士一级毛片 | 亚偷熟乱区视频在线观看 | 亚洲国产韩国欧美在线不卡 | 亚洲精品乱码蜜桃久久久 | 色婷婷网| 久久热这里只有 精品 | 国产精品视频视频久久 | 日出水了特别黄的视频 | 狠狠色狠狠色综合系列 | 婷婷麻豆 | 欧美专区综合 | 性福演算法| 成人国产网站v片免费观看 成人国产精品视频 | 国产精品久久久久久吹潮 | 五月天导航 | 青春草在线观看精品免费视频 | 护士让我吃奶我扒她奶 | 人与动人物人a级特片 | 日本一区二区三区视频在线观看 | 三叶草私人研究所 | 黑人巨大精品战中国美女 |