Web API 2中的文件上载问题
虽然我上传文件并附上表单发布此工作文件,但我发送来自Rest Client的相同信息,例如Google Chrome中的Postman或使用Android或iOS应用程序发布文件信息Web Api 2代码未检测到文件multipart / form-post
以下是我的HTML代码
<form enctype="multipart/form-data" method="post" action="/api/feedback">
<input type="text" name="Scope" placeholder="Scope" value="feedback">
<input type="text" name="Lang" placeholder="Lang" value="en">
<input type="text" name="Collection" placeholder="Collection" value="7b22437573746f6d65724964223a392c2253657276696365526571756573744964223a312c224174746974756465223a332e322c22576f726b457468696373223a342e322c2248796769656e65223a352c22416d6f757450616964223a333132332e327d">
<input type="file" name="Photo1" placeholder="Photo1">
<input type="file" name="Photo2" placeholder="Photo2">
<input type="file" name="Signature" placeholder="Signature">
<input type="submit" value="Submit">
</form>
此.Net Web Api 2代码
public async Task<Result> Post()
{
var model = new ApiData();
var result = new Result();
if (Request.Content.IsMimeMultipartContent())
{
try
{
string root = HttpContext.Current.Server.MapPath("~/assets/temp");
var provider = new MultipartFormDataStreamProvider(root);
var sb = new System.Text.StringBuilder(); // Holds the response body
// Read the form data and return an async task.
await Request.Content.ReadAsMultipartAsync(provider);
// This illustrates how to get the form data.
foreach (var key in provider.FormData.AllKeys)
{
foreach (var val in provider.FormData.GetValues(key))
{
if (key.Equals("Scope"))
model.Scope = val;
if (key.Equals("Lang"))
model.Lang = val;
if (key.Equals("Collection"))
model.Collection = val;
}
}
if (!model.Scope.Equals("feedback", StringComparison.InvariantCultureIgnoreCase))
result.Text = "Missing Scope.";
else
{
var Util = new Utils();
model.Collection = Util.ToString(model.Collection);
var _Feedback = JsonConvert.DeserializeObject<Feedback>(model.Collection);
try
{
// This illustrates how to get the file names for uploaded files.
foreach (var file in provider.FileData)
{
FileInfo fileInfo = new FileInfo(file.LocalFileName);
string BaseUrl = HttpContext.Current.Server.MapPath("~/assets/feedback/");
string oldFile = file.Headers.ContentDisposition.FileName.TrimStart('"').TrimEnd('"');
string NewName = string.Format("{0}{1}", Util.NewGuid, Path.GetExtension(oldFile));
if (file.Headers.ContentDisposition.Name.ToLower().Contains("photo"))
{
_Feedback.Photos = string.IsNullOrEmpty(_Feedback.Photos) ? NewName : _Feedback.Photos + "," + NewName;
fileInfo.MoveTo(BaseUrl + NewName);
}
else if (string.IsNullOrEmpty(_Feedback.Signatures) && file.Headers.ContentDisposition.Name.ToLower().Contains("signature"))
{
_Feedback.Signatures = NewName;
fileInfo.MoveTo(BaseUrl + NewName);
}
}
}
catch { }
if (Util.IsRequired(_Feedback.CustomerId)
&& Util.IsRequired(_Feedback.ServiceRequestId)
&& Util.IsRequired(_Feedback.Attitude)
&& Util.IsRequired(_Feedback.WorkEthics)
&& Util.IsRequired(_Feedback.Hygiene)
)
{
var feedback = new Feedback()
{
CustomerId = _Feedback.CustomerId,
ServiceRequestId = _Feedback.ServiceRequestId,
Attitude = _Feedback.Attitude,
WorkEthics = _Feedback.WorkEthics,
Hygiene = _Feedback.Hygiene,
AmoutPaid = _Feedback.AmoutPaid,
Photos = _Feedback.Photos,
Signatures = _Feedback.Signatures,
Created = DateTime.UtcNow,
Updated = DateTime.UtcNow
};
db.Feedbacks.Add(feedback);
db.SaveChanges();
if (feedback.Id != default(int))
{
result.Success = true;
result.Text = "Success";
}
}
else
{
result.Text = "Required Parameters missing.";
}
}
}
catch
{
result.Text = "Error";
}
}
else
result.Text = "Signature or photo missing";
return result;
}
这是Postmen请求
在Fiddler客户端中公开发布请求我已经看到在使用html表单发布时,在multipart / form-data中存在边界;虽然Postman或其他RestClient中没有边界。
答案 0 :(得分:5)
这可能是邮递员bug。
总而言之,如果使用Postman设置Content-Type标头,它似乎会覆盖默认浏览器功能而不添加边界。大多数时候这是一件好事,但不适用于multipart / form-data,因为我们需要浏览器为我们添加边界。尝试删除Content-Type标头。发送实际的帖子时,浏览器会自动添加正确的标题并创建边界。
您的WebApi代码看起来很好。你的if检查只是假的。
//This will be false since it's a malformed request.
if (Request.Content.IsMimeMultipartContent())
答案 1 :(得分:1)
我知道这是一篇老文章,但是我认为这可以帮助遇到相同问题的人。在邮递员中删除Content-Type标头。该请求将通过。