Zyo
Zyo

Reputation: 2068

C# WebClient using UploadString to call HttpPost method from an ApiController also in C#. 415 or 400 error

I want in C# to call an ApiController also in C# but I'm getting error 415 or 400 when uploading the Json using the UploadString method from the WebClient instance.

The server code is the auto-generated call TestController. The file is exactly how Visual Studio 2019 generate it.

[Route("api/[controller]")]
[ApiController]
public class TestController : ControllerBase
{
    // GET: api/Test
    [HttpGet]
    public IEnumerable<string> Get()
    {
        return new string[] { "value1", "value2" };
    }

    // POST: api/Test
    [HttpPost]
    public void Post([FromBody] string value)
    {
    }
    ...
}

The client code look like that:

WebClient client = new WebClient();
client.UploadString("https://localhost:44345/api/Test", "ABC");   // Edit: "ABC" is not a valid JSON

I'm getting System.Net.WebException: 'The remote server returned an error: (415) Unsupported Media Type.'

So after googling, most suggest is the ContentType not getting specify, if I add

client.Headers[HttpRequestHeader.ContentType] = "application/json";

I get System.Net.WebException: 'The remote server returned an error: (400) Bad Request.'

Any clue?

Seems like the problem is related to the POST/PUT/PATCH... if I do the GET, it's working and returning me the sample data ["value1","value2"]

Edit: I'm not stick to using WebClient.UploadString method but I would like a solution that doesn't involved 25 lines of custom code... I means I can't believe it's that hard where you can do it in jQuery using a single line.

Upvotes: 6

Views: 6050

Answers (2)

A_Sk
A_Sk

Reputation: 4630

Simple Solution:

Specify Content-type in header while calling the API,

            WebClient client = new WebClient();
            client.Headers.Add("Content-Type", "text/json");
            client.UploadString("https://localhost:44345/api/Test", "\"ABC\"");

Edit:

Don't use [From_Body] attribute as it has terrible error handling capability, see Here.

If request body has any invalid input(syntax error,unsupported input) then it'll throw 400 and 415 for bad request and unsupported content. for the same reason it may take null as input from the request body it it doesn't understand the format.

So, remove the attribute and try uploading the string in plain format as it accept only String and you doesn't required to specify the Content-Type attribute while making the request.

[HttpPost]
 public void Post(string value)
 {

 }

And call it like how you were calling in your original post.

WebClient client = new WebClient();
client.UploadString("https://localhost:44345/api/Test", "ABC");

Upvotes: 2

Kirk Larkin
Kirk Larkin

Reputation: 93093

I'm getting System.Net.WebException: 'The remote server returned an error: (415) Unsupported Media Type.'

When you use [FromBody], the Content-Type header is used in order to determine how to parse the request body. When Content-Type isn't specified, the model-binding process doesn't know how to consume the body and therefore returns a 415.

I get System.Net.WebException: 'The remote server returned an error: (400) Bad Request.'

By setting the Content-Type header to application/json, you're instructing the model-binding process to treat the data as JSON, but ABC itself isn't valid JSON. If you just want to send a JSON-encoded string, you can also wrap the value in quotes, like this:

client.UploadString("https://localhost:44345/api/Test", "\"ABC\"");

"ABC" is a valid JSON string and will be accepted by your ASP.NET Core API.

Upvotes: 8

Related Questions