【问题标题】:Serializing a Complex Object for a GET Request for ASP.NET Core为 ASP.NET Core 的 GET 请求序列化复杂对象
【发布时间】:2021-12-07 23:32:38
【问题描述】:

所以,以前我的团队对所有内容都使用 POST 请求。我终于在说服他们按预期使用动词方面赢得了胜利。
用于查询的 GET,
用于创建等的 POST。

我们有一个非常复杂的对象,我们需要将其作为 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] 尝试绑定类型为“WebApp.Payloads.Request.CompletedAuditDto”的参数“有效负载”... [14:35:44 DBG] 尝试使用请求数据中的名称“”绑定“WebApp.Payloads.Request.CompletedAuditDto”类型的参数“有效负载”... [14:35:44 DBG] 尝试使用请求数据中的名称“UserId”绑定“System.Int32”类型的属性“WebApp.Payloads.Request.CompletedAuditDto.UserId”... [14:35:44 DBG] 尝试绑定“System.Int32”类型的属性“WebApp.Payloads.Request.CompletedAuditDto.UserId”。 [14:35:44 DBG] 尝试使用请求数据中的名称“CategoryId”绑定“System.String”类型的属性“WebApp.Payloads.Request.CompletedAuditDto.CategoryId”... [14:35:44 DBG] 尝试绑定“System.String”类型的属性“WebApp.Payloads.Request.CompletedAuditDto.CategoryId”。 [14:35:44 DBG] 尝试在请求数据中使用名称“StartMillis”绑定“System.Int64”类型的属性“WebApp.Payloads.Request.CompletedAuditDto.StartMillis”... [14:35:44 DBG] 尝试绑定“System.Int64”类型的属性“WebApp.Payloads.Request.CompletedAuditDto.StartMillis”。 [14:35:44 DBG] 尝试在请求数据中使用名称“EndMillis”绑定“System.Int64”类型的属性“WebApp.Payloads.Request.CompletedAuditDto.EndMillis”... [14:35:44 DBG] 尝试绑定“System.Int64”类型的属性“WebApp.Payloads.Request.CompletedAuditDto.EndMillis”。 [14:35:44 DBG] 尝试使用请求数据中的名称“GroupByAttributeTypeId”绑定类型为“System.String”的属性“WebApp.Payloads.Request.CompletedAuditDto.GroupByAttributeTypeId”... [14:35:44 DBG] 尝试绑定“System.String”类型的属性“WebApp.Payloads.Request.CompletedAuditDto.GroupByAttributeTypeId”。 [14:35:44 DBG] 尝试绑定“WebApp.Payloads.Request.CompletedAuditDto”类型的参数“payload”。 [14:35:44 DBG] 尝试绑定“WebApp.Payloads.Request.CompletedAuditDto”类型的参数“payload”。

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

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.B%55D. %5D=6697

【问题讨论】:

    标签: asp.net-core model-binding


    【解决方案1】:

    首先,您需要在模型中添加 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

    【讨论】:

    • 我不敢相信我没有看到。我记得昨天我在想,好像有什么不对劲,但我不能指望它。我从来不会这样编码,所以我不认为公共变量被随机使用而不是属性。但它在我没有看到它。非常感谢。下一个挑战是找到一个序列化器来序列化这样的 Javascript 对象。再次感谢。
    • 作为附录,您可以使用 qs 将其序列化,如下所示:qs.stringify(val, { allowDots: true }) 会生成类似 UserId=1&amp;CategoryId=39&amp;StartMillis=1609459200000&amp;EndMillis=1635724799000&amp;GroupByAttributeTypeId=105&amp;SelectedAttributes%5B0%5D.TypeId=100&amp;SelectedAttributes%5B0%5D.AttrIds%5B0%5D=1&amp;SelectedAttributes%5B1%5D.TypeId=105&amp;SelectedAttributes%5B1%5D.AttrIds%5B0%5D=6697 的字符串。模型绑定器对此很满意。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多