如何使用 .Net 4.0 中包含的 HttpClient 类将文件上传到在 IIS Express 中运行的 Asp.Net MVC 4.0 操作
Posted
技术标签:
【中文标题】如何使用 .Net 4.0 中包含的 HttpClient 类将文件上传到在 IIS Express 中运行的 Asp.Net MVC 4.0 操作【英文标题】:How to upload files to Asp.Net MVC 4.0 action running in IIS Express with HttpClient class included in .Net 4.0 【发布时间】:2013-03-26 13:44:58 【问题描述】:我有一个 C/S 应用程序。我用 Asp.Net MVC 4.0 实现了服务器,客户端在 .Net 4.5 上运行。
我在服务器端有一个控制器动作如下所示:
public JsonResult Upload(string arg1, int arg2)
//do something about arg1 and arg2 here
...
var files = Request.Files;
if (files.Count > 0)
foreach(var file in files)
var ms = new MemoryStream();
file.InputStream.CopyTo(ms);
//save it to somewhere
...
...
我创建了一个测试 html 页面来在浏览器中对其进行测试。它按预期工作。
在客户端,我使用HttpClient 类,它在不涉及文件上传的情况下完美运行。然而,经过几天的研究,我仍然没有运气在运行 IIS Express 的调试机器中解决这个问题。我发现所有的线索都指向MultipartFormDataContent
,但是仍然无法正常工作,即使我复制了那些示例代码,服务器端仍然无法获取任何东西,所有args都是空的,并且没有文件在里面Request.Files
。我曾经有自己的基于HttpWebRequest 的http helper 类,它适用于文件上传,但我更喜欢在这个新项目中使用HttpClient。
那么,如何使用 HttpClient 将文件上传到服务器?
【问题讨论】:
请注意,我没有在 IIS 中对此进行测试,也没有使用 Asp.net MVC 3.0 对其进行测试。 【参考方案1】:用 Fiddler 调试后,将原始 http 消息与 WinMerge 进行比较,我发现 Firefox 和我的程序之间的差异:
Firefox(删除了一些标题以使事情变得简单):
POST http://localhost:53400/Input/Upload HTTP/1.1
Host: localhost:53400
Content-Type: multipart/form-data; boundary=---------------------------1590871622043
Content-Length: ****
-----------------------------1590871622043
Content-Disposition: form-data; name="arg1"
abc
-----------------------------1590871622043
Content-Disposition: form-data; name="arg2"
3
-----------------------------1590871622043
Content-Disposition: form-data; name="uploadfile"; filename="wave.wav"
Content-Type: audio/wav
//file data here
-----------------------------1590871622043--
我的程序 MultipartFormDataContent
:
POST http://localhost:53400/Input/Save HTTP/1.1
Content-Type: multipart/form-data; boundary="caac5ea7-8ab4-4682-be40-ecb3ddf3e70a"
Host: localhost:53400
Content-Length: ****
--caac5ea7-8ab4-4682-be40-ecb3ddf3e70a
Content-Disposition: form-data; name=arg1
abc
--caac5ea7-8ab4-4682-be40-ecb3ddf3e70a
Content-Disposition: form-data; name=arg2
3
--caac5ea7-8ab4-4682-be40-ecb3ddf3e70a
Content-Disposition: form-data; name=uploadfile; filename=wave.wav; filename*=utf-8''wave.wav
//file data here
--caac5ea7-8ab4-4682-be40-ecb3ddf3e70a--
我注意到的最后一件事是,在这些 Content-Disposition
行中,Firefox 引用了所有值,但我的程序没有。人们可以很容易地认为这无关紧要,但最后我发现这就是确切的原因。
现在我知道了原因,下面是有效的代码,就像引用名称一样简单:
var multipart = new MultipartFormDataContent();
multipart.Add(new StringContent("abc"), '"' + "arg1" + '"');
multipart.Add(new StringContent("3"), '"' + "arg2" + '"');
// byte[] fileData;
multipart.Add(new ByteArrayContent(fileData), '"' + "uploadfile"+ '"', '"' + "wave.wav" + '"');
//HttpClient http; string url;
var response = await http.PostAsync(url, multipart);
response.EnsureSuccessStatusCode();
//...
【讨论】:
以上是关于如何使用 .Net 4.0 中包含的 HttpClient 类将文件上传到在 IIS Express 中运行的 Asp.Net MVC 4.0 操作的主要内容,如果未能解决你的问题,请参考以下文章
我如何在 ASP.Net Core 2.1 mvc 应用程序中包含 System.Identitymodel 4.0
ASP.NET MVC jQuery 自动完成与页面中包含的脚本中的 url.action 助手