从绑定中排除某些属性的最佳方法
Best way to exclude some properties from binding
我的一个 classes 有一些属性,我希望模型活页夹始终忽略它们。
目前我在操作方法中使用 [Bind(Exclude ="")]
,如下所示:
public ActionResult Edit([Bind(Exclude = "prop1, prop2, prop3")] BusinessModel model)
这个class已经用在了几个动作方法中。我必须手动排除它们,还是有更好的方法?
我应该特别注意 class,它们是导航属性。
使用集中式代码解决此问题的一种方法是覆盖 DefaultModelBinder
的 BindModel
并排除您不想绑定的属性。
public class CustomDataBinder : DefaultModelBinder
{
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
if (bindingContext.ModelType == typeof(BusinessModel))
{
HttpRequestBase request = controllerContext.HttpContext.Request;
string name = request.Form.Get("Name");
return new BusinessModel
{
Name = name
};
}
else
{
return base.BindModel(controllerContext, bindingContext);
}
}
}
然后在Application_Start()
中的Global.asax
注册。
ModelBinders.Binders.Add(typeof(BusinessModel), new CustomDataBinder());
在上述情况下,我使用了 BusinessModel
,如下所述 -
public class BusinessModel
{
public string prop1 { get; set; }
public string Name { get; set; }
}
为了测试,我创建了一个简单的视图 -
@model WebApplication1.Controllers.BusinessModel
@using (Html.BeginForm("PostData", "Home"))
{
@Html.EditorFor(model => model.prop1, new { htmlAttributes = new { @class = "form-control" } })
@Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } })
<input type="submit" value="Create" class="btn btn-default" />
}
视图呈现时,我在两个编辑器中都输入了一些数据 -
当我点击创建按钮时,Prop1
编辑器中输入的值未绑定 -
很棒,但我想添加一个小细节。
return base.BindModel
使用新的 BindingContext 可能更好,它排除了要忽略的属性而不是 returning 一个 BusinessModel
对象直的。
这让 DefaultModelBinder 的 ModelState 验证机制开始运行。
public class CustomDataBinder : DefaultModelBinder
{
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
if (bindingContext.ModelType == typeof(BusinessModel))
{
BindAttribute bindAttribute = new BindAttribute
{
Exclude = "prop1, prop2, prop3"
};
// create new property filter where only properties which are not exluded in the above bindAttribute are bound
Predicate<string> newPropertyFilter = propertyName => bindAttribute.IsPropertyAllowed(propertyName) && bindingContext.PropertyFilter(propertyName);
ModelBindingContext newBindingContext = new ModelBindingContext()
{
//bind default ModelMetaData
ModelMetadata = bindingContext.ModelMetadata,
//set to new property filter which exludes certain properties
PropertyFilter = newPropertyFilter,
//bind default ModelState
ModelState = bindingContext.ModelState,
//bind default ValueProvider
ValueProvider = bindingContext.ValueProvider
};
return base.BindModel(controllerContext, newBindingContext);
}
else
{
return base.BindModel(controllerContext, bindingContext);
}
}
}
我的一个 classes 有一些属性,我希望模型活页夹始终忽略它们。
目前我在操作方法中使用 [Bind(Exclude ="")]
,如下所示:
public ActionResult Edit([Bind(Exclude = "prop1, prop2, prop3")] BusinessModel model)
这个class已经用在了几个动作方法中。我必须手动排除它们,还是有更好的方法?
我应该特别注意 class,它们是导航属性。
使用集中式代码解决此问题的一种方法是覆盖 DefaultModelBinder
的 BindModel
并排除您不想绑定的属性。
public class CustomDataBinder : DefaultModelBinder
{
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
if (bindingContext.ModelType == typeof(BusinessModel))
{
HttpRequestBase request = controllerContext.HttpContext.Request;
string name = request.Form.Get("Name");
return new BusinessModel
{
Name = name
};
}
else
{
return base.BindModel(controllerContext, bindingContext);
}
}
}
然后在Application_Start()
中的Global.asax
注册。
ModelBinders.Binders.Add(typeof(BusinessModel), new CustomDataBinder());
在上述情况下,我使用了 BusinessModel
,如下所述 -
public class BusinessModel
{
public string prop1 { get; set; }
public string Name { get; set; }
}
为了测试,我创建了一个简单的视图 -
@model WebApplication1.Controllers.BusinessModel
@using (Html.BeginForm("PostData", "Home"))
{
@Html.EditorFor(model => model.prop1, new { htmlAttributes = new { @class = "form-control" } })
@Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } })
<input type="submit" value="Create" class="btn btn-default" />
}
视图呈现时,我在两个编辑器中都输入了一些数据 -
当我点击创建按钮时,Prop1
编辑器中输入的值未绑定 -
return base.BindModel
使用新的 BindingContext 可能更好,它排除了要忽略的属性而不是 returning 一个 BusinessModel
对象直的。
这让 DefaultModelBinder 的 ModelState 验证机制开始运行。
public class CustomDataBinder : DefaultModelBinder
{
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
if (bindingContext.ModelType == typeof(BusinessModel))
{
BindAttribute bindAttribute = new BindAttribute
{
Exclude = "prop1, prop2, prop3"
};
// create new property filter where only properties which are not exluded in the above bindAttribute are bound
Predicate<string> newPropertyFilter = propertyName => bindAttribute.IsPropertyAllowed(propertyName) && bindingContext.PropertyFilter(propertyName);
ModelBindingContext newBindingContext = new ModelBindingContext()
{
//bind default ModelMetaData
ModelMetadata = bindingContext.ModelMetadata,
//set to new property filter which exludes certain properties
PropertyFilter = newPropertyFilter,
//bind default ModelState
ModelState = bindingContext.ModelState,
//bind default ValueProvider
ValueProvider = bindingContext.ValueProvider
};
return base.BindModel(controllerContext, newBindingContext);
}
else
{
return base.BindModel(controllerContext, bindingContext);
}
}
}