【问题标题】:using MultipartFormDataStreamProvider and ReadAsMultipartAsync使用 MultipartFormDataStreamProvider 和 ReadAsMultipartAsync
【发布时间】:2012-12-05 21:26:43
【问题描述】:

我将如何在ApiController 中使用MultipartFormDataStreamProviderRequest.Content.ReadAsMultipartAsync

我在谷歌上搜索了一些教程,但我无法让其中任何一个工作,我使用的是 .net 4.5。

这是我目前得到的:

public class TestController : ApiController
{
    const string StoragePath = @"T:\WebApiTest";
    public async void Post()
    {
        if (Request.Content.IsMimeMultipartContent())
        {
            var streamProvider = new MultipartFormDataStreamProvider(Path.Combine(StoragePath, "Upload"));
            await Request.Content.ReadAsMultipartAsync(streamProvider);
            foreach (MultipartFileData fileData in streamProvider.FileData)
            {
                if (string.IsNullOrEmpty(fileData.Headers.ContentDisposition.FileName))
                {
                    throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotAcceptable, "This request is not properly formatted"));
                }
                string fileName = fileData.Headers.ContentDisposition.FileName;
                if (fileName.StartsWith("\"") && fileName.EndsWith("\""))
                {
                    fileName = fileName.Trim('"');
                }
                if (fileName.Contains(@"/") || fileName.Contains(@"\"))
                {
                    fileName = Path.GetFileName(fileName);
                }
                File.Copy(fileData.LocalFileName, Path.Combine(StoragePath, fileName));
            }
        }
        else
        {
            throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotAcceptable, "This request is not properly formatted"));
        }
    }
}

我得到了异常

MIME 多部分流意外结束。 MIME 多部分消息不是 完成。

await task; 运行时。 有没有人知道我做错了什么或者在使用 web api 的普通 asp.net 项目中有一个工作示例。

【问题讨论】:

  • 如果t.IsFaulted 为真,则表示存在异常,它将填充到Exception 属性中。看看异常是什么。或者只是 await task; 以简化代码,除其他外,它将重新引发任何异常。
  • 将 ContinueWith 和 if 语句替换为“await task;”之后我收到“MIME 多部分流意外结束。MIME 多部分消息不完整。”
  • 我认为下面的帖子可能会有所帮助stackoverflow.com/questions/17177237/…

标签: c# asp.net asp.net-web-api


【解决方案1】:

我解决了错误,我不明白这与多部分流结束有什么关系,但这里是工作代码:

public class TestController : ApiController
{
    const string StoragePath = @"T:\WebApiTest";
    public async Task<HttpResponseMessage> Post()
    {
        if (Request.Content.IsMimeMultipartContent())
        {
            var streamProvider = new MultipartFormDataStreamProvider(Path.Combine(StoragePath, "Upload"));
            await Request.Content.ReadAsMultipartAsync(streamProvider);
            foreach (MultipartFileData fileData in streamProvider.FileData)
            {
                if (string.IsNullOrEmpty(fileData.Headers.ContentDisposition.FileName))
                {
                    return Request.CreateResponse(HttpStatusCode.NotAcceptable, "This request is not properly formatted");
                }
                string fileName = fileData.Headers.ContentDisposition.FileName;
                if (fileName.StartsWith("\"") && fileName.EndsWith("\""))
                {
                    fileName = fileName.Trim('"');
                }
                if (fileName.Contains(@"/") || fileName.Contains(@"\"))
                {
                    fileName = Path.GetFileName(fileName);
                }
                File.Move(fileData.LocalFileName, Path.Combine(StoragePath, fileName));
            }
            return Request.CreateResponse(HttpStatusCode.OK);
        }
        else
        {
            return Request.CreateResponse(HttpStatusCode.NotAcceptable, "This request is not properly formatted");
        }
    }
}

【讨论】:

  • 我们可以看一个例子来说明这个 Post 方法是如何被客户端调用的吗?
  • 我在以await 开头的行出现以下错误:“在 HttpRequest.GetBufferedInputStream 的调用者填充内部存储之前访问了 BinaryRead、Form、Files 或 InputStream。”您对可能的原因有什么建议吗?
  • @ciuncan 检查stackoverflow.com/questions/17602845/… 的答案,它可能会对您有所帮助!
  • @Peter 谢谢,我看到了那篇帖子,但看不到任何解决方案的建议,但可能是什么原因。他们还提到了 Web API 实现的一些问题,但这是一个一年前的帖子。我将 Web API 库升级到边缘版本(当前为 5.2.0)。其实我的代码和你的一模一样,我也在asp.net网站上查看了教程代码:asp.net/web-api/overview/working-with-http/…。除了ReadAsMultipartAsync 方法之外,我看不到还有什么在访问底层InputStream 等。
  • 原始代码的问题在于 API 不知道(也没有办法)知道 async void 方法何时结束。这就是为什么它设法在你阅读它的路上处理掉流。使用Task&lt;&gt;-returning 方法,调用代码有机会知道您何时准备好请求,并在您不再需要流时关闭流。每次看到async void,你都应该感到难过。
【解决方案2】:

首先你应该在ajax请求头中定义enctypemultipart/form-data。

[Route("{bulkRequestId:int:min(1)}/Permissions")]
    [ResponseType(typeof(IEnumerable<Pair>))]
    public async Task<IHttpActionResult> PutCertificatesAsync(int bulkRequestId)
    {
        if (Request.Content.IsMimeMultipartContent("form-data"))
        {
            string uploadPath = HttpContext.Current.Server.MapPath("~/uploads");

            var streamProvider = new MyStreamProvider(uploadPath);

            await Request.Content.ReadAsMultipartAsync(streamProvider);

            List<Pair> messages = new List<Pair>();
            foreach (var file in streamProvider.FileData)
            {
                FileInfo fi = new FileInfo(file.LocalFileName);
                messages.Add(new Pair(fi.FullName, Guid.NewGuid()));
            }

            //if (_biz.SetCertificates(bulkRequestId, fileNames))
            //{
            return Ok(messages);
            //}
            //return NotFound();
        }
        return BadRequest();
    }
}




public class MyStreamProvider : MultipartFormDataStreamProvider
{
    public MyStreamProvider(string uploadPath) : base(uploadPath)
    {
    }
    public override string GetLocalFileName(HttpContentHeaders headers)
    {
        string fileName = Guid.NewGuid().ToString()
            + Path.GetExtension(headers.ContentDisposition.FileName.Replace("\"", string.Empty));
        return fileName;
    }
}

【讨论】:

    猜你喜欢
    • 2015-02-20
    • 1970-01-01
    • 2013-07-31
    • 2018-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-14
    相关资源
    最近更新 更多