ASP.NET Web API File saved as "BodyPart_3ded2bfb-40be-4183-b789-9301f93e90af"

Rivka picture Rivka · Jun 10, 2012 · Viewed 24.2k times · Source

I'm uploading files using the ASP.NET Web API. I've done this before the RC but for some reason the file is being saved as "BodyPart_3ded2bfb-40be-4183-b789-9301f93e90af" instead of the file name. The filename variable below returns this bodypart string too instead of the file name. I can't seem to figure out where I'm going wrong. Any help is appreciated.

Client code:

function upload() {
    $("#divResult").html("Uploading...");
    var formData = new FormData($('form')[0]); 
    $.ajax({
        url: 'api/files/uploadfile?folder=' + $('#ddlFolders').val(),
        type: 'POST',
        success: function (data) {
            $("#divResult").html(data);
        },
        data: formData,
        cache: false,
        contentType: false,
        processData: false
    });
}; 

Controller:

    public Task<HttpResponseMessage> UploadFile([FromUri]string folder)
    {
        if (!Request.Content.IsMimeMultipartContent())
        {
            throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.UnsupportedMediaType));
        }

        // Save file
        MultipartFormDataStreamProvider provider = new MultipartFormDataStreamProvider(HttpContext.Current.Server.MapPath("~/Files"));
        Task<IEnumerable<HttpContent>> task = Request.Content.ReadAsMultipartAsync(provider);

        return task.ContinueWith<HttpResponseMessage>(contents =>
        {
            string filename = provider.BodyPartFileNames.First().Value;
            return new HttpResponseMessage()
          {
              Content = new StringContent(string.Format("File saved in {0}.", folder))
          };

        }, TaskScheduler.FromCurrentSynchronizationContext());

The files are looking like:

enter image description here

Answer

Henrik Frystyk Nielsen picture Henrik Frystyk Nielsen · Jun 10, 2012

That was a concious change we made -- it was considered a security risk to take the file name provided in the Content-Disposition header field and so instead we now compute a file name which is what you are seeing.

If you want to control the server local file name yourself then you can derive from MultipartFormDataStreamProvider and override GetLocalFileName to provide whatever name you want. Note though that there may be security considerations doing so.

Hope this helps,

Henrik