Reputation: 345
Issue with file upload in Web API 2
While i upload file with form post this work file but while i am sending same information from Rest Client like Postman in Google Chrome or posting file information with Android or iOS application Web Api 2 code is not detecting file multipart/form-post
Following is my html code
<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>
This .Net Web Api 2 Code
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;
}
This is Postmen request
Exposing post request in Fiddler Client i have seen that while posting using html form post there is boundary in multipart/form-data; although there is no boundary in Postman or other RestClient.
Upvotes: 1
Views: 3308
Reputation: 11
I know this an old post but I think this could help someone who has the same issue. In postman remove Content-Type header. The request will go through fine.
Upvotes: 1
Reputation: 1893
This may be a Postman bug.
To summarize, if you set the Content-Type header with Postman, it seems to override the default browser functionality and not add the boundary. Most the time this is a good thing, but not for multipart/form-data since we need the browser to add the boundary for us. Try removing the Content-Type header. When sending the actual Post, the browser will automatically add the proper header and create the boundary.
Your WebApi code looks fine. Your if check will just be false.
//This will be false since it's a malformed request.
if (Request.Content.IsMimeMultipartContent())
Upvotes: 5