方括号中带有(属性)的方法参数

Posted

技术标签:

【中文标题】方括号中带有(属性)的方法参数【英文标题】:Method parameter with (attribute) in brackets 【发布时间】:2014-11-26 00:31:14 【问题描述】:

我有一个来自 KendoUI 的代码示例。

public ActionResult Customers_Read([DataSourceRequest]DataSourceRequest request)

    return Json(GetCustomers().ToDataSourceResult(request));


private static IEnumerable<CustomerViewModel> GetCustomers()

    var northwind = new SampleEntities();
    return northwind.Customers.Select(customer => 
        new CustomerViewModel
        
            CustomerID  = customer.CustomerID,
            CompanyName = customer.CompanyName,
            ContactName = customer.ContactName,
            // ...
        );

这个例子运行良好。

我对@9​​87654324@ 方法中的[DataSourceRequest] 感到困惑...

当我删除(属性?)[DataSourceRequest] 时,请求中的属性为空(null)...(它们未绑定)-> 结果:过滤器不起作用。

[DataSourceRequest] 是什么?它像属性上的属性吗?

Code Example -> IndexController.cs 代码示例

【问题讨论】:

这里我假设DataSourceRequestAttributeDataSourceRequest 不一样。 请看我编辑的答案。 【参考方案1】:

您看到的是模型绑定器属性。 DataSourceRequest 实际上是 DataSourceRequestAttribute 并扩展了 CustomModelBinderAttribute 类。创建这样一个属性相当简单:

首先我们需要一个模型:

public class MyModel

    public string MyProp1  get; set; 

    public string MyProp2  get; set; 

我们需要能够通过创建自定义模型绑定器来创建绑定。根据您的值发送到服务器的方式,从表单或查询字符串中获取值:

public class MyModelBinder : IModelBinder

     public object BindModel (ControllerContext controllerContext, ModelBindingContext bindingContext)
     
         MyModel model = new MyModel();

         //model.MyProp1 = controllerContext.HttpContext.Request.Form["MyProp1"];
         //model.MyProp2 = controllerContext.HttpContext.Request.Form["MyProp2"];
         //or
         model.MyProp1 = controllerContext.HttpContext.Request.QueryString["MyProp1"];
         model.MyProp2 = controllerContext.HttpContext.Request.QueryString["MyProp2"];

         return model;
     

我们需要做的最后一件事是创建模型绑定器属性,该属性可以在动作结果签名中设置。它的唯一目的是指定必须用于它装饰的参数的模型绑定器:

public class MyModelBinderAttribute : CustomModelBinderAttribute

     public override IModelBinder GetBinder()
     
          return new MyModelBinder();
     

可以通过创建一个简单的ActionResult 并使用查询字符串中的参数调用它来测试自定义绑定(因为我上面的实现在查询字符串中查找参数):

public ActionResult DoBinding([MyModelBinder]MyModel myModel)

    return new EmptyResult();


//inside the view
<a href="/Home/DoBinding?MyProp1=value1&MyProp2=value2">Click to test</a>

正如 DavidG 所说,DataSourceRequestAttributeDataSourceRequest 不同。由于Attribute 命名约定,它们似乎具有相同的名称,即DataSourceRequestAttribute 在装饰对象或属性时丢失了Attribute 部分。

作为结论,DataSourceRequestAttribute 只是告诉框架应该为DataSourceRequest request 参数使用自定义模型绑定器(可能是DataSourceRequestModelBinder 或类似的东西)。

有关更多信息,请参阅以下链接:source、source。

【讨论】:

啊,现在我明白了。谢谢你非常详细的回答! @EdiG。它也困扰了我一段时间。我做了一些挖掘(在线和使用反编译器)并被证明是一个漂亮的技巧。测试它并使用它。 谢谢。你能告诉我为什么使用没有属性 [decimal] 或 [fooDto(attribute)] 的默认(隐含?)绑定器可以很好地绑定其他操作参数吗? @MichaelBrennt 您通常不需要用于基本类型(字符串、日期、小数)的自定义模型绑定器;标准模型活页夹会为您解决这个问题。它甚至可以绑定复杂的对象(类)。但是,有一些限制:您基本上必须具有相同的属性(即名称)和类型。这意味着发送到您的(服务器)操作的(客户端)数据必须匹配。现在,如果您遇到数据不匹配的情况(不同的名称和/或结构),或者只是想更好地控制模型的绑定方式,那么编写自己的模型绑定器是有意义的。 @MichaelBrennt 作为一个简短的例子,因为你很熟悉剑道,所以考虑Kendo.Mvc.UI.DataSourceRequest 类,它有一个IList&lt;SortDescriptor&gt; Sorts 属性。 SortDescriptor 类内部有一些代码,但基本上它有两个属性:string MemberListSortDirection SortDirection,其中ListSortDirection enum。看看结构如何变得相对复杂?好吧,如果您在对网格进行排序时查看发送的数据,您会看到请求有一个 sort 属性,它是 field-direction。简单而不同。

以上是关于方括号中带有(属性)的方法参数的主要内容,如果未能解决你的问题,请参考以下文章

http、https请求URL中带有&等特殊字符的解决方法

对于js定时器中带有参数的回调函数没有延迟效果的解决方法

对于js定时器中带有参数的回调函数没有延迟效果的解决方法

Delphi的类和对象之数组属性和属性的索引

ASP.NET Web API 中带有可选参数的属性路由

javascript XMLHttpRequest 对象的open() 方法参数说明