自定义模型Binderinheritance自DefaultModelBinder
我正在尝试为MVC 4构建一个自定义模型绑定器,它将inheritance自DefaultModelBinder
。 我希望它拦截任何绑定级别的任何接口,并尝试从名为AssemblyQualifiedName
的隐藏字段加载所需的类型。
这是我到目前为止(简化):
public class MyWebApplication : System.Web.HttpApplication { protected void Application_Start() { ModelBinders.Binders.DefaultBinder = new InterfaceModelBinder(); } } public class InterfaceModelBinder : DefaultModelBinder { public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { if (bindingContext.ModelType.IsInterface && controllerContext.RequestContext.HttpContext.Request.Form.AllKeys.Contains("AssemblyQualifiedName")) { ModelBindingContext context = new ModelBindingContext(bindingContext); var item = Activator.CreateInstance( Type.GetType(controllerContext.RequestContext.HttpContext.Request.Form["AssemblyQualifiedName"])); Func modelAccessor = () => item; context.ModelMetadata = new ModelMetadata(new DataAnnotationsModelMetadataProvider(), bindingContext.ModelMetadata.ContainerType, modelAccessor, item.GetType(), bindingContext.ModelName); return base.BindModel(controllerContext, context); } return base.BindModel(controllerContext, bindingContext); } }
示例Create.cshtml文件(简化):
@model Models.ScheduledJob @* Begin Form *@ @Html.Hidden("AssemblyQualifiedName", Model.Job.GetType().AssemblyQualifiedName) @Html.Partial("_JobParameters") @* End Form *@
上面的部分_JobParameters.cshtml
查看Model.Job
的属性并构建编辑控件,类似于@Html.EditorFor()
,但有一些额外的标记。 ScheduledJob.Job
属性的类型为IJob
(接口)。
ScheduledJobsController.cs示例(简化):
[HttpPost] public ActionResult Create(ScheduledJob scheduledJob) { //scheduledJob.Job here is not null, but has only default values }
保存表单时,它正确解释对象类型并获取新实例,但对象的属性未设置为适当的值。
我还需要做些什么来告诉默认绑定器接管指定类型的属性绑定?
这篇文章告诉我,我的模型绑定器过于复杂。 以下代码有效:
public class InterfaceModelBinder : DefaultModelBinder { public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { if (bindingContext.ModelType.IsInterface) { Type desiredType = Type.GetType( EncryptionService.Decrypt( (string)bindingContext.ValueProvider.GetValue("AssemblyQualifiedName").ConvertTo(typeof(string)))); bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, desiredType); } return base.BindModel(controllerContext, bindingContext); } }
使用MVC 4可以轻松覆盖消息,如果这是您在自定义模型绑定器中可能需要的全部内容:
protected void Application_Start(object sender, EventArgs e) { //set mvc default messages, or language specifc ClientDataTypeModelValidatorProvider.ResourceClassKey = "ValidationMessages"; DefaultModelBinder.ResourceClassKey = "ValidationMessages"; }
然后使用以下条目创建名为ValidationMessages
资源文件:
NAME: FieldMustBeDate VALUE: The field {0} must be a date. NAME: FieldMustBeNumeric VALUE: The field {0} must be a number
。
我们这样做是因为合规性失败了。 我们的安全扫描不喜欢javascript
注入将返回并出现在validation消息中并执行。 通过使用此实现,我们将覆盖返回用户提供的值的默认消息。
- 在Html.BeginForm MVC4控制器动作中传递多个参数
- 即使将身份validation模式设置为“Windows”,ASP.Net MVC4 User.Identity.Name也会变为空
- 为特定控制器操作选择自定义输出缓存提供程
- 如何在ASP.Net MVC控制器中正确使用ServiceStack身份validation
- 在类中使用UserProfile外键在MVC 4中创建新的配置文件
- 返回模型以使用selectlistitem默认值查看错误
- ResolveBundleUrl无法解析所有文件?
- 在MVCrazor回来后,maintaning下降选定状态?
- TextBoxFor()不生成validation标记