方括号中带有(属性)的方法参数 [英] Method parameter with (attribute) in brackets
问题描述
我有一个来自 KendoUI 的代码示例.
public ActionResult Customers_Read([DataSourceRequest]DataSourceRequest request){返回 Json(GetCustomers().ToDataSourceResult(request));}私有静态 IEnumerable获取客户(){var Northwind = new SampleEntities();返回 Northwind.Customers.Select(customer =>新客户视图模型{CustomerID = customer.CustomerID,公司名称 = 客户.公司名称,ContactName = customer.ContactName,//...});}
这个例子工作正常.
我对 Customers_Read
方法中的 [DataSourceRequest]
感到困惑...
当我删除(属性?)[DataSourceRequest]
时,请求中的属性为空(空)...(它们未绑定)-> 结果:过滤器不起作用.
[DataSourceRequest]
是什么?它像属性上的属性吗?
代码示例 -> IndexController.cs代码示例
您看到的是模型绑定器属性.DataSourceRequest
实际上是 DataSourceRequestAttribute
并扩展了 CustomModelBinderAttribute
类.创建这样的属性相当简单:
首先我们需要一个模型:
公共类 MyModel{公共字符串 MyProp1 { 获取;放;}公共字符串 MyProp2 { 获取;放;}}
我们需要能够通过创建自定义模型绑定器来创建绑定.根据您的值发送到服务器的方式,从表单或查询字符串中获取值:
公共类 MyModelBinder : IModelBinder{公共对象 BindModel (ControllerContext controllerContext, ModelBindingContext bindingContext){MyModel 模型 = new MyModel();//model.MyProp1 = controllerContext.HttpContext.Request.Form["MyProp1"];//model.MyProp2 = controllerContext.HttpContext.Request.Form["MyProp2"];//或者model.MyProp1 = controllerContext.HttpContext.Request.QueryString["MyProp1"];model.MyProp2 = controllerContext.HttpContext.Request.QueryString["MyProp2"];退货模式;}}
我们需要做的最后一件事是创建模型绑定器属性,该属性可以在操作结果签名中设置.它的唯一目的是指定必须用于它装饰的参数的模型绑定器:
公共类 MyModelBinderAttribute : CustomModelBinderAttribute{公共覆盖 IModelBinder GetBinder(){返回新的 MyModelBinder();}}
可以通过创建一个简单的 ActionResult
并使用查询字符串中的参数调用它来测试自定义绑定(因为我上面的实现在查询字符串中查找参数):
public ActionResult DoBinding([MyModelBinder]MyModel myModel){返回新的 EmptyResult();}//视图内部<a href="/Home/DoBinding?MyProp1=value1&MyProp2=value2">点击测试</a>
正如 DavidG 所指出的,DataSourceRequestAttribute
与 DataSourceRequest
不同.由于 Attribute
命名约定,它们似乎具有相同的名称,即 DataSourceRequestAttribute
在装饰对象或属性时会丢失 Attribute
部分.
作为结论,DataSourceRequestAttribute
只是告诉框架应该将自定义模型绑定器(可能是 DataSourceRequestModelBinder
或类似的东西)用于 DataSourceRequest 请求
参数.
I have a code example from 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,
// ...
});
}
This example works fine.
I am confused about [DataSourceRequest]
in Customers_Read
method...
When I remove (the Attribute?) [DataSourceRequest]
, the properties from request are empty (null)... (they aren't bound) -> result: filters doesn't work.
What is the [DataSourceRequest]
? Is it like an attribute on properties?
Code Example -> IndexController.cs Code Example
What you are seeing is a model binder attribute. The DataSourceRequest
is actually DataSourceRequestAttribute
and extends the CustomModelBinderAttribute
class. Creating such an attribute is fairly simple:
First we need a model:
public class MyModel
{
public string MyProp1 { get; set; }
public string MyProp2 { get; set; }
}
We need to be able to create the binding, by creating a custom model binder. Depending on how your values are sent to the server, get the values either from the form or the query string:
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;
}
}
The last thing we need to do is create the model binder attribute which can be set inside the action result signature. Its sole purpose is specifying the model binder which must be used for the parameter it decorates:
public class MyModelBinderAttribute : CustomModelBinderAttribute
{
public override IModelBinder GetBinder()
{
return new MyModelBinder();
}
}
The custom binding can be tested by creating a simple ActionResult
and calling it with the parameters in the query string (since my implementation above looks for parameters in the query string):
public ActionResult DoBinding([MyModelBinder]MyModel myModel)
{
return new EmptyResult();
}
//inside the view
<a href="/Home/DoBinding?MyProp1=value1&MyProp2=value2">Click to test</a>
As DavidG noted, the DataSourceRequestAttribute
is different than DataSourceRequest
. They appear to have the same names due to the Attribute
name convention, i.e. DataSourceRequestAttribute
looses the Attribute
part when decorating an object or a property.
As a conclusion, the DataSourceRequestAttribute
just tells the framework that a custom model binder (probably DataSourceRequestModelBinder
or something similar) should be used for the DataSourceRequest request
parameter.
Please see the following links for additional information: source, source.
这篇关于方括号中带有(属性)的方法参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!