asp.net html写入流,在 ASP.NET Web API 中发送 HTML 窗体数据:文件上传和多部分 ASP.NET 4。x | Microsoft Docs...

本文详细介绍了如何在ASP.NET WebAPI中处理文件上传和多部分MIME数据。通过示例展示了如何创建上传文件的HTML表单,以及WebAPI控制器如何异步读取并处理这些数据。重点讲解了`MultipartFormDataStreamProvider`类的使用,以及如何从多部分MIME消息中获取表单控件的数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在 ASP.NET Web API 中发送 HTML 窗体数据:文件上传和多部分 MIME

06/21/2012

本文内容

第2部分:文件上传和多部分 MIME

本教程演示如何将文件上传到 web API。 还介绍了如何处理多部分 MIME 数据。

下面是用于上载文件的 HTML 窗体的示例:

Image Caption

Image File

9a338eb214e19762d88aa8333b9408a0.png

此窗体包含文本输入控件和文件输入控件。 当窗体包含文件输入控件时, enctype特性应始终 "多部分/窗体数据",这将指定窗体将作为多部分 MIME 消息发送。

通过查看示例请求,可以最轻松地了解多部分 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--

此消息分为两部分,分别用于每个窗体控件。 部分边界由以破折号开头的行指示。

Note

部分边界包含随机组件("41184676334"),以确保边界字符串不会意外出现在消息部分中。

每个消息部分都包含一个或多个标头,后面是部分内容。

内容处置标头包含控件的名称。 对于文件,它还包含文件名。

Content-type 标头介绍了该部分中的数据。 如果省略此标头,则默认值为 text/简洁。

在上面的示例中,用户使用内容类型 image/jpeg 上传了一个名为 GrandCanyon 的文件;并且文本输入的值为 "夏天假期"。

文件上传

现在,让我们看看从多部分 MIME 消息读取文件的 Web API 控制器。 控制器将异步读取文件。 Web API 使用基于任务的编程模型支持异步操作。 首先,如果你针对的是支持async和await关键字的 .NET Framework 4.5,则代码为。

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 PostFormData()

{

// Check if the request contains 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);

}

}

}

请注意,控制器操作不采用任何参数。 这是因为,我们处理操作中的请求正文,而不调用媒体类型格式化程序。

IsMultipartContent方法检查请求是否包含多部分 MIME 消息。 否则,控制器将返回 HTTP 状态代码415(不支持的媒体类型)。

MultipartFormDataStreamProvider类是一个帮助器对象,它为上传的文件分配文件流。 若要读取多部分 MIME 消息,请调用ReadAsMultipartAsync方法。 此方法提取所有消息部分,并将其写入MultipartFormDataStreamProvider提供的流中。

当方法完成时,可以从FileData属性获取有关文件的信息,该属性是MultipartFileData对象的集合。

MultipartFileData是服务器上保存文件的本地文件名。

MultipartFileData包含部件标题(而不是请求标头)。 你可以使用它来访问_处置和 Content-type 标头的内容。

顾名思义, ReadAsMultipartAsync是一种异步方法。 若要在方法完成后执行工作,请使用延续任务(.net 4.0)或await关键字(.net 4.5)。

下面是前面代码的 .NET Framework 4.0 版本:

public Task PostFormData()

{

// Check if the request contains 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.

var task = Request.Content.ReadAsMultipartAsync(provider).

ContinueWith(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;

}

读取窗体控件数据

我前面介绍的 HTML 窗体具有文本输入控件。

Image Caption

可以从MultipartFormDataStreamProvider的FormData属性中获取该控件的值。

public async Task 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是包含窗体控件的名称/值对的NameValueCollection 。 集合可以包含重复键。 请考虑以下形式:

Round-Trip

One-Way

Only show non-stop flights

Compare nearby airports

My travel dates are flexible

Seating Preference

Aisle

Window

Center

No Preference

29f6000058f45e84f9d1ce21c01dfe32.png

请求正文可能如下所示:

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

在这种情况下, FormData集合将包含以下键/值对:

行程:往返行程

选项:不间断

选项:日期

座位:窗口

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值