All*_*ice 4 c# asp.net-mvc model-binding modelbinders
我有一个POCO,我用它作为MVC3中一个动作的参数.像这样的东西:
public class SearchData
{
public string Property1 { get; set; }
public string Property2 { get; set; }
public string Property3 { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
public ActionResult Index(SearchData query)
{
// I'd like to be able to do this
if (query == null)
{
// do something
}
}
Run Code Online (Sandbox Code Playgroud)
目前,query作为SearchData所有属性的实例传递null.我更喜欢我得到一个null,query所以我可以在上面的代码中进行空检查.
我总是可以查看ModelBinder.Any()或只是ModelBinder查看各种键,看看它是否有任何属性query,但我不想使用反射来循环遍历属性query.此外,我只能使用ModelBinder.Any()检查查询是否是我唯一的参数.只要我添加其他参数,该功能就会中断.
使用MVC3中的当前模型绑定功能,是否可以获得将POCO参数返回null的行为?
您需要实现自定义模型绑定器才能执行此操作.你可以扩展DefaultModelBinder.
public override object BindModel(
ControllerContext controllerContext,
ModelBindingContext bindingContext)
{
object model = base.BindModel(controllerContext, bindingCOntext);
if (/* test for empty properties, or some other state */)
{
return null;
}
return model;
}
Run Code Online (Sandbox Code Playgroud)
这是绑定器的实际实现,如果所有属性都为null,则将为模型返回null.
/// <summary>
/// Model binder that will return null if all of the properties on a bound model come back as null
/// It inherits from DefaultModelBinder because it uses the default model binding functionality.
/// This implementation also needs to specifically have IModelBinder on it too, otherwise it wont get picked up as a Binder
/// </summary>
public class SearchDataModelBinder : DefaultModelBinder, IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
// use the default model binding functionality to build a model, we'll look at each property below
object model = base.BindModel(controllerContext, bindingContext);
// loop through every property for the model in the metadata
foreach (ModelMetadata property in bindingContext.PropertyMetadata.Values)
{
// get the value of this property on the model
var value = bindingContext.ModelType.GetProperty(property.PropertyName).GetValue(model, null);
// if any property is not null, then we will want the model that the default model binder created
if (value != null)
return model;
}
// if we're here then there were either no properties or the properties were all null
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
ModelBinders.Binders.Add(typeof(SearchData), new SearchDataModelBinder());
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
MvcHandler.DisableMvcResponseHeader = true;
}
Run Code Online (Sandbox Code Playgroud)