検索
ホームページバックエンド開発C#.Net チュートリアルASP.NET WebAPI (selfhost) はファイル同期または非同期アップロードを実装します

前言
前面我们讲过利用AngularJs上传到WebAPi中进行处理,同时我们在MVC系列中讲过文件上传,本文结合MVC+WebAPi来进行文件的同步或者异步上传,顺便回顾下css和js,MVC作为客户端,而WebAPi利用不依赖于IIS的selfhost模式作为服务端来接收客户端的文件且其过程用Ajax来实现,下面我们一起来看看。

同步上传

多余的话不用讲,我们直接看页面。

<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>

上述我们直接上传后通过上传的状态来显示查看上传文件路径并访问,就是这么简单。下面我们来MVC后台逻辑

[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);
          //设置请求头中的附件为文件名称,以便在WebAPi中进行获取
   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)
   {
            //获取到上传文件地址,并渲染到视图中进行访问
    var m = result.Content.ReadAsStringAsync().Result;
    var list = JsonConvert.DeserializeObject<List<string>>(m);
    ViewBag.Success = list.FirstOrDefault();
 
   }
   else
   {
    ViewBag.Failed = "上传失败啦,状态码:" + result.StatusCode + ",原因:" + result.ReasonPhrase + ",错误信息:" + result.Content.ToString();
   }
  }
 }
 return View();
}

注意:上述将获取到文件字节流数组需要传递给 MultipartFormDataContent ,要不然传递到WebAPi时会获取不到文件数据。

到这里为止在MVC中操作就已经完毕,此时我们来看看在WebAPi中需要完成哪些操作。

(1)首先肯定需要判断上传的数据是否是MimeType类型。

if (!Request.Content.IsMimeMultipartContent())
{
 throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}

(2)我们肯定是需要重新生成一个文件名称以免重复,利用Guid或者Date或者其他。

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

(3)我们需要利用此类 MultipartFileStreamProvider 设置上传路径并将文件写入到这个里面。

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

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

  return Request.CreateResponse(HttpStatusCode.Created, JsonConvert.SerializeObject(savedFilePath));
分步骤解析了这么多,组装代码如下:

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为需要去掉域名的后面地址
               //如上述请求为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 ,因为此时我们重新命名了文件名称,所以需要将该文件移动到我们重新命名的文件地址。

整个过程就是这么简单,下面我们来看看演示结果。

ASP.NET WebAPi(selfhost)实现文件同步或异步上传

此时居然出错了,有点耐人寻味,在服务端是返回如下的Json字符串

List<string> savedFilePath = new List<string>();

此时进行反序列化时居然出错,再来看看页面上的错误信息:

ASP.NET WebAPi(selfhost)实现文件同步或异步上传

无法将字符串转换为List,这不是一一对应的么,好吧,我来看看返回的字符串到底是怎样的,【当将鼠标放上去】时查看的如下:

ASP.NET WebAPi(selfhost)实现文件同步或异步上传

【当将点击查看】时结果如下:

ASP.NET WebAPi(selfhost)实现文件同步或异步上传

由上知点击查看按钮时返回的才是正确的json,到了这里我们发现Json.NET序列化时也是有问题的,于是乎在进行反序列化时将返回的字符串需要进行一下处理转换成正确的json字符串来再来进行反序列化,修改如下:     

var m = result.Content.ReadAsStringAsync().Result;
    m = m.TrimStart(&#39;\"&#39;);
    m = m.TrimEnd(&#39;\"&#39;);
    m = m.Replace("\\", "");
    var list = JsonConvert.DeserializeObject<List<string>>(m);

到这里我们的同步上传告一段落了,这里面利用Json.NET进行反序列化时居然出错问题,第一次遇到Json.NET反序列化时的问题,比较奇葩,费解。

异步上传

所谓的异步上传不过是利用Ajax进行上传,这里也就是为了复习下脚本或者Razor视图,下面的内容只是将视图进行了修改而已,对于异步上传我利用了jquery.form.js中的异步api,请看如下代码:

<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">文件访问地址</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 = $(&#39;.progress-bar&#39;);
  var percent = $(&#39;.progress-bar&#39;);
  $(&#39;form&#39;).ajaxForm({
   beforeSend: function () {
    $("#progress").show();
    var percentValue = &#39;0%&#39;;
    bar.width(percentValue);
    percent.html(percentValue);
   },
   uploadProgress: function (event, position, total, percentComplete) {
    var percentValue = percentComplete + &#39;%&#39;;
    bar.width(percentValue);
    percent.html(percentValue);
   },
   success: function (d) {
    var percentValue = &#39;100%&#39;;
    bar.width(percentValue);
    percent.html(percentValue);
    $(&#39;#fu1&#39;).val(&#39;&#39;);
   },
   complete: function (xhr) {
    if (xhr.responseText != null) {
     $("#linkAddr").prop("href", xhr.responseText);
     $("#success").show();
    }
    else {
     $("#fail").show();
    }
   }
  });
 })();
</script>

我们截图看下其中上传过程

上传中:

ASP.NET WebAPi(selfhost)实现文件同步或异步上传

上传完成:

当然这里的100%不过是针对小文件的实时上传,如果是大文件肯定不是实时的,利用其它组件来实现更加合适,这里我只是学习学习仅此而已。

注意:这里还需重申一遍,之前在MVC上传已经叙述过,MVC默认的上传文件是有限制的,所以超过其限制,则无法上传,需要进行如下设置

(1)在IIS 5和IIS 6中,默认文件上传的最大为4兆,当上传的文件大小超过4兆时,则会得到错误信息,但是我们通过如下来设置文件大小。

<system.web>
 <httpRuntime maxRequestLength="2147483647" executionTimeout="100000" />
</system.web>

   

(2)在IIS 7+,默认文件上传的最大为28.6兆,当超过其默认设置大小,同样会得到错误信息,但是我们却可以通过如下来设置文件上传大小(同时也要进行如上设置)。

<system.webServer>
 <security>
  <requestFiltering>
   <requestLimits maxAllowedContentLength="2147483647" />
  </requestFiltering>
 </security>
</system.webServer>

   

总结 

本节我们学习了如何将MVC和WebAPi隔离开来来进行上传,同时我们也发现在反序列化时Json.NET有一定问题,特此记录下,当发现一一对应时反序列化返回的Json字符串不是标准的Json字符串,我们对返回的Json字符串需要作出如下处理才行(也许还有其他方案)。               

var jsonString = "返回的json字符串";
jsonString = jsonString.TrimStart(&#39;\"&#39;);
jsonString = jsonString.TrimEnd(&#39;\"&#39;);
jsonString = jsonString.Replace("\\", "");

   

接下来会准备系统学习下SQL Server和Oracle,循序渐进,你说呢!休息,休息!

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持PHP中文网。


声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
c#.netはあなたにぴったりですか?その適用性の評価c#.netはあなたにぴったりですか?その適用性の評価Apr 13, 2025 am 12:03 AM

c#.netissuitableforenterprise-levelApplicationsとsystemduetoitsSystemdutyping、richlibraries、androbustperformance.

.NET内のC#コード:プログラミングプロセスの調査.NET内のC#コード:プログラミングプロセスの調査Apr 12, 2025 am 12:02 AM

.NETでのC#のプログラミングプロセスには、次の手順が含まれます。1)C#コードの作成、2)中間言語(IL)にコンパイルし、3).NETランタイム(CLR)によって実行される。 .NETのC#の利点は、デスクトップアプリケーションからWebサービスまでのさまざまな開発シナリオに適した、最新の構文、強力なタイプシステム、および.NETフレームワークとの緊密な統合です。

C#.NET:コアの概念とプログラミングの基礎を探るC#.NET:コアの概念とプログラミングの基礎を探るApr 10, 2025 am 09:32 AM

C#は、Microsoftによって開発された最新のオブジェクト指向プログラミング言語であり、.NETフレームワークの一部として開発されています。 1.C#は、カプセル化、継承、多型を含むオブジェクト指向プログラミング(OOP)をサポートしています。 2。C#の非同期プログラミングは非同期を通じて実装され、適用応答性を向上させるためにキーワードを待ちます。 3. LINQを使用してデータ収集を簡潔に処理します。 4.一般的なエラーには、null参照の例外と、範囲外の例外インデックスが含まれます。デバッグスキルには、デバッガーと例外処理の使用が含まれます。 5.パフォーマンスの最適化には、StringBuilderの使用と、不必要な梱包とボクシングの回避が含まれます。

テストC#.NETアプリケーション:ユニット、統合、およびエンドツーエンドテストテストC#.NETアプリケーション:ユニット、統合、およびエンドツーエンドテストApr 09, 2025 am 12:04 AM

C#.NETアプリケーションのテスト戦略には、ユニットテスト、統合テスト、エンドツーエンドテストが含まれます。 1.単位テストにより、コードの最小ユニットがMSTEST、ヌニット、またはXUNITフレームワークを使用して独立して動作することを保証します。 2。統合テストでは、一般的に使用されるシミュレートされたデータと外部サービスを組み合わせた複数のユニットの機能を検証します。 3.エンドツーエンドのテストでは、ユーザーの完全な操作プロセスをシミュレートし、通常、セレンは自動テストに使用されます。

高度なC#.NETチュートリアル:次のシニア開発者インタビューをエース高度なC#.NETチュートリアル:次のシニア開発者インタビューをエースApr 08, 2025 am 12:06 AM

C#シニア開発者とのインタビューでは、非同期プログラミング、LINQ、.NETフレームワークの内部作業原則などのコア知識をマスターする必要があります。 1.非同期プログラミングは、非同期を通じて操作を簡素化し、アプリケーションの応答性を向上させるのを待ちます。 2.LinqはSQLスタイルでデータを操作し、パフォーマンスに注意を払います。 3.ネットフレームワークのCLRはメモリを管理し、ガベージコレクションに注意して使用する必要があります。

c#.netインタビューの質問と回答:専門知識を高めるc#.netインタビューの質問と回答:専門知識を高めるApr 07, 2025 am 12:01 AM

C#.NETインタビューの質問と回答には、基本的な知識、コアの概念、高度な使用が含まれます。 1)基本知識:C#は、Microsoftが開発したオブジェクト指向言語であり、主に.NETフレームワークで使用されています。 2)コアの概念:委任とイベントは動的な結合方法を可能にし、LINQは強力なクエリ関数を提供します。 3)高度な使用:非同期プログラミングは応答性を向上させ、式ツリーは動的コード構造に使用されます。

C#.NETを使用したマイクロサービスの構築:建築家向けの実用的なガイドC#.NETを使用したマイクロサービスの構築:建築家向けの実用的なガイドApr 06, 2025 am 12:08 AM

C#.NETは、その強力なエコシステムと豊富なサポートのため、マイクロサービスを構築するために人気のある選択肢です。 1)asp.netcoreを使用してRestfulapiを作成して、順序の作成とクエリを処理します。 2)GRPCを使用して、マイクロサービス間の効率的な通信を実現し、注文サービスを定義および実装します。 3)Dockerコンテナ化されたマイクロサービスを介して展開と管理を簡素化します。

C#.NETセキュリティベストプラクティス:一般的な脆弱性の防止C#.NETセキュリティベストプラクティス:一般的な脆弱性の防止Apr 05, 2025 am 12:01 AM

C#および.NETのセキュリティベストプラクティスには、入力検証、出力エンコード、例外処理、認証と承認が含まれます。 1)正規表現または組み込みのメソッドを使用して入力を検証して、悪意のあるデータがシステムに入るのを防ぎます。 2)XSS攻撃を防ぐための出力エンコード、httputility.htmlencodeメソッドを使用します。 3)例外処理により、情報の漏れが回避され、エラーが記録されますが、詳細情報はユーザーに返されません。 4)ASP.Netidentityおよび請求に基づく許可を使用して、不正アクセスから申請を保護します。

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

このプロジェクトは osdn.net/projects/mingw に移行中です。引き続きそこでフォローしていただけます。 MinGW: GNU Compiler Collection (GCC) のネイティブ Windows ポートであり、ネイティブ Windows アプリケーションを構築するための自由に配布可能なインポート ライブラリとヘッダー ファイルであり、C99 機能をサポートする MSVC ランタイムの拡張機能が含まれています。すべての MinGW ソフトウェアは 64 ビット Windows プラットフォームで実行できます。

WebStorm Mac版

WebStorm Mac版

便利なJavaScript開発ツール

SecLists

SecLists

SecLists は、セキュリティ テスターの究極の相棒です。これは、セキュリティ評価中に頻繁に使用されるさまざまな種類のリストを 1 か所にまとめたものです。 SecLists は、セキュリティ テスターが必要とする可能性のあるすべてのリストを便利に提供することで、セキュリティ テストをより効率的かつ生産的にするのに役立ちます。リストの種類には、ユーザー名、パスワード、URL、ファジング ペイロード、機密データ パターン、Web シェルなどが含まれます。テスターはこのリポジトリを新しいテスト マシンにプルするだけで、必要なあらゆる種類のリストにアクセスできるようになります。

Dreamweaver Mac版

Dreamweaver Mac版

ビジュアル Web 開発ツール

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser は、オンライン試験を安全に受験するための安全なブラウザ環境です。このソフトウェアは、あらゆるコンピュータを安全なワークステーションに変えます。あらゆるユーティリティへのアクセスを制御し、学生が無許可のリソースを使用するのを防ぎます。