如何上传文件到Asp.使用.Net 4.0中包含的HttpClient类在IIS Express中运行.Net MVC

本文关键字:Net 包含 HttpClient IIS MVC 运行 Express 类在 文件 使用 Asp | 更新日期: 2023-09-27 18:05:51

我有一个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,但仍然不能得到它的工作,即使我复制那些样本代码,服务器端仍然不能得到一个东西,所有的参数都是空的,没有文件是在Request.Files。我曾经有我自己的基于HttpWebRequest的http helper类,它适用于文件上传,但我更喜欢在这个新项目中使用HttpClient。

那么,我如何上传文件到服务器与HttpClient?

如何上传文件到Asp.使用.Net 4.0中包含的HttpClient类在IIS Express中运行.Net MVC

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

My Program with 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();
//...