Search code examples
c#.net-coremodel-bindingasp.net-core-3.0.net-core-3.0

Model not binding all properties in Query Parameters .Net Core 3.0 HTTP GET


I'm trying to bind to a complex object via Query Parameters, and I only seem to be binding the first property, and everything else is initialized with defaults (0, null, false, etc. . . ).

The HTTP Request is coming in with all the applicable property names and values. The property names are an exact match. It binds the first property in the query parameters, but not the others. When the request comes in & is replaced with &amps;. From what research I've done online these should be the same in the eyes of the model binder. Here is my current setup

public class MyComplexObject
{
    public string Id { get; set; }
    public int Level { get; set; }
    public Enum MyEnum { get; set; }
}
[HttpGet]
public IActionResult MyAction( [FromQuery] MyComplexObject model)
{
    // stuff done here.  model.Id is set to the correct value, everything
    // else is set to an initialized value based on type. 

    return View("view", model)
}

This is in an MVC .Net Core 3.0 Web Project (not an API).

When I debug on the action and look at this.Request.QueryString It shows "?Id=2100&Level=6&MyEnum=MyEnumValue" So values are being passed in, I just can't get it to bind to the rest of the properties, and it correctly binds the first property in the Query string (Id).

All the sources I can find say this is how I should set up a complex object via QueryParameters, but I can't find anything decisive on if this is broken for .Net Core 3.0, everything I read is for .Net Core 2.2 and earlier, as well as for POST and WebApi's.

Is this possible in .Net 3.0? If so, what am I doing wrong? There are other ways to go about doing this, I can set up route parameters that bind correctly, but I'm going to be doing this a bunch, and I was hoping to just pass in my model and be done with it rather than url/{paramters1}/{parameter2}/...

Edit::

When I open the chrome debugger and click on the Network tag the call looks like so.

{myurl}?Id=2100&Level=6&MyEnum=MyEnumValue so it matches the Request in the debugger.

Edit Part 2:

I'm making the request via a jQuery .load({url}) in the client. I did a hack var url = url.replace('%amp;', '&'); and that solved one of my problems and it correctly bound the property.

Thank you all for the help!


Solution

  • I was making the request via a jQuery .load({url}) in the client. I did a hack

    var url = url.replace('%amp;', '&');
    

    and that solved one of my problems and it correctly bound the property.