0

I have some simple Python

import requests
response = requests.post(url+'users/', data = 'hallo')

And a simple ASP.Net Core API

public void Post(string value)
{
    var newUser = JsonConvert.DeserializeObject<User>(value);
    // [...]
}

When I breakpoint the C# code the incoming parameter 'value' is always null. I have tried sending JSON instead of a simple string, setting the headers to 'text/plain', 'application/json', or 'application/x-www-form-urlencoded' in Python but the result is the same. I have tried decorating the parameter [FromBody] in the ASP.Net Core API, but then I get a 400 error ("The input was invalid").

What am I missing?

(EDIT. Here is a hacky fix, definitely not an answer, but it may help people see what's wrong.

public void Post(string value)
{
    Request.EnableRewind();
    var body = "";
    using (var reader = new StreamReader(Request.Body))
    {
        Request.Body.Seek(0, SeekOrigin.Begin);
        body = reader.ReadToEnd();
    }
    value = body;
    var newUser = JsonConvert.DeserializeObject<User>(value);
    // [...]
}

Then value is set correctly. But if the value is sitting there in the body of the post, it is frustrating that using [FromBody] results in a 400 error.)

8
  • You need to tell MVC that the parameter is coming from the post body: [FromBody]string value Commented Feb 8, 2019 at 15:11
  • I mention that in the question. If I add [FromBody] then I get a 400 error back from the server. Commented Feb 8, 2019 at 15:12
  • And what is that 400 error? Commented Feb 8, 2019 at 15:12
  • What if you do data = { 'value' : 'hallo' } Commented Feb 8, 2019 at 15:14
  • So are you going to tell us what that 400 error is? There will be an error message in there that explains everything.... Commented Feb 8, 2019 at 15:35

2 Answers 2

3

Hi dumbledad I had this same issue, I guess you would have solved it but I wanted to post the solution here.

I had to send the data to params instead of data.

So on the Python side:

payload = {"type": "2"}
myheaders={'Content-type':'application/json', 'Accept':'application/json'}
r = requests.post(url=myurl,headers=myheaders, params=payload)

On the c# side:

[Route("MyFunction")]
[HttpPost]
public ActionResult GetOpenFootball_(string type){}

This mapped the value "2" to the string parameter called "type".

EDIT

I managed to get objects through the [From Body] tag in this way:

I changed the header to: _headers = {'Content-type': 'application/json', 'Accept': 'text/plain'}

I put my parameters into a json such as: jsondata = {"username":"selzero"}

Then I plugged that into the json property in request like: r = requests.post(url=_url, headers=_headers,json=jsondata)

This works, MVC controller [FromBody] likes it.

Sign up to request clarification or add additional context in comments.

1 Comment

I just came across this but thought I'd add a note. I think ASP.NET web APIs usually take in the data through the key value pairs in the url. Looking at Pythons docs, the params is what does that not json, or data. docs.python-requests.org/en/master/user/quickstart That's probably why if you tested with postman it would work fine. Bc I think postman passes data as parameters in the url query string. Also, kind of irrelevant but you don't necessarily need the headers part of the request.
0

If you make your request like this:

response = requests.post(url, data={'value' : 'hallo'})

Then this will associate 'hallo' with the method-parameter value:

[HttpPost]
public void Post(string value)
{
    Console.WriteLine(value);
}

If you need to send more data, you could also wrap your request in an object and fetch it by model-binding. See more here: Model Validation in ASP.NET Web API. It looks like that's what you're attempting to do anyways here: var newUser = JsonConvert.DeserializeObject<User>(value);

You can achieve this automatically like this:

response = requests.post(url, json={ 'FirstName' : 'john', 'LastName' : 'doe' })

Notice the use of json=. And in your controller:

public class User {
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

[HttpPost]
public void Post([FromBody] User user)
{
    Console.WriteLine(user.FirstName);
    Console.WriteLine(user.LastName);
}
// Outputs:
// john
// doe

Comments

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.