Home > OS >  Serializing a Complex Object for a GET Request for ASP.NET Core
Serializing a Complex Object for a GET Request for ASP.NET Core

Time:10-23

So, previously my team used POST requests for everything. I finally won the war in convincing them the use the verbs as intended.
GETs for queries,
POSTs for creates etc.

We have a pretty complex object which we need to send as a GET:

{
    "UserId": "1",
    "CategoryId": "39",
    "StartMillis": 1609459200000,
    "EndMillis": 1635724799000,
    "GroupByAttributeTypeId": "105",
    "SelectedAttributes": [{
            "TypeId": "100",
            "AttributeIds": [1]
        }, {
            "TypeId": "105",
            "AttributeIds": [6697]
        }
    ]
}

This is easy as a POST, but not so much as a GET. The Action method that we created looks something like:

[HttpGet]
[Route(AspNet.Mvc.ActionTemplate)]

public IActionResult GetCompletedAudits([FromQuery]CompletedAuditDto payload)
{
   return OkResponse(_auditService.GetCompletedAudit(payload));
}

where CompletedAuditDto is:

public class CompletedAuditDto
{
    public int UserId { get; set; }
    public string CategoryId { get; set; }
    public long StartMillis { get; set; }
    public long EndMillis { get; set; }
    public string GroupByAttributeTypeId { get; set; }

    public IEnumerable<TypeAttributeDto> SelectedAttributes;
}

and TypeAttributeDto is:

public class TypeAttributeDto
{
    public int TypeId;
    public IEnumerable<int> AttrIds;
}

And I've tried many different serializations using the qs library. But the SelectedAttributes collection always comes up as null. I turned my logging down to the debug level and the model binder doesn't even seem to attempt to deserialize that object (no mention of the SelectedAttributes collection)

[14:35:44 DBG] Attempting to bind parameter 'payload' of type 'WebApp.Payloads.Request.CompletedAuditDto' ... [14:35:44 DBG] Attempting to bind parameter 'payload' of type 'WebApp.Payloads.Request.CompletedAuditDto' using the name '' in request data ... [14:35:44 DBG] Attempting to bind property 'WebApp.Payloads.Request.CompletedAuditDto.UserId' of type 'System.Int32' using the name 'UserId' in request data ... [14:35:44 DBG] Done attempting to bind property 'WebApp.Payloads.Request.CompletedAuditDto.UserId' of type 'System.Int32'. [14:35:44 DBG] Attempting to bind property 'WebApp.Payloads.Request.CompletedAuditDto.CategoryId' of type 'System.String' using the name 'CategoryId' in request data ... [14:35:44 DBG] Done attempting to bind property 'WebApp.Payloads.Request.CompletedAuditDto.CategoryId' of type 'System.String'. [14:35:44 DBG] Attempting to bind property 'WebApp.Payloads.Request.CompletedAuditDto.StartMillis' of type 'System.Int64' using the name 'StartMillis' in request data ... [14:35:44 DBG] Done attempting to bind property 'WebApp.Payloads.Request.CompletedAuditDto.StartMillis' of type 'System.Int64'. [14:35:44 DBG] Attempting to bind property 'WebApp.Payloads.Request.CompletedAuditDto.EndMillis' of type 'System.Int64' using the name 'EndMillis' in request data ... [14:35:44 DBG] Done attempting to bind property 'WebApp.Payloads.Request.CompletedAuditDto.EndMillis' of type 'System.Int64'. [14:35:44 DBG] Attempting to bind property 'WebApp.Payloads.Request.CompletedAuditDto.GroupByAttributeTypeId' of type 'System.String' using the name 'GroupByAttributeTypeId' in request data ... [14:35:44 DBG] Done attempting to bind property 'WebApp.Payloads.Request.CompletedAuditDto.GroupByAttributeTypeId' of type 'System.String'. [14:35:44 DBG] Done attempting to bind parameter 'payload' of type 'WebApp.Payloads.Request.CompletedAuditDto'. [14:35:44 DBG] Done attempting to bind parameter 'payload' of type 'WebApp.Payloads.Request.CompletedAuditDto'.

Any ideas how I can get this serialized into a format which the model-binder would be happy with. This is one of the many things I have attempted:

UserId=1&CategoryId=39&StartMillis=1609459200000&EndMillis=1635724799000&GroupByAttributeTypeId=105&SelectedAttributes[].TypeId=100&SelectedAttributes[].AttributeIds[]=1&SelectedAttributes[].TypeId=105&SelectedAttributes[].AttributeIds[]=6697

CodePudding user response:

Firstly, you need add getter setter in your model like below:

public class CompletedAuditDto
{
    public int UserId { get; set; }
    public string CategoryId { get; set; }
    public long StartMillis { get; set; }
    public long EndMillis { get; set; }
    public string GroupByAttributeTypeId { get; set; }

    public IEnumerable<TypeAttributeDto> SelectedAttributes { get; set; }
}
public class TypeAttributeDto
{
    public int TypeId { get; set; }
    public IEnumerable<int> AttrIds { get; set; }
}

Then send request like below:

UserId=1&CategoryId=39&StartMillis=1609459200000&EndMillis=1635724799000&GroupByAttributeTypeId=105&SelectedAttributes[0].TypeId=100&SelectedAttributes[0].AttrIds=1&SelectedAttributes[1].TypeId=105&SelectedAttributes[1].AttrIds=6697

  • Related