Error with ReadAsMultipartAsync and MultiPartFormDataStreamP
本文关键字:MultiPartFormDataStreamP and ReadAsMultipartAsync with Error | 更新日期: 2023-09-27 18:34:55
我正在尝试将文件异步上传到我的Web服务器(ASP.NET MVC(。特别是我的 Web API 终结点。我遵循了几个教程,但不断收到空参数错误。
它发生在我子类MultipartFormDataStreamProvider
.该方法GetLocalFileName
,首先被正确调用,使用正确的HttpContentHeaders
,但随后使用null
标头第二次调用。
该文件使用我设置的文件名成功保存,但是当我遇到异常时,我无法知道生成的名称是什么。
但是,如果我只使用基MultipartFormDataStreamProvider
类,则文件可以完美保存,没有错误,但在这种情况下我无法控制文件名。
这是 api 方法:
[HttpPost]
public async Task<FilesUploadResult> Save()
{
// Check if the request contains multipart/form-data.
if (!Request.Content.IsMimeMultipartContent())
{
var ret = new FilesUploadResult(HttpStatusCode.UnsupportedMediaType, null);
ret.Message = "Unsupported Media Type. Request must contain multipart/form-data form.";
return ret;
}
var path = UploadsFolderPath;
// to-do: this works but for some reason makes a call with empty headers.
var provider = new SimpleMultipartFormDataStreamProvider(path);
// this provider saves the file with an arbritrary name
//var provider = new MultipartFormDataStreamProvider(path);
try
{
// Read the form data.
await Request.Content.ReadAsMultipartAsync(provider as MultipartFormDataStreamProvider);
var files = from f in provider.FileData
let info = new FileInfo(f.LocalFileName)
select new FileUploadDescription(info.Name, path + "''" + info.Name, info.Length, HttpStatusCode.Created);
var ret = new FilesUploadResult(HttpStatusCode.OK, files);
return ret;
}
catch (Exception ex)
{
var ret = new FilesUploadResult(HttpStatusCode.InternalServerError, null);
ret.Message = ex.Message;
return ret;
}
}
这是我SimpleMultipartFormDataStreamProvider
的代码:
public class SimpleMultipartFormDataStreamProvider : MultipartFormDataStreamProvider
{
public SimpleMultipartFormDataStreamProvider(string path) : base(path) { }
public override string GetLocalFileName(HttpContentHeaders headers)
{
// make sure the headers are valid
if (headers == null)
{
throw new ArgumentNullException("headers");
}
// filename
var filename = CleanString(headers.ContentDisposition.FileName); ;
// create the local file name
var localFileName = string.Format("_{0}_{1}", GetRandomName(), filename);
//this is here because Chrome submits files in quotation marks which get treated as part of the filename and get escaped
return localFileName.Replace("'"", string.Empty);
}
private string GetRandomName()
{
return GuidHelper.ShortUniqueId(16);
}
private static string CleanString(string str)
{
if (string.IsNullOrWhiteSpace(str))
return string.Empty;
var sb = new StringBuilder();
foreach (char c in str)
{
if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || c == '.' || c == '_')
{
sb.Append(c);
}
}
return sb.ToString();
}
}
谁能告诉我为什么我两次调用GetLocalFileName
,第二次用空标题调用?
即使我在 MVC4 中也遇到过这种行为,它提交 2 个文件,其中一个是空的,所以最好检查文件是否有任何内容,然后继续保存文件。为此可以有多种方法: 其中之一是从Request.Files
获取所有文件的列表(这是一个字符串数组(
foreach (string fileName in Request.Files)
{
HttpPostedFileBase file = Request.Files[fileName];
//Save file content goes here
if (file != null && file.ContentLength > 0)
{
//logic to save the content
}
}
GetLocalFileName 为分段请求中的每个文件调用一次。如果在同一请求中发送两个文件,则 GetLocal文件名将被调用两次。我认为您应该检查如何调用该服务并使用提琴手或类似的东西,以查看您是否真的在发送两个文件。如果在同一请求中发送多个部分,请尝试指定每个部分的内容类型。
我自己想通了。
问题是我实现的用于子类MultipartDataStreamProvider
的类在不同的项目中。
该项目引用了 .Net 。与 Web API 项目中的当前程序集不同的 HTTP 程序集。
我唯一做的就是将CustomMultipartDataStreamProvider类移动到同一个项目中,一切都运行良好。