Bind query parameters to a model in ASP.NET Core

43,853

Solution 1

You need to add [FromQuery] attribute to the model properties individually

public class Criteria
{
  [FromQuery(Name = "first_name")]
  public string FirstName { get; set; }
}

Solution 2

Solution for .net core 2.1, 2.2, 3.0 and 3.1

Or without attributes you can do something like this which is cleaner I think (of course if the model properties are same as query parameters).

Meanwhile I use it in .net core 2.1, 2.2 and 3.0 preview & 3.1.

public async Task<IActionResult> Get([FromQuery]ReportQueryModel queryModel) 
{ 

}

Solution 3

For anyone that got here from search engine like me:

To make it work on asp.net core 3.1+

public async Task<IActionResult> Get([FromQuery] RequestDto request);

public class RequestDto
{
  [FromQuery(Name = "otherName")]
  public string Name { get; set; }
}

Will read json property otherName into RequestDto.Name so basically you have to use FromQuery in 2 places. Above answers are IMHO too complicated for such a simple thing already provided in asp.net framework.

Solution 4

In my case, I had an issue where my parameter name was option and in my class I also had the property called option so it was collapsing.

public class Content
{
    
    public string Option { get; set; }
    
    public int Page { get; set; }
}

public async Task<IActionResult> SendContent([FromQuery] Content option)

changed the parameter to something else:

public async Task<IActionResult> SendContent([FromQuery] Content contentOptions)
Share:
43,853
Carl Thomas
Author by

Carl Thomas

Updated on July 12, 2022

Comments

  • Carl Thomas
    Carl Thomas almost 2 years

    I am trying to use model binding from query parameters to an object for searching.

    My search object is

    [DataContract]
    public class Criteria 
    {
      [DataMember(Name = "first_name")]
      public string FirstName { get; set; }
    }
    

    My controller has the following action

    [Route("users")]
    public class UserController : Controller 
    {
      [HttpGet("search")]
      public IActionResult Search([FromQuery] Criteria criteria)
      {
        ...
      }
    }
    

    When I call the endpoint as follows .../users/search?first_name=dave the criteria property on the controller action is null. However, I can call the endpoint not as snake case .../users/search?firstName=dave and the criteria property contains the property value. In this case Model Binding has worked but not when I use snake_case.

    How can I use snake_case with Model Binding?

  • Dmitry Pavlov
    Dmitry Pavlov over 6 years
    What if I want to use data contracts with members with the custom names for GET and POST endpoints, so in the first case it will be FromQuery, and FromBody for POST request?
  • sander
    sander about 6 years
    I can't get this to work but it is marked as an answer.
  • sander
    sander about 6 years
    I just want to add that I had an issue which other people could encounter too: I named my parameter 'model'. My object had a property which was also named 'model'. The databinding wouldn't work untill I renamed my parameter.
  • Alexandre Ribeiro
    Alexandre Ribeiro over 5 years
    Yep, it works only with [FromQuery] in controller method
  • Daniel Gimenez
    Daniel Gimenez over 5 years
    This is the correct answer for NetCore 2.1 and above, the accepted answer is an anachronism.
  • Mohsen Kamrani
    Mohsen Kamrani over 5 years
    Either this should be the accepted answer or the OP which happens to be the one who's given the accepted answer should update their answer.
  • Rebecca
    Rebecca about 5 years
    I think the problem is that this answer doesn't address the specifics of question. The OP specifically requires a different name for the property, and this doesn't support that, as stated by the person that gave this answer.
  • Ramūnas
    Ramūnas about 5 years
    FromQuery sits in Microsoft.AspNetCore.Mvc package, it is a bit sad to add this dependency to the project where you only store your POCO.
  • Twisted Whisper
    Twisted Whisper about 5 years
    I'm using .net core 2.2 and this method doesn't work for me. However, the accepted answer does.
  • peyman gilmour
    peyman gilmour about 5 years
    @TwistedWhisper I am still using it! Can be related to the binding. Are you sure you have same parameters in both side ( query string and class object ) ?
  • peyman gilmour
    peyman gilmour almost 5 years
    @TwistedWhisper It works fine for me. I am using it in .net core 2.2 and 3.0 preview 5 and 6. The secret is you have to have same spelling properties in both sides.
  • Alex Gamezo
    Alex Gamezo over 4 years
    Make sure you're using Properties, in the Request model, and not fields. That was my missed mistake
  • elembie
    elembie over 3 years
    @sander 's solution worked for me - thank you I spend well over an hour trying to figure this one out. Lesson learned to check all parameter names.
  • sander
    sander over 3 years
    @elembie yeah, this one was a real gotcha!
  • Max
    Max over 3 years
    It will also works with [JsonPropertyName("otherName")] on your properties. Because of that I´m assuming it will also work with Newtonsoft.JSON annotations (but didn´t try). So you can just specify [FromQuery] in your method and could still use the same object in a Body when needed (without additional annotations). No need to be this specific about it.
  • peyman gilmour
    peyman gilmour over 3 years
    @TwistedWhisper That's true. Same spelling!
  • peyman gilmour
    peyman gilmour over 3 years
    @AlexGamezo That's true. It is important to use properties.
  • Sudara
    Sudara over 3 years
    Yes, those should be properties with getter and setter and the class should have a parameterless constructor too
  • code5
    code5 about 3 years
    @Max - hi Max. No it doesn't work for Newtonsoft [JsonPropery(Name = "otherName")]