asp.net-mvc – 自定义模型绑定,模型状态和数据注释
我有一些关于自定义模型绑定,模型状态和数据注释的问题.
1)如果我的模型上有数据注释,那么在自定义模型绑定器中进行验证是否是多余的,因为这就是我认为的数据注释点. 2)为什么我的控制器将模型状态视为有效,即使它不是,主要是我使Name属性为null或太短. 3)将自定义模型绑定器视为构造方法是否可行,因为这是他们提醒我的. 首先是我的模型. public class Projects { [Key] [Required] public Guid ProjectGuid { get; set; } [Required] public string AccountName { get; set; } [Required(ErrorMessage = "Project name required")] [StringLength(128,ErrorMessage = "Project name cannot exceed 128 characters")] [MinLength(3,ErrorMessage = "Project name must be at least 3 characters")] public string Name { get; set; } [Required] public long TotalTime { get; set; } } 然后我使用自定义模型绑定器绑定模型的某些属性.请不要介意它只是试图让它运行然后重构它是快速和肮脏的. public class ProjectModelBinder : IModelBinder { public object BindModel(ControllerContext controllerContext,ModelBindingContext bindingContext) { if (controllerContext == null) { throw new ArgumentNullException("controllerContext"); } if (bindingContext == null) { throw new ArgumentNullException("bindingContext"); } var p = new Project(); p.ProjectGuid = System.Guid.NewGuid(); p.AccountName = controllerContext.HttpContext.User.Identity.Name; p.Name = controllerContext.HttpContext.Request.Form.Get("Name"); p.TotalTime = 0; // // Is this redundant because of the data annotations?!?! // if (p.AccountName == null) bindingContext.ModelState.AddModelError("Name","Name is required"); if (p.AccountName.Length < 3) bindingContext.ModelState.AddModelError("Name","Minimum length is 3 characters"); if (p.AccountName.Length > 128) bindingContext.ModelState.AddModelError("Name","Maximum length is 128 characters"); return p; } } 现在我的控制器动作. [HttpPost] public ActionResult CreateProject([ModelBinder(typeof(ProjectModelBinder))]Project project) { // // For some reason the model state comes back as valid even when I force an error // if (!ModelState.IsValid) return Content(Boolean.FalseString); //_projectRepository.CreateProject(project); return Content(Boolean.TrueString); } 编辑 我在另一个stackoverflow问题上找到了一些代码,但我不确定在哪个点上我会将以下值注入此possible solution. 创建新对象时我想要注入的内容: var p = new Project(); p.ProjectGuid = System.Guid.NewGuid(); p.AccountName = controllerContext.HttpContext.User.Identity.Name; p.Name = controllerContext.HttpContext.Request.Form.Get("Name"); p.TotalTime = 0; 如何将上述代码纳入以下内容(可能的解决方案): public class ProjectModelBinder : DefaultModelBinder { public override object BindModel(ControllerContext controllerContext,ModelBindingContext bindingContext) { if (bindingContext.ModelType == typeof(Project)) { ModelBindingContext newBindingContext = new ModelBindingContext() { ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType( () => new Project(),// construct a Project object,typeof(Project) // using the Project metadata ),ModelState = bindingContext.ModelState,ValueProvider = bindingContext.ValueProvider }; // call the default model binder this new binding context return base.BindModel(controllerContext,newBindingContext); } else { return base.BindModel(controllerContext,bindingContext); } } } } 解决方法
如果从DefaultModelBinder继承,覆盖BindModel方法,调用base.BindModel方法然后进行手动更改(设置guid,帐户名和总时间),您会发现事情更容易.
1)完成验证是多余的.您可以编写代码来反映验证元数据,就像默认情况一样,或者只是删除数据注释验证,因为您没有在模型绑定器中使用它. 2)我不知道,似乎是正确的,您应该单步执行代码并确保自定义绑定器填充所有适用的规则. 3)这是一个肯定的工厂,但不是一个构造函数. 编辑:你不能更接近解决方案,只需在模型工厂函数中设置所需的属性 public class ProjectModelBinder : DefaultModelBinder { public override object BindModel(ControllerContext controllerContext,ModelBindingContext bindingContext) { if (bindingContext.ModelType == typeof(Project)) { ModelBindingContext newBindingContext = new ModelBindingContext() { ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType( () => new Project() // construct a Project object { ProjectGuid = System.Guid.NewGuid(),AccountName = controllerContext.HttpContext.User.Identity.Name,// don't set name,thats the default binder's job TotalTime = 0,},typeof(Project) // using the Project metadata ),ValueProvider = bindingContext.ValueProvider }; // call the default model binder this new binding context return base.BindModel(controllerContext,newBindingContext); } else { return base.BindModel(controllerContext,bindingContext); } } } 或者您可以替代地覆盖CreateModel方法: protected override object CreateModel(ControllerContext controllerContext,ModelBindingContext bindingContext,System.Type modelType) { if (modelType == typeof(Project)) { Project model = new Project() { ProjectGuid = System.Guid.NewGuid(),thats the default binder's job TotalTime = 0,}; return model; } throw new NotSupportedException("You can only use the ProjectModelBinder on parameters of type Project."); } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- asp.net-mvc – 使用jquery Ajax加载PartialView?
- ASP.NET框架是CLR还是BCL的一部分?
- asp.net – 命令超时和连接超时之间的区别
- asp.net-mvc – asp.net mvc – 视图中的命名空间
- asp.net-mvc – 在Razor View中重命名mvc模型对象
- 代码翻译:ASP.NET Server.Transfer in PHP
- asp.net-mvc – 共享WCF服务和身份验证的MVC2应用程序(和其
- asp.net-mvc – ASP.NET MVC:正确的地方为部分视图?
- asp.net-mvc-5 – MVC5身份验证过滤器
- asp.net – 在MVC中使用iTextSharp在MVC Razor中将HTML转换
- 在ASP.Net中,在哪个页面生命周期事件中,viewstat
- asp.net – 编码HTML页面标题的正确方法
- asp.net-mvc-4 – MVC4/DotNetOpenAuth中的自定义
- 深入理解Asp.Net中WebForm的生命周期
- 我需要为ASP.NET 4网站提供额外的XSS安全性吗?
- asp.net-mvc – 我应该在ASP.NET MVC中使用Anti-
- asp.net – 有没有办法隐藏架构或至少从Sql Serv
- 如何配置IIS 7以使用子目录作为默认文档?
- asp.net – 将Eval参数从ASPX文件传递给JavaScri
- asp.net – 在根站点下托管的应用程序中配置子目