为 ASP.NET Core 的 GET 请求序列化复杂对象

Serializing a Complex Object for a GET Request for ASP.NET Core

因此,之前我的团队对所有内容都使用 POST 请求。我最终赢得了 war 说服他们按预期使用动词。
GET 查询,
POSTs 用于创建等

我们有一个非常复杂的对象,我们需要将其作为 GET 发送:

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

这与 POST 一样简单,但不如 GET 简单。我们创建的 Action 方法类似于:

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

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

其中 CompletedAuditDto 是:

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;
}

TypeAttributeDto是:

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

并且我使用 qs 库尝试了许多不同的序列化。 但是 SelectedAttributes 集合总是显示为空。 我将日志记录降低到 debug 级别,模型联编程序似乎甚至没有尝试反序列化该对象(没有提到 SelectedAttributes 集合)

[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'.

关于如何将其序列化为模型绑定程序满意的格式的任何想法。 这是我尝试过的许多事情之一:

UserId=1&CategoryId=39&StartMillis=1609459200000&EndMillis=1635724799000&GroupByAttributeTypeId=105&SelectedAttributes%5B%5D.TypeId=100&SelectedAttributes%5B%5D.AttributeIds%5B%5D=1&SelectedAttributes%5B%5D.TypeId=105&SelectedAttributes%5B%5D.AttributeIds%5B%5D=6697

首先,您需要在您的模型中添加 getter setter,如下所示:

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; }
}

然后像下面这样发送请求:

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