文件上传与产生额外的表单数据从MVC网页API [英] File Upload with Additonal Form Data to Web Api from MVC
问题描述
我想上载其他表单数据的文件,并通过MVC发布到网络API,但我不能完成的任务。
I am trying to upload a file with additional form data and post to Web API via MVC but i couldn't accomplish.
MVC侧
首先,我得到了提交的表单在MVC。下面是此动作
Firstly i got the submitted form at MVC. Here is the action for this.
[HttpPost]
public async Task<ActionResult> Edit(BrandInfo entity) {
try {
byte[] logoData = null;
if(Request.Files.Count > 0) {
HttpPostedFileBase logo = Request.Files[0];
logoData = new byte[logo.ContentLength];
logo.InputStream.Read(logoData, 0, logo.ContentLength);
entity.Logo = logo.FileName;
entity = await _repo.Update(entity.BrandID, entity, logoData);
}
else
entity = await _repo.Update(entity,entity.BrandID);
return RedirectToAction("Index", "Brand");
}
catch(HttpApiRequestException e) {
// logging, etc
return RedirectToAction("Index", "Brand");
}
}
下面code职位的Multipartform对Web API
Below code post the Multipartform to Web API
string requestUri = UriUtil.BuildRequestUri(_baseUri, uriTemplate, uriParameters: uriParameters);
MultipartFormDataContent formData = new MultipartFormDataContent();
StreamContent streamContent = null;
streamContent = new StreamContent(new MemoryStream(byteData));
streamContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data") {
FileName = "\"" + fileName + "\"",
Name = "\"filename\""
};
streamContent.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
formData.Add(streamContent);
formData.Add(new ObjectContent<TRequestModel>(requestModel, _writerMediaTypeFormatter), "entity");
return _httpClient.PutAsync(requestUri, formData).GetHttpApiResponseAsync<TResult>(_formatters);
正如你可以看到我试图发送文件数据和对象,具有相同的 MultipartFormDataContent
。我找不到更好的方式来送我的实体 ObjectContent
。另外,我使用JSON.Net串行
As you can see i am trying to send file data and object with same MultipartFormDataContent
. I couldn't find better way to send my entity as ObjectContent
. Also i am using JSON.Net Serializer
关于提琴手,似乎后全成。
Regarding to fiddler, post seems successfull.
PUT http://localhost:12836/api/brand/updatewithlogo/13 HTTP/1.1
Content-Type: multipart/form-data; boundary="10255239-d2a3-449d-8fad-2f31b1d00d2a"
Host: localhost:12836
Content-Length: 4341
Expect: 100-continue
--10255239-d2a3-449d-8fad-2f31b1d00d2a
Content-Disposition: form-data; filename="web-host-logo.gif"; name="filename"
Content-Type: application/octet-stream
GIF89a��L������X�������wW����������xH�U�)�-�k6�������v6�������̥�v�J���������7����V:�=#�ի�I(�xf�$�������
// byte data
// byte data
'pf�Y��y�ؙ�ڹ�(�;
--10255239-d2a3-449d-8fad-2f31b1d00d2a
Content-Type: application/json; charset=utf-8
Content-Disposition: form-data; name=entity
{"BrandID":13,"AssetType":null,"AssetTypeID":2,"Logo":"web-host-logo.gif","Name":"Geçici Brand","Models":null,"SupplierBrands":null}
--10255239-d2a3-449d-8fad-2f31b1d00d2a--
网络API侧
最后我正在追赶在后的Web API侧,试图解析,但我不能。因为 MultipartFormDataStreamProvider
的的FileData code>和
FORMDATA
集合是百达空
Finally i am catching post at Web API side and trying to parse but i couldn't. Because MultipartFormDataStreamProvider
's FileData
and FormData
collections are allways empty.
[HttpPut]
public void UpdateWithLogo(int id) {
if(Request.Content.IsMimeMultipartContent()) {
var x = 1; // this code has no sense, only here to check IsMimeMultipartContent
}
string root = HttpContext.Current.Server.MapPath("~/App_Data");
var provider = new MultipartFormDataStreamProvider(root);
try {
// Read the form data.
Request.Content.ReadAsMultipartAsync(provider);
foreach(var key in provider.FormData.AllKeys) {
foreach(var val in provider.FormData.GetValues(key)) {
_logger.Info(string.Format("{0}: {1}", key, val));
}
}
// This illustrates how to get the file names.
foreach(MultipartFileData file in provider.FileData) {
_logger.Info(file.Headers.ContentDisposition.FileName);
_logger.Info("Server file path: " + file.LocalFileName);
}
}
catch(Exception e) {
throw new HttpApiRequestException("Error", HttpStatusCode.InternalServerError, null);
}
}
我希望你能帮忙找到我的错误。
I hope you can help to find my mistake.
更新
我也意识到这一点,如果我注释掉 StreamContent
或 ObjectContent
和只添加的StringContent,我仍然可以吨得到任何东西从 MultipartFormDataStreamProvider
。
I also realized that, if i comment out StreamContent
or ObjectContent
and only add StringContent, still i can't get anything from MultipartFormDataStreamProvider
.
推荐答案
最后我解决我的问题,这是所有关于异步:)
Finally i resolved my problem and it was all about async :)
正如你可以在API的操作方法我已经叫 ReadAsMultipartAsync
synchrously方法看,但这是一个错误。我与 ContinueWith
等以后我改变了我的code像下面我的问题解决了调用它。
As you can see at API action method i had called ReadAsMultipartAsync
method synchrously but this was a mistake. I had to call it with ContinueWith
so after i changed my code like below my problem solved.
var files = Request.Content.ReadAsMultipartAsync(provider).ContinueWith<HttpResponseMessage>(task => {
if(task.IsFaulted)
throw task.Exception;
// do additional stuff
});
这篇关于文件上传与产生额外的表单数据从MVC网页API的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!