9

I currently am able to save a file being uploaded to a WebAPI controller, but I'd like to be able to save the file as a guid with the correct file name extension so it can be viewed correctly.

Code:

 [ValidationFilter]
    public HttpResponseMessage UploadFile([FromUri]string AdditionalInformation)
    {
        var task = this.Request.Content.ReadAsStreamAsync();
        task.Wait();

        using (var requestStream = task.Result)
        {
            try
            {
                // how can I get the file extension of the content and append this to the file path below?

                using (var fileStream = File.Create(HttpContext.Current.Server.MapPath("~/" + Guid.NewGuid().ToString())))
                {
                    requestStream.CopyTo(fileStream);
                }
            }
            catch (IOException)
            {                    
                throw new HttpResponseException(HttpStatusCode.InternalServerError);
            }
        }

        HttpResponseMessage response = new HttpResponseMessage();
        response.StatusCode = HttpStatusCode.Created;
        return response;
    }

I can't seem to get a handle on the actual filename of the content. I thought headers.ContentDisposition.FileName might be a candidate but that doesn't seem to get populated.

4
  • Here is a similar question with an answer [stackoverflow.com/questions/14937926/… [1]: stackoverflow.com/questions/14937926/… Commented May 28, 2013 at 21:05
  • Could you share how your request's headers look like? do you have the ContentDisposition header populated in the request? Commented May 28, 2013 at 21:14
  • It's the responsibility of the client to set such headers. What does your client look like? Commented May 28, 2013 at 21:52
  • @Kiran: No it isn't populated. Also, all the examples seem to use a stream provider to load the stream. I would like to read it without using a provider and save the file with a guid and extension. The reason for not using a stream provider is that it doesn't seem to allow me to return to the calling function the guid created for the file. Commented May 29, 2013 at 7:27

1 Answer 1

19

Thanks for the comments above which pointed me in the right direction.

To clarify the final solution, I used a MultipartFormDataStreamProvider which streams the file automatically. The code is in another question I posted to a different problem here: MultipartFormDataStreamProvider and preserving current HttpContext

My full provider code is listed below. The key to generating the guid file name is to override the GetLocalFileName function and use the headers.ContentDisposition property. The provider handles the streaming of the content to file.

public class MyFormDataStreamProvider : MultipartFormDataStreamProvider
{
    public MyFormDataStreamProvider (string path)
        : base(path)
    { }

    public override Stream GetStream(HttpContent parent, HttpContentHeaders headers)
    {
        // restrict what images can be selected
        var extensions = new[] { "png", "gif", "jpg" };
        var filename = headers.ContentDisposition.FileName.Replace("\"", string.Empty);

        if (filename.IndexOf('.') < 0)
            return Stream.Null;

        var extension = filename.Split('.').Last();

        return extensions.Any(i => i.Equals(extension, StringComparison.InvariantCultureIgnoreCase))
                   ? base.GetStream(parent, headers)
                   : Stream.Null;

    }

    public override string GetLocalFileName(System.Net.Http.Headers.HttpContentHeaders headers)
    {
        // override the filename which is stored by the provider (by default is bodypart_x)
        string oldfileName = headers.ContentDisposition.FileName.Replace("\"", string.Empty);
        string newFileName = Guid.NewGuid().ToString() + Path.GetExtension(oldfileName);

        return newFileName;       
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

Throws a null reference exception at var filename = headers.ContentDisposition.FileName.Replace("\"", string.Empty);. Fixed by checking if filename is not null before doing a Replace().
Why did you aldo override GetStream method?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.