(转)WebApi发送HTML表单数据:文件上传与多部分MIME

   2023-02-08 学习力0
核心提示:本文引自:http://www.cnblogs.com/r01cn/archive/2012/12/20/2826230.htmlBy Mike Wasson|June 21, 2012作者:Mike Wasson | 日期:2012-6-21Part 2: File Upload and Multipart MIME第2部分:文件上传与多部分MIMEThis tutorial shows how to upload files

本文引自:http://www.cnblogs.com/r01cn/archive/2012/12/20/2826230.html

By Mike Wasson|June 21, 2012
作者:Mike Wasson | 日期:2012-6-21

Part 2: File Upload and Multipart MIME
第2部分:文件上传与多部分MIME

This tutorial shows how to upload files to a web API. It also describes how to process multipart MIME data.
本教程演示如何对Web API上传文件。也描述如何处理多部分MIME数据。

Here is an example of an HTML form for uploading a file:
以下是一个上传文件的HTML表单(如图5-8):

<form name="form1" method="post" enctype="multipart/form-data" action="api/upload">
    <div>
        <label for="caption">Image Caption</label>
        <input name="caption" type="text" />
    </div>
    <div>
        <label for="image1">Image File</label>
        <input name="image1" type="file" />
    </div>
    <div>
        <input type="submit" value="Submit" />
    </div>
</form>
(转)WebApi发送HTML表单数据:文件上传与多部分MIME

图5-8. 文件上传表单

This form contains a text input control and a file input control. When a form contains a file input control, the enctype attribute should always be "multipart/form-data", which specifies that the form will be sent as a multipart MIME message.
该表单有一个文本输入控件和一个文件输入控件。当表单含有文件输入控件时,其enctype标签属性应当总是“multipart/form-data”,它指示此表单将作为多部分MIME消息进行发送。

The format of a multipart MIME message is easiest to understand by looking at an example request:
通过考察一个示例请求,很容易理解multipart(多部分)MIME消息的格式:

POST http://localhost:50460/api/values/1 HTTP/1.1
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:12.0) Gecko/20100101 Firefox/12.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: multipart/form-data; boundary=---------------------------41184676334
Content-Length: 29278
-----------------------------41184676334 Content-Disposition: form-data; name="caption"
Summer vacation -----------------------------41184676334 Content-Disposition: form-data; name="image1"; filename="GrandCanyon.jpg" Content-Type: image/jpeg
(Binary data not shown)(二进制数据,未列出) -----------------------------41184676334--

This message is divided into two parts, one for each form control. Part boundaries are indicated by the lines that start with dashes.
这条消息分成两个部件parts),分别用于每个表单控件。部件边界由以一些破折号开始的行指示。

The part boundary includes a random component ("41184676334") to ensure that the boundary string does not accidentally appear inside a message part.
部件边界包含了一个随机组件(“41184676334”),以确保边界字符串不会偶然出现在消息部件之中。

Each message part contains one or more headers, followed by the part contents.
每一个消息部件含有一个或多个报头,后跟部件内容。

  • The Content-Disposition header includes the name of the control. For files, it also contains the file name.
    Content-Disposition(内容布置)报头包括控件名称。对于文件,它也包括文件名。
  • The Content-Type header describes the data in the part. If this header is omitted, the default is text/plain.
    Content-Type(内容类型)报头描述部件中的数据。如果该报头被忽略,默认为text/plain(文本格式)。

In the previous example, the user uploaded a file named GrandCanyon.jpg, with content type image/jpeg; and the value of the text input was "Summer Vacation".
在上一示例中,用户上传名为GrandCanyon.jpg的文件,其内容类型为image/jpeg,而文本输入框的值为“Summer Vacation”。

File Upload
文件上传

Now let's look at a Web API controller that reads files from a multipart MIME message. The controller will read the files asynchronously. Web API supports asynchronous actions using the task-based programming model. First, here is the code if you are targeting .NET Framework 4.5, which supports the async and await keywords.
现在,让我们考查从一个多部分MIME消息读取文件的控制器。该控制器将异步读取文件。Web API支持使用“基于任务的编程模型(这是关于.NET并行编程的MSDN文档 — 译者注)”的异步动作。首先,以下是针对.NET Framework 4.5的代码,它支持asyncawait关键字。

using System.Diagnostics;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web;
using System.Web.Http; 
public class UploadController : ApiController { public async Task<HttpResponseMessage> PostFormData() { // Check if the request contains multipart/form-data. // 检查该请求是否含有multipart/form-data if (!Request.Content.IsMimeMultipartContent()) { throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType); }
string root = HttpContext.Current.Server.MapPath("~/App_Data"); var provider = new MultipartFormDataStreamProvider(root);
try { // Read the form data. // 读取表单数据 await Request.Content.ReadAsMultipartAsync(provider);
// This illustrates how to get the file names. // 以下描述如何获取文件名 foreach (MultipartFileData file in provider.FileData) { Trace.WriteLine(file.Headers.ContentDisposition.FileName); Trace.WriteLine("Server file path: " + file.LocalFileName); } return Request.CreateResponse(HttpStatusCode.OK); } catch (System.Exception e) { return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, e); } } }

Notice that the controller action does not take any parameters. That's because we process the request body inside the action, without invoking a media-type formatter.
注意,控制器动作不取任何参数。这是因为我们是在动作中处理请求体的,不必调用media-type格式化器。

The IsMultipartContent method checks whether the request contains a multipart MIME message. If not, the controller returns HTTP status code 415 (Unsupported Media Type).
IsMultipartContent方法检查该请求是否含有多部分MIME消息。如果不是,控制器返回HTTP状态码415(不支持的媒体类型)。

The MultipartFormDataStreamProvider class is a helper object that allocates file streams for uploaded files. To read the multipart MIME message, call the ReadAsMultipartAsync method. This method extracts all of the message parts and writes them into the streams provided by the MultipartFormDataStreamProvider.
MultipartFormDataStreamProvider类是一个辅助器对象,它为上传文件分配文件流。为了读取多部分MIME消息,需调用ReadAsMultipartAsync方法。该方法提取所有消息部件,并把它们写入由MultipartFormDataStreamProvider提供的流中。

When the method completes, you can get information about the files from the FileData property, which is a collection of MultipartFileDataobjects.
当该方法完成时,你可以通过FileData属性获得文件的信息,该属性是一个MultipartFileData对象的集合。

  • MultipartFileData.FileName is the local file name on the server, where the file was saved.
    MultipartFileData.FileName是保存此文件的服务器上的一个本地文件名。
  • MultipartFileData.Headers contains the part header (not the request header). You can use this to access the Content_Disposition and Content-Type headers.
    MultipartFileData.Headers含有部件报头(不是请求报头)。你可以用它来访问Content_Disposition和Content-Type报头。

As the name suggests, ReadAsMultipartAsync is an asynchronous method. To perform work after the method completes, use a continuation task (.NET 4.0) or the await keyword (.NET 4.5).
正如名称所暗示的那样,ReadAsMultipartAsync是一个异步方法。为了在该方法完成之后执行一些工作,需要使用“continuation(继续)任务”(.NET 4.0)或await关键字(.NET 4.5)。

Here is the .NET Framework 4.0 version of the previous code:
以下是前述代码的.NET Framework 4.0版本:

public Task<HttpResponseMessage> PostFormData()
{
    // Check if the request contains multipart/form-data.
    // 检查该请求是否含有multipart/form-data
    if (!Request.Content.IsMimeMultipartContent())
    {
        throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
    }
string root = HttpContext.Current.Server.MapPath("~/App_Data"); var provider = new MultipartFormDataStreamProvider(root);
// Read the form data and return an async task. // 读取表单数据,并返回一个async任务 var task = Request.Content.ReadAsMultipartAsync(provider). ContinueWith<HttpResponseMessage>(t => { if (t.IsFaulted || t.IsCanceled) { Request.CreateErrorResponse(HttpStatusCode.InternalServerError, t.Exception); }
// This illustrates how to get the file names. // 以下描述了如何获取文件名 foreach (MultipartFileData file in provider.FileData) { Trace.WriteLine(file.Headers.ContentDisposition.FileName); Trace.WriteLine("Server file path: " + file.LocalFileName); } return Request.CreateResponse(HttpStatusCode.OK); });
return task; }

Reading Form Control Data
读取表单控件数据

The HTML form that I showed earlier had a text input control.
前面显示的HTML表单有一个文本输入控件。

    <div>
        <label for="caption">Image Caption</label>
        <input name="caption" type="text" />
    </div>

You can get the value of the control from the FormData property of the MultipartFormDataStreamProvider
可以通过MultipartFormDataStreamProviderFormData属性获取控件的值。

public async Task<HttpResponseMessage> PostFormData()
{
    if (!Request.Content.IsMimeMultipartContent())
    {
        throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
    }
string root = HttpContext.Current.Server.MapPath("~/App_Data"); var provider = new MultipartFormDataStreamProvider(root);
try { await Request.Content.ReadAsMultipartAsync(provider);
// Show all the key-value pairs. // 显示所有“键-值”对 foreach (var key in provider.FormData.AllKeys) { foreach (var val in provider.FormData.GetValues(key)) { Trace.WriteLine(string.Format("{0}: {1}", key, val)); } }
return Request.CreateResponse(HttpStatusCode.OK); } catch (System.Exception e) { return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, e); } }

FormData is a NameValueCollection that contains name/value pairs for the form controls. The collection can contain duplicate keys. Consider this form:
FormData是一个NameValueCollection(名字/值集合),它含有表单控件的“名字/值”对。该集合可能含有重复键。考虑以下表单(如图5-9):

<form name="trip_search" method="post" enctype="multipart/form-data" action="api/upload">
    <div>
        <input type="radio" name="trip" value="round-trip"/>
        Round-Trip
    </div>
    <div>
        <input type="radio" name="trip" value="one-way"/>
        One-Way
    </div> 
<div> <input type="checkbox" name="options" value="nonstop" /> Only show non-stop flights </div> <div> <input type="checkbox" name="options" value="airports" /> Compare nearby airports </div> <div> <input type="checkbox" name="options" value="dates" /> My travel dates are flexible </div>
<div> <label for="seat">Seating Preference</label> <select name="seat"> <option value="aisle">Aisle</option> <option value="window">Window</option> <option value="center">Center</option> <option value="none">No Preference</option> </select> </div> </form>
(转)WebApi发送HTML表单数据:文件上传与多部分MIME

图5-9. 有重复键的表单

The request body might look like this:
该请求体看上去可能像这样:

-----------------------------7dc1d13623304d6
Content-Disposition: form-data; name="trip"
round-trip -----------------------------7dc1d13623304d6 Content-Disposition: form-data; name="options"
nonstop -----------------------------7dc1d13623304d6 Content-Disposition: form-data; name="options"
dates -----------------------------7dc1d13623304d6 Content-Disposition: form-data; name="seat"
window -----------------------------7dc1d13623304d6--

In that case, the FormData collection would contain the following key/value pairs:
在这种情况下,FormData集合会含有以下“键/值”对:

    • trip: round-trip
    • options: nonstop
    • options: dates
    • seat: window
 
反对 0举报 0 评论 0
 

免责声明:本文仅代表作者个人观点,与乐学笔记(本网)无关。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
    本网站有部分内容均转载自其它媒体,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责,若因作品内容、知识产权、版权和其他问题,请及时提供相关证明等材料并与我们留言联系,本网站将在规定时间内给予删除等相关处理.

  • HTML中将背景颜色渐变 html设置背景颜色渐变
    通过使用 css3 渐变可以让背景两个或多个指定的颜色之间显示平稳的过渡,由于用到css3所以需要考虑下浏览器兼容问题,例如:从左到右的线性渐变,且带有透明度的样式:#grad {background: -webkit-linear-gradient(left,rgba(255,0,0,0),rgba(255,0,0,1)); /*
    03-08
  • html5 Canvas 如何自适应屏幕大小
    但是这样创建出的画布不能随着浏览器窗口大小的改变而动态的改变画布的大小。而这一点往往又非常重要, 因为我们会经常改变浏览器窗口大小,不会一直保持某个固定的大小。 html代码 canvas width="300" height="300" id="myCanvas"/canvas设置样式 * {
    03-08
  • Vue中出现Do not use built-in or reserved HTML elements as component id:footer等等vue warn问题
    Vue中出现Do not use built-in or reserved HTM
    错误示图:原因:是因为在本地项目对应文件的script中,属性name出现了错误的命名方式,导致浏览器控制台报错!  诸如: name: header 、  、 name: menu , 等等都属于错误的命名方式等 错误代码命名如下:解决办法:办法1: 如果我们采用正确命名
    03-08
  • HTML在网页中插入音频视频简单的滚动效果
    HTML在网页中插入音频视频简单的滚动效果
    每次上网,打开网页后大家都会看到在网页的标签栏会有个属于他们官网的logo,现在学了HTML了,怎么不会制作这个小logo呢,其实很简单,也不需要死记硬背,每当这行代码出现的时候能知道这是什么意思就ok1 link rel="shortcuticon" type="image/x-icon" href="
    03-08
  • HTML的video标签,不能下载视频代码
    !-- 在线视频不能下载代码 --!DOCTYPE html html headscript src="../Demo/demo/book/JQuery/jQuery v2.2.0.js"/script/headbody div style="text-align:center;"video src="../images/PreviewVideo.mp4" width="820"controls="controls&
    03-08
  • ThinkPHP报错 The requested URL /admin/index/login.html was not found on this server.
    ThinkPHP报错 The requested URL /admin/index/
           解决方案在入口文件夹public下查看.htaccess是否存在。不存在则新建,存在的话,那内容替换为下面这串代码 就可以解决Not Fund#IfModule mod_rewrite.c#Options +FollowSymlinks -Multiviews#RewriteEngine On##RewriteCond %{REQUEST_FILENAME
    03-08
  • HTML特殊字符、列表、表格总结 html特殊符号对
            HTML实体字符  在HTML中一些特殊的字符需要用特殊的方式才能显示出来,比如小于号、版权等,  在课堂上老师教了我们一个有点意思的:空格,在教材上字符实体是“nbsp”通过老师  的演示我们发现不同的浏览器他所显示的效果不同,有的比
    03-08
  • 【JavaScript】使用document.write输出覆盖HTML
    您只能在 HTML 输出中使用 document.write。如果您在文档加载后使用该方法,会覆盖整个文档。分析HTML输出流是指当前数据形式是HTML格式的数据,这部分数据正在被导出、传输或显示,所以称为“流”。通俗的来说就是HTML文档的加载过程,如果遇到document.writ
    03-08
  • ASP.Net MVC 控制@Html.DisplayFor日期显示格式
    在做一個舊表的查詢頁時,遇到一個問題:字段在db里存儲的是DATETIME,但保存的值只有日期,沒有時間數據,比如2018/2/26 0:00:00,顯示出來比較難看,當然也可以做一個ViewModel,在字段上添加Attribute定義來更改名稱和顯示名稱,如下:[Display(Name = "建
    03-08
  • html 基础代码
    title淄博汉企/title/headbody bgcolor="#00CC66" topmargin="200" leftmargin="200" bottommargin="200"a name="top"/a今天br /天气nbsp;nbsp;nbsp;nbsp;nbsp;不错br /font color="#CC0000"格式控制标签br /b 文字加粗方式1\bbr /str
    03-08
点击排行