ASP.NET web api cannot get application/x-www-form-urlencoded HTTP POST
Solution 1
Quoting from here:
By default, Web API tries to get simple types from the request URI. The FromBody attribute tells Web API to read the value from the request body.
Web API reads the response body at most once, so only one parameter of an action can come from the request body. If you need to get multiple values from the request body, define a complex type.
Second, the client needs to send the value with the following format:
=value
Specifically, the name portion of the name/value pair must be empty for a simple type.
So, if you want to post data in the format data=string
, you have to create complex type.
public class MyFormData
{
public string Data { get; set; }
}
And update your controller like so:
public void Post(MyFormData formData)
{
//your JSON string will be in formData.Data
}
Of course, other alternatives for you is to change the content type to JSON, but really depends on your requirements.
Solution 2
This post is old, but I stumbled on it while searching for answer. I'll post how I got mine to work, maybe someone will find it useful.
Here's the request:
POST /api/values HTTP/1.1
Host: localhost:62798
Accept: text/json
Content-Type: application/x-www-form-urlencoded
Cache-Control: no-cache
Postman-Token: 51ee1c5f-acbb-335b-35d9-d2b8e62abc74
UID=200&EMAIL=john%40jones.com&FIRST_NAME=John&LAST_NAME=jones&PHONE=433-394-3324&CITY=Seattle&STATE_CODE=WA&ZIP=98105
Here's the Model:
public class SampleModel{
public string UID { get; set; }
public string Email { get; set; }
public string First_Name { get; set; }
public string Last_Name { get; set; }
public string Phone { get; set; }
public string City { get; set; }
public string State_Code { get; set; }
public string Zip { get; set; }
}
And here's the POST method that automagically(FromBody) converts urlencoded values to the model.
public HttpResponseMessage Post([FromBody] SampleModel value){
I was able to pick out any value i.e.
SearchCity(value.City);
SearchName(value.Last_Name);
Solution 3
You should create an object of your data like:
public class Device
{
public string mac {get;set;}
public string model {get;set;}
}
then change your controller's action method like this and pass your object to this method from consume
public void Post(Device deviceData)
{
// You can extract data like deviceData.mac, deviceData.model etc
data.Add(deviceData);
}
You can use one of the popular library json.net for serialize/deserialize of json object in C#
Solution 4
create a model
public class MyClass {
public string mac { get; set; }
public string model { get; set; }
}
and use .net JavaScriptSerializer().Deserialize
public void Post([FromBody]string formData){
MyClass obj = new System.Web.Script.Serialization.JavaScriptSerializer().Deserialize<MyClass>(formData);
//get mac and model by obj.mac obj.model
}
cheers :)
Solution 5
For asp.net core 3.x you need to supply the correct decorators to handle the request correctly:
[HttpPost("MyPostHandler")]
[Consumes("application/x-www-form-urlencoded")]
public async Task<IActionResult> MyPostHandler([FromForm] string id)
{
}
Jun
Updated on May 04, 2020Comments
-
Jun about 4 years
I'm new to web-api. I want to receive a HTTP POST data using web-api. The content-type is
application/x-www-form-urlencoded
, and the request body is like:data={"mac":"0004ED123456","model":"SG6200NXL"}
(JSON format).My controller is like this:
public void Post([FromBody]string formData) { data.Add(formData); }
But formData is always null. Only when I change the request body to:
={"mac":"0004ED123456","model":"SG6200NXL"}
I can find
{"mac":"0004ED123456","model":"SG6200NXL"}
was saved in myformData
string.So my question is how should I receive the data with format:
data={"mac":"0004ED123456","model":"SG6200NXL"}
?And is there a easy way that I can desalinize the JSON into C#?
Thanks for help!
UPDATE: I tried to use model, but it still not work for me. My model is:
public class Device { public string mac { get; set; } public string model { get; set; } }
and my HTTP POST request is:
header:
User-Agent: Fiddler Content-type: application/x-www-form-urlencoded Host: localhost:52154 Content-Length: 46
body:
data={"mac":"0004ED123456","model":"SG6200NX"}
I have to use
Content-type: application/x-www-form-urlencoded
as far as I know because the HTTP POST is sent by a router. My job is to receive the data. -
Jun over 10 yearsI tried your way but it seems not work for me. I still got null value. My post request header is User-Agent: Fiddler Content-type: application/x-www-form-urlencoded Host: localhost:52154, and request body is data={"mac":"0004ED123456","model":"SG6200NX"}, I can only see a null value add to my data string list.
-
Jun over 10 yearsI tried this way but it still not work for me. Please see my update. Thanks for your help.
-
YK1 over 10 yearsyour updated
Device
model would work if you send data inmac=string&model=string
format. But your format isdata=string
, so you have to have a single property calleddata
as I have shown in my answer. -
jplara over 6 yearshow would map the form data to my class if the name has hyphens? like data={"mac":"0004ED123456","model":"SG6200NX","device-id":"aUniqueId"}
-
YK1 over 6 years@jplara - i think you may have to go for a custom formatter - c-sharpcorner.com/article/…
-
jplara over 6 yearsi found another option, the custom formatter was overkill for my purposes, you can accept
FormDataCollection
and that would give you access to the posted data -
Liam almost 6 yearsSerialising the model yourself is totally unnecessary.