HttpClient上传MultipartFormData来玩2框架 [英] HttpClient uploading MultipartFormData to play 2 framework
问题描述
我在使用RestSharp客户端的Windows Phone 8项目中有以下代码:
I have the following code in a Windows Phone 8 project that uses RestSharp client:
public async Task<string> DoMultiPartPostRequest(String ext, JSonWriter jsonObject, ObservableCollection<Attachment> attachments)
{
var client = new RestClient(DefaultUri);
// client.Authenticator = new HttpBasicAuthenticator(username, password);
var request = new RestRequest(ext, Method.POST);
request.RequestFormat = DataFormat.Json;
request.AddParameter("json", jsonObject.ToString(), ParameterType.GetOrPost);
// add files to upload
foreach (var a in attachments)
request.AddFile("attachment", a.FileBody, "attachment.file", a.ContType);
var content = await client.GetResponseAsync(request);
if (content.StatusCode != HttpStatusCode.OK)
return "error";
return content.Content;
}
Fiddler显示生成的标题:
Fiddler shows the generated header:
POST http://192.168.1.101:9000/rayz/create HTTP/1.1
Content-Type: multipart/form-data; boundary=-----------------------------28947758029299
Content-Length: 71643
Accept-Encoding: identity
Accept: application/json, application/xml, text/json, text/x-json, text/javascript, text/xml
User-Agent: RestSharp 104.1.0.0
Host: 192.168.1.101:9000
Connection: Keep-Alive
Pragma: no-cache
-------------------------------28947758029299
Content-Disposition: form-data; name="json"
{
"userId": "2D73B43390041E868694A85A65E47A09D50F019C180E93BAACC454488F67A411",
"latitude": "35.09",
"longitude": "33.30",
"accuracy": "99",
"maxDistance": "dist",
"Message": "mooohv"
}
-------------------------------28947758029299
Content-Disposition: form-data; name="attachment"; filename="attachment.file"
Content-Type: image/jpeg
?????JFIF??`?`?????C? $" &0P40,,0bFJ:Ptfzxrfpn????????np????????|????????????C"$$0*0^44^?p??????????????????????????????????????????????????????`?"??????????????
-------------------------------28947758029299
上面的代码在Play2 API上运行正常。但是RestSharp似乎不稳定我决定使用Microsoft提供的本机HttpClient。
The code above works fine on the Play2 API. However since the RestSharp does not seem to be stable I have decided to use the native HttpClient provided by Microsoft.
因此我编写了另一个使用HttpClient执行相同工作的函数:
Hence I wrote another function that uses HttpClient to do the same job:
public async Task<string> DoMultiPartPostRequest2(String ext, JSonWriter jsonObject,
ObservableCollection<Attachment> attachments)
{
var client = new HttpClient();
var content = new MultipartFormDataContent();
var json = new StringContent(jsonObject.ToString());
content.Add(json, "json");
foreach (var a in attachments)
{
var fileContent = new StreamContent(new MemoryStream(a.FileBody));
fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
Name = "attachment",
FileName = "attachment.file"
};
fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse(a.ContType);
content.Add(fileContent);
}
var resp = await client.PostAsync(DefaultUri + ext, content);
if (resp.StatusCode != HttpStatusCode.OK)
return "error";
var reponse = await resp.Content.ReadAsStringAsync();
return reponse;
}
从该代码生成的标题如下:
The header that is generated from that code is the following:
POST http://192.168.1.101:9000/rayz/create HTTP/1.1
Accept: */*
Content-Length: 6633
Accept-Encoding: identity
Content-Type: multipart/form-data; boundary="e01b2196-d24a-47a2-a99b-e82cc4a2f92e"
User-Agent: NativeHost
Host: 192.168.1.101:9000
Connection: Keep-Alive
Pragma: no-cache
--e01b2196-d24a-47a2-a99b-e82cc4a2f92e
Content-Type: text/plain; charset=utf-8
Content-Disposition: form-data; name=json
{
"userId": "2D73B43390041E868694A85A65E47A09D50F019C180E93BAACC454488F67A411",
"latitude": "35.09",
"longitude": "33.30",
"accuracy": "99",
"maxDistance": "dist",
"Message": "test"
}
--e01b2196-d24a-47a2-a99b-e82cc4a2f92e
Content-Disposition: form-data; name=attachment; filename=attachment.file
Content-Type: image/jpeg
?????JFIF??`?`?????C? $" &0P40,,0bFJ:Ptfzxrfpn????????np????????|????????????C"$$0*0^44^?p????????????????????????????????????????????????????????"??????????????
--e01b2196-d24a-47a2-a99b-e82cc4a2f92e--
到目前为止一直很好。从我的观点来看,这两个标题似乎完全相同。
So far so good. From my point of view the two headers seem to be identical.
但是,当我在执行 Http.MultipartFormData body = request()。body()。asMultipartFormData();
之后调试Play 2 API时,我注意到多部分数据不在正确解析。
However when I debug the Play 2 API after executing Http.MultipartFormData body = request().body().asMultipartFormData();
I noticed that the multipart data are not being parsed correctly.
更具体地说,体变量中的multipart字段如下:
More specifically the multipart filed in the body variable is as follows:
MultipartFormData(Map(),List(),List(BadPart(Map(ntent-type -> text/plain; charset=utf-8, content-disposition -> form-data; name=json)), BadPart(Map()), BadPart(Map()), BadPart(Map()), BadPart(Map())),List())
您可以注意到它有几个(本例中实际为5个)BadParts。
示例: BadPart(Map(ntent-type) - >文本/无格式; charset = utf-8,content-disposition - >形式数据; name = json))
As you can notice it has several (actually 5 in this example) BadParts.
Example: BadPart(Map(ntent-type -> text/plain; charset=utf-8, content-disposition -> form-data; name=json))
谁能看到这里出了什么问题? HttpClient生成的标题是错误的吗?
Can anyone see what is going wrong here? Is the header generated by HttpClient wrong?
推荐答案
这是解决方案..(黑客)
Here is the solution.. (hack)
当边界中有引号时,Play Framework似乎存在问题。
There seems to be a problem with Play Framework when the boundary has quotes in it.
所以我在创建multipart后添加了以下代码为了删除它们:
So i added the following code after multipart is created in order to remove them:
var content = new MultipartFormDataContent();
foreach (var param in content.Headers.ContentType.Parameters.Where(param => param.Name.Equals("boundary")))
param.Value = param.Value.Replace("\"", String.Empty);
最后我不得不添加引号 \手动设置标题上的特定值,如下所示:
Finally i had to add quotes "\"" manually to specific values on the header like the following:
原文: Content-Disposition:form-data;命名=附件; filename = attachment.file
更改为: Content-Disposition:form-data; NAME = 附件; filename =attachment.file
和
原文: Content-Disposition:form-data; name = json
更改为: Content-Disposition:form-data; name =json
我认为在标题中的任何地方都没有引号是错误的,也许是解析应该相应地修改游戏框架。
I don't think that its a mistake to have quotes or not anywhere in the header and maybe the parsing on play framework should be fixed accordingly.
这篇关于HttpClient上传MultipartFormData来玩2框架的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!