ReadAsMultipartAsync 实际上是如何工作的?

see*_*uit 5 .net c# asp.net multipartform-data asp.net-web-api

canvas我正在使用 FormData API 上传网站中的一个元素。我是这样做的:

upload: function (e) {
    var file = this.imagePreview.ui.canvas.get(0).toDataURL("image/jpeg")
                   .replace('data:image/jpeg;base64,', '');
    if (file) {
        var formData = new FormData();
        formData.append('file', file);
        $.ajax({
            url: app.getApiRoot + 'UserFiles/',
            type: "post",
            data: formData,
            processData: false,
            contentType: false,
            error: function () {
                $("#file_upload_result").html('there was an error while submitting');
            }
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

data:image/jpeg;base64,我将根据这篇文章替换整个业务业务。

在后端我有以下多部分控制器:

public async Task<IHttpActionResult> PostUserFile()
{
    string imageDir = ConfigurationManager.AppSettings["UploadedImageDir"];
    var PATH = HttpContext.Current.Server.MapPath("~/" + imageDir);
    var rootUrl = Request.RequestUri.AbsoluteUri.Replace(Request.RequestUri.AbsolutePath, String.Empty);

    if (Request.Content.IsMimeMultipartContent())
    {
        var streamProvider = new CustomMultipartFormDataStreamProvider(PATH);
        await Request.Content.ReadAsMultipartAsync(streamProvider).ContinueWith(t =>
        {
            if (t.IsFaulted || t.IsCanceled)
            {
                throw new HttpResponseException(HttpStatusCode.InternalServerError);
            }

            var files = streamProvider.FileData.Select(i =>
                        {
                            var info = new FileInfo(i.LocalFileName);
                            return new UserFile(User.Identity.GetUserId(), info.Name, rootUrl + "/" + imageDir + "/" + info.Name, info.Length / 1024);
                        });

            db.UserFiles.AddRange(files);
            db.SaveChangesAsync();
        });

        return Ok();
    }
    else
    {
        throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotAcceptable, "This request is not properly formatted"));
    }
}
Run Code Online (Sandbox Code Playgroud)

我的实现如下CustomMultipartFormDataStreamProvider

public class CustomMultipartFormDataStreamProvider : MultipartFormDataStreamProvider
{
    public CustomMultipartFormDataStreamProvider(string path)
        : base(path)
    { }

    public override string GetLocalFileName(Headers.HttpContentHeaders headers)
    {
        var name = !string.IsNullOrWhiteSpace(headers.ContentDisposition.FileName) ? 
                      headers.ContentDisposition.FileName : 
                      "NoName";
        // This is here because Chrome submits files in quotation 
        // marks which get treated as part of the filename and get escaped
        return name.Replace("\"\"", string.Empty);
    }
}
Run Code Online (Sandbox Code Playgroud)

遗憾的是,输入到方法中的内容FileDatastreamProviderReadAsMultipartAsync的:

文件数据计数 = 0

我发现有趣的另一件事是上传的二进制文件被转义,正如我从监视窗口中注意到的那样:

转义数据

%2f是字符的转义序列/

我根本无法确定问题所在。有人有什么建议吗?

Cri*_*n18 0

混合使用ContinueWith和async/await会导致问题,只要这样做await Request.Content.ReadAsMultipartAsync(streamProvider);,其中的所有内容.ContinueWith都会像正常代码一样在await之后进行。

\n\n

或者删除 async/await 并添加:

\n\n
return Request.Content.ReadAsMultipartAsync(streamProvider).Continu\xe2\x80\x8c\xe2\x80\x8beWith...\n
Run Code Online (Sandbox Code Playgroud)\n\n

您也可以查看此链接:Sending HTML Form Data in ASP.NET Web API: File Upload and Multipart MIME

\n