如何通过 FromQuery 参数将“System.Object”类型传递给控制器

Posted

技术标签:

【中文标题】如何通过 FromQuery 参数将“System.Object”类型传递给控制器【英文标题】:How to pass "System.Object" type to the Controller through a FromQuery parameter 【发布时间】:2020-08-12 07:53:13 【问题描述】:

我的控制器中有这个方法需要接收过滤表达式列表,因此我可以过滤 DynamoDB 表,但要过滤的值可以是字符串、数字、布尔值等... 所以我使用了“System.Object”类型的属性。但似乎控制器无法将 FromQuery 参数绑定到类型“System.Object”对象。

        [HttpGet]
        public IActionResult Get(
            [FromRoute]string name,
            [FromQuery]FilterExpression[] filters
            )
        
            return Ok(m_attributeService.GetByAttributeName(name, filters));
        

FilterExpression 类

    public class FilterExpression
    
        public FilterExpression()
        public FilterExpression(
            string field, 
            string comparisonOperator, 
            dynamic values
            )
        
            Field = field;
            ComparisonOperator = comparisonOperator;
            Values = values;
        

        public string Field  get;set; 
        public string ComparisonOperator  get;set; 
        public object Values  get;set; 
    

但每次我做任何请求时,Values 属性总是 null。 我想知道在我的方法中接收不同数据类型的解决方法。

【问题讨论】:

这是因为在查询中一切都是字符串,直到它被框架根据您指定的类型强制转换。框架如何自动区分?values=1&values=true&values=foo字符串中的类型?仅仅因为它说 1 或 true 并不意味着您不希望将它们作为字符串。您需要在某处指定自定义逻辑,说明它是否是数字,转换它,如果它是一个布尔转换它等等。无论是通过比较字符串还是使用 int.TryParse/bool.TryParse 都取决于您。 如果只需要一个端点,我会接受 Values 作为字符串列表/数组并使用自定义函数强制它。如果适用于许多人,一些自定义中间件可能会更好。 【参考方案1】:

你可以绑定任何你喜欢的东西。但是,modelbinder 必须检查类型以确定它可以绑定到哪些属性,然后相应地绑定来自请求的数据。 Object 没有属性,因此模型绑定器不会绑定任何内容。我想你正在尝试多态绑定,但这不是模型绑定的工作方式。尽管动作在技术上是方法,但它们的功能不像常规方法那样,因为它们是动态调用的。当您作为开发人员通过传递给方法来向上转换某个对象时,您仍然拥有完整的对象,因此以后总是可以将其向下转换回它的类型。在请求管道中,模型绑定器只有一个集合字符串键值对,它试图将其解释为某种类型。它必须知道从动作参数创建什么类型,所以如果你使用基类型,你得到的只是基类型。所有无关的数据都将被丢弃。

【讨论】:

【参考方案2】:

我认为自定义数据绑定器可以帮助您。在MSDN documentation中查看更多信息

【讨论】:

以上是关于如何通过 FromQuery 参数将“System.Object”类型传递给控制器的主要内容,如果未能解决你的问题,请参考以下文章

将 [FromQuery] 与复杂对象一起使用

.Net Core009 API参数和复合搜索

.Net Core009 API参数和复合搜索

.Net Core009 API参数和复合搜索

.Net Core009 API参数和复合搜索

如何通过 System.Diagnostics.Process() 将参数传递给已经打开的终端