File upload 从MVC将带有附加表单数据的文件上载到Web Api

File upload 从MVC将带有附加表单数据的文件上载到Web Api,file-upload,asp.net-mvc-4,asp.net-web-api,multipartform-data,File Upload,Asp.net Mvc 4,Asp.net Web Api,Multipartform Data,我试图上传一个包含额外表单数据的文件,并通过MVC发布到Web API,但我无法完成 MVC侧 首先我在MVC拿到了提交的表格。下面是这方面的行动 [HttpPost] public async Task<ActionResult> Edit(BrandInfo entity) { try { byte[] logoData = null;

我试图上传一个包含额外表单数据的文件,并通过MVC发布到Web API,但我无法完成

MVC侧

首先我在MVC拿到了提交的表格。下面是这方面的行动

    [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");
                }
            }
Web API端

最后,我在WebAPI端看到了这篇文章,并试图解析,但我做不到。因为
MultipartFormDataStreamProvider
FileData
FormData
集合总是空的

[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);
            }              
        }
我希望你能帮我找出错误

更新


我还意识到,如果我注释掉
StreamContent
ObjectContent
,只添加StringContent,我仍然无法从
MultipartFormDataStreamProvider

中获得任何信息,最后我解决了我的问题,这一切都是关于异步的:)

正如您在API操作方法中看到的,我同步调用了
ReadAsMultipartAsync
方法,但这是一个错误。我不得不用
ContinueWith
调用它,所以在我像下面这样更改代码之后,我的问题就解决了

var files = Request.Content.ReadAsMultipartAsync(provider).ContinueWith<HttpResponseMessage>(task => {
                    if(task.IsFaulted)
                        throw task.Exception;
// do additional stuff
});
var files=Request.Content.ReadAsMultipartAsync(provider.ContinueWith)(任务=>{
if(task.IsFaulted)
抛出任务异常;
//做额外的事情
});

啊,我忘了那个限制。对不起,我有点困惑。具体的任务是什么?我也应该把表单数据放在这里吗?也许你找到了?我想看到整个工作更新,如果是的话possible@TomasHesse我很想帮忙,但我离开了那份工作,不再访问那些代码块。我遇到了一个稍微不同的问题-浏览器从请求中删除了我的文件,直到我给了他们一个名称/id。这对诊断问题有很大帮助
[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);
            }              
        }
var files = Request.Content.ReadAsMultipartAsync(provider).ContinueWith<HttpResponseMessage>(task => {
                    if(task.IsFaulted)
                        throw task.Exception;
// do additional stuff
});