1

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;
}
Paul S
  • 37
  • 1
  • 4
  • I am guessing - when you do `get`, it just makes no sense to pass a model. So, there is probably no support for it. You need to read protocol/specs. It is probably what it is – T.S. Jan 16 '19 at 20:17
  • @T.S. hmm, I personally find it cleaner to have a single object over multiple params – Paul S Jan 16 '19 at 20:24
  • It doesn't matter what you personally think. Only matter is REST spec. With GET you don't get to enjoy this. You have to POST something to read from request body – T.S. Jan 16 '19 at 21:23
  • ASP.NET Web API has a parameter binding attribute [FromUri] to read a complex type from the url :) – Paul S Jan 16 '19 at 21:27
  • That is correct. But not from body – T.S. Jan 16 '19 at 21:52

2 Answers2

1

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();
}
Marcus Höglund
  • 16,172
  • 11
  • 47
  • 69
  • the example posted is a simplified version of the one posted - I've renamed the endpoint to DoSomething() as it was misleading. – Paul S Jan 16 '19 at 21:00
  • I'm dealing with a GET request - according to the docs [FromQuery] may be an option. – Paul S Jan 16 '19 at 21:01
  • @PaulS Ok :). Then you should use FromUri attribute. It will compose the query strings into the model object – Marcus Höglund Jan 16 '19 at 21:04
0

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?

Ryan Schlueter
  • 2,223
  • 2
  • 13
  • 19