Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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

like image 615
Rivka Avatar asked Jun 10 '12 17:06

Rivka


2 Answers

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

like image 177
Henrik Frystyk Nielsen Avatar answered Nov 20 '22 10:11

Henrik Frystyk Nielsen


I updated the code for the tutorial to make it work with ASP.NET Web API RC. Indeed, as Henrik mentioned Content-Disposition is no longer used a file name. See the source files at the bottom of the post - http://www.strathweb.com/2012/04/html5-drag-and-drop-asynchronous-multi-file-upload-with-asp-net-webapi/

Please note, that there are further changes to MultipartFormDataStreamProvider that didn't make the cut to the RC, so it's now even more flexible. Henrik blogged about those here - http://blogs.msdn.com/b/henrikn/archive/2012/04/27/asp-net-web-api-updates-april-27.aspx.

EDIT: I have blogged about new and improved way of uploading files in Web API RTM, so that should hopefully help gets things organized - http://www.strathweb.com/2012/08/a-guide-to-asynchronous-file-uploads-in-asp-net-web-api-rtm/

like image 19
Filip W Avatar answered Nov 20 '22 11:11

Filip W