The remote server returned an error: (415) Unsupported Media Type

57,383

Solution 1

+1 on what Radim has mentioned above...As per your action Web API model binding notices that the parameter fileContents is a complex type and by default assumes to read the request body content using the formatters. (note that since fileName and description parameters are of string type, they are expected to come from uri by default).

You can do something like the following to prevent model binding to take place:

[HttpPost]
[HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
[Route("UploadFile")]
public async Task UploadFile(string fileName, string description)
{
   byte[] fileContents = await Request.Content.ReadAsByteArrayAsync();

   ....
}

BTW, what do you plan to do with this fileContents? are you trying to create a local file? if yes, there is a better way to handle this.

Update based on your last comment:

A quick example of what you could do

[HttpPost]
[HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
[Route("UploadFile")]
public async Task UploadFile(string fileName, string description)
{
    Stream requestStream = await Request.Content.ReadAsStreamAsync();

    //TODO: Following are some cases you might need to handle
    //1. if there is already a file with the same name in the folder
    //2. by default, request content is buffered and so if large files are uploaded
    //   then the request buffer policy needs to be changed to be non-buffered to imporve memory usage
    //3. if exception happens while copying contents to a file

    using(FileStream fileStream = File.Create(@"C:\UploadedFiles\" + fileName))
    {
        await requestStream.CopyToAsync(fileStream);
    }

    // you need not close the request stream as Web API would take care of it
}

Solution 2

You are setting the ContentType = "text/plain", and this settings drive the Formatter selection. Please check Media Formatters for more details.

An extract:

In Web API, the media type determines how Web API serializes and deserializes the HTTP message body. There is built-in support for XML, JSON, and form-urlencoded data, and you can support additional media types by writing a media formatter.

So, there is no built in text/plain formatter, ie: Unsupported Media Type. You can change the content-type to some supported, built-in, or implement custome one (as described in the link)

Share:
57,383
NoWar
Author by

NoWar

[email protected]

Updated on January 04, 2020

Comments

  • NoWar
    NoWar over 4 years

    I try to upload a text file from WPF RESTful client to ASP .NET MVC WebAPI 2 website.

    Client code

    HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create("http://localhost:22678/api/Account/UploadFile?fileName=test.txt&description=MyDesc1");
    
    request.Method = WebRequestMethods.Http.Post;
    request.Headers.Add("Authorization", "Bearer " + tokenModel.ExternalAccessToken);  
    request.ContentType = "text/plain";
    request.MediaType = "text/plain";
    byte[] fileToSend = File.ReadAllBytes(@"E:\test.txt");  
    request.ContentLength = fileToSend.Length;
    
    using (Stream requestStream = request.GetRequestStream())
    {
          // Send the file as body request. 
          requestStream.Write(fileToSend, 0, fileToSend.Length);
          requestStream.Close();
    }
    
    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                            Console.WriteLine("HTTP/{0} {1} {2}", response.ProtocolVersion, (int)response.StatusCode, response.StatusDescription);
    

    WebAPI 2 code

    [HttpPost]
    [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
    [Route("UploadFile")]
    public void UploadFile(string fileName, string description, Stream fileContents)
    {
        byte[] buffer = new byte[32768];
        MemoryStream ms = new MemoryStream();
        int bytesRead, totalBytesRead = 0;
        do
        {
            bytesRead = fileContents.Read(buffer, 0, buffer.Length);
            totalBytesRead += bytesRead;
    
            ms.Write(buffer, 0, bytesRead);
        } while (bytesRead > 0);
    
       var data = ms.ToArray() ;
    
        ms.Close();
        Debug.WriteLine("Uploaded file {0} with {1} bytes", fileName, totalBytesRead);
    }
    

    So.. Under the client code I am facing that exception

    The remote server returned an error: (415) Unsupported Media Type.

    Any clue what do I am missing?