This is my webapi 2 endpoint - the MVC duplicate suggestion is not relevant
[Route("Test2")]
[HttpPost]
public IHttpActionResult Test2([FromBody] Guid? guid)
{
return Ok();
}
when I use fiddler to manually test this using:
Content-Type: application/json
in the header and this payload in the body:
{"guid":"1c3c8edc-d87a-46dc-adbf-e7112bf16d22"}
The method is hit but the guid is null. Any ideas?
It can't be deserialized directly to Guid. Now, you are sending object from fiddler, something like:
public class SampleObject
{
public Guid guid {get; set;}
}
Try send just:
"1c3c8edc-d87a-46dc-adbf-e7112bf16d22"
in the body of the request.
You send response through header. Thats why you get null. You have to send request through body.
public class Test
{
public Guid guid {get; set;}
}
you have to sent request through body like
"1c3c8edc-d87a-46dc-adbf-e7112bf16d22"
and if you want to send request through header then your code will be like this
[Route("Test2")]
[HttpPost]
public IHttpActionResult Test2()
{
IEnumerable<string> headerValues=request.Headers.GetValues("MyCustomID");
var guid = headerValues.FirstOrDefault();
return Ok();
}
Related
I am working on ASP.NET Core 2.1 Web API project. I am trying to follow this article: https://www.c-sharpcorner.com/article/jwt-json-web-token-authentication-in-asp-net-core/ but I am stuck at Action. My model class just won't bind to the input.
[AllowAnonymous]
[HttpPost]
public IActionResult Login([FromBody] LoginVM loginVM)
{
IActionResult response = Unauthorized(); // cant reach this point, my breakpoint is here
var user = AuthenticateUser(new UserModel { });
if (user != null)
{
var tokenString = GenerateJSONWebToken(user);
response = Ok(new { token = tokenString });
}
return response;
}
public class LoginVM
{
public string Username { get; set; }
public string Password { get; set; }
}
You're posting as x-www-form-urlencoded, but you have the [FromBody] attribute applied to the action param. These two things are fundamentally incompatible. To accept x-www-form-urlencoded (or multipart/form-data) you must apply the [FromForm] attribute to the param. If you have [FromBody], as you do now, then you can only accept something like application/json or application/xml (if you also enable the XML serializers).
If the issue is that you want to be able to accept both application/json and x-www-form-urlencoded request bodies, that is not possible. You'll need a separate action for each request body encoding, though you can factor out the actual meat of the action into a private method on the controller that both actions can utilize.
Choose "raw" in Body and "Content-Type" as "application/json" in postman and then try.
Inside my ASP.NET WebApi program, I have an Author model:
public class Author
{
public int Id { get; set; }
[Required] public string Name { get; set; }
}
I also have an AuthorsController, with a PostAuthor(Author author) method:
// POST: api/Authors
[ResponseType(typeof(Author))]
public async Task<IHttpActionResult> PostAuthor(Author author)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
// etc.
}
When I send a POST request programmatically inside my unit tests, HTTP Status Code 201 Created is returned:
However, when I send a POST request using Postman, I receive HTTP Status Code 400 Bad Request instead:
As you can see, when I send a POST request using Postman, the argument passed into the PostAuthor(Author author) method is null, and model validation fails as a result:
What should I do to ensure that POST requests from Postman can be processed?
Couple of changes: define it as HttpPost and use FromBody like
// POST: api/Authors
[HttpPost]
[ResponseType(typeof(Author))]
public async Task<IHttpActionResult> PostAuthor([FromBody] Author author)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
// etc.
}
Replace = with : in postman body, its a JSON after all.
If you send in application/json and your API wait as INBOUND JSON, so try to send in JSON format, something like
{
"Id":"6",
"Name":"P.G. Wodehouse"
}
I'm having an issue with an endpoint, it takes an object which isn't binding and consequently returning a 400 bad request.
I've gotten around this issue by passing in the individual properties of the object rather than the object itself, but would prefer the passing of an object.
WebClient webClient = new WebClient();
webClient.QueryString.Add("firstName", "value1");
webClient.QueryString.Add("lastName", "value2");
string result = webClient.DownloadString(url);
[HttpGet]
public async Task<IActionResult> DoSomething(string firstName, string lastName)
{
// this endpoint works perfectly
return Ok();
}
[HttpGet]
public async Task<IActionResult> DoSomething([FromBody]SubmitModel model)
{
// this endpoint returns a 400 bad request
return Ok();
}
public class SubmitModel
{
public string FirstName {get; set;}
public string LastName {get; set;
}
By design, GET request does not contain data in the request body.
So when your Submit method recieves a request, it can't bind the model from the body as the data does not exist and therefore returns an bad request response.
As your method is named Submit, it sounds like you should use a POST request instead. POST request, by design, sends data in the request body and is suited for submitting data to the server.
Try it like this
[HttpPost]
public async Task<IActionResult> Submit([FromBody]SubmitModel model)
{
// this endpoint returns a 400 bad request
return Ok();
}
I don't know if there is a good way to do what you're wanting. To get a little bit closer you can add this attribute to pull directly from the url
[HttpGet]
public ActionResult Get([FromUri]SubmitModel model)
{
// this endpoint returns a 400 bad request
return Ok();
}
Another thing you can do if need be is create an extension method that reflects over the model and adds all the properties/values to the query string. Some good examples here How do I serialize an object into query-string format?
I receive a null value always in web api rest post request to a controller
In my controller
[HttpPost]
public HttpResponseMessage PostCustomer([FromBody]Customer customer)
{
System.Diagnostics.Debug.WriteLine(customer); #CustomerApp.Models.Customer
System.Diagnostics.Debug.WriteLine(customer.FirstName); #null
}
Model
public class Customer
{
public int Id { get; set; }
public string LastName { get; set; }
public string FirstName { get; set; }
}
Request:
POST: http://localhost:21894/api/customer/postcustomer
Content-Type: application/json
body: {FirstName: "xxxx", LastName: 'yyyy'}
I tried the following solutions but nothing works out
https://myadventuresincoding.wordpress.com/2012/06/19/c-supporting-textplain-in-an-mvc-4-rc-web-api-application/
How to get POST data in WebAPI?
Can anybody guide me with help or the correct link
Answer:
Made a curl request instead of dealing with postman as like this gave me the solution
$ curl -H "Content-Type: application/json" -X POST -d '{"FirstName":"Jefferson","LastName":"sampaul"}' http://localhost
:21894/api/customer/postcustomer
I think you mean to have a Customer object as input like below instead of string
public HttpResponseMessage PostCustomer([FromBody]Customer customer)
{
Well make this below change and try reposting the request. It should work
public HttpResponseMessage PostCustomer(Customer customer)
{
return OK(customer.FirstName);
}
Request:
POST: http://localhost:21894/api/customer/postcustomer
Content-Type: application/json; charset=utf-8
{"Id":101,"FirstName":"xxxx","LastName":'yyyy'}
set your entity to be a customer not a string
[HttpPost]
public Customer PostCustomer(Customer customer)
{
System.Diagnostics.Debug.WriteLine(customer);
return customer;
}
Make sure you have [HttpPost] attribute on your method also no need for the [FromBody]
I have a webapi method as httppost as shown below. I am trying to make a request using
fiddler but I cant get param object. It is null if I send the request as shown in the image. what am I doing wrong?
[ActionName("getCustomerByName")]
[HttpPost]
public async Task<List<Customer>> GetcustomerByName(object param)
{
}
What do you expect object param to be?
Does the request body JSON string represent a Customer ?
If yes, use Customer as the type instead of object eg
public async Task<List<Customer>> GetCustomerByName(Customer param)
If no then define a class (Any name) with the same field names as the JSON string you are passing and use that class instead of object eg
public class QueryArgs
{
public int Id { get; set; }
// rest of your fields go here
}
public async Task<List<Customer>> GetCustomerByName(QueryArgs param)