I am using the FileUpload sample from the asp.net tutorials. When I build it as a stand alone, it works fine. However, whenever I try to add that functionality to a new MVC4 website, the routing is wrong. I’m probably not explaining this well, so here is the code:
[HttpPost]
public async Task<HttpResponseMessage> PostFile()
{
// Check if the request contains multipart/form-data.
if (!Request.Content.IsMimeMultipartContent())
{
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}
string root = HttpContext.Current.Server.MapPath("~/App_Data");
var provider = new MultipartFormDataStreamProvider(root);
try
{
var sb = new 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)
{
var strings = provider.FormData.GetValues(key);
if (strings != null) foreach(var val in strings)
{
sb.Append(string.Format("{0}: {1}\n", key, val));
}
}
// This illustrates how to get the file names for uploaded files.
foreach(var file in provider.FileData)
{
var fileInfo = new FileInfo(file.LocalFileName);
sb.Append(string.Format("Uploaded file: {0} ({1} bytes)\n", fileInfo.Name, fileInfo.Length));
}
return new HttpResponseMessage
{
Content = new StringContent(sb.ToString())
};
}
catch (System.Exception e)
{
return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, e);
}
}
Here is the page I’m using:
<div style="height:400px;">
<h3>File Upload</h3>
<form name="trip_search" method="post" enctype="multipart/form-data" action="api/upload">
<div>
<input type="radio" name="trip" value="round-trip"/>
Round-Trip
</div>
<div>
<input type="radio" name="trip" value="one-way"/>
One-Way
</div>
<div>
<input type="checkbox" name="options" value="nonstop" />
Only show non-stop flights
</div>
<div>
<input type="checkbox" name="options" value="airports" />
Compare nearby airports
</div>
<div>
<input type="checkbox" name="options" value="dates" />
My travel dates are flexible
</div>
<div>
<label for="seat">Seating Preference</label>
<select name="seat">
<option value="aisle">Aisle</option>
<option value="window">Window</option>
<option value="center">Center</option>
<option value="none">No Preference</option>
</select>
</div>
<div>
<input type="submit" value="Submit" />
</div>
</form>
When I directly navigate to localhost:13927api/upload I see a response from the web api method. I’ve got the DefaultApi route registered in my WebApiConfig.
But when I’m on the page localhost/Home/About and I click on the submit button, it attempts to go to localhost/Home/api/upload – which does not exist.
What am I missing?
EDIT
The suggestion by Mario fixed my issue. The action method on my form was not relative to the root.
action="api/upload" vs. action="/api/upload"
That fixes my problem.
A bit of elaboration on the issue:
When you are in the default path (say yoursite/Home/Index -> if that is your default), then the action=”api/myaction” will work because the current path is still seen as the root of the website. However, once you actually navigate to a path (say yoursite/Home/About), the current path is now under “Home” and so my missing “/” naturally was relative to my current path rather than the root. This is why the samples work without the leading “/”, because the view in question is the default view.
Added the answer, if that can help others too:
Your form
action="api/upload"is not relative to the root. Tryaction="/api/upload"or use one of the helpers to specify the route.