ASP.NET MVC绑定与远程validation

我有一个ModelA ,一个成员toBeRemoteChecked和一个模型MapToA与成员valueToMap 。 每当我创建一个ModelA实例时,我还需要一个MapToA实例,所以我有一个模型CreateModelA ,它包含一个成员modelA和一个成员valueToMap 。 提交表单时,我将modelA添加到数据库表ModelA并创建并向MapToA添加一个实例,该实例由MapToA的id和valueToMap 。 在代码方面

 public class ModelA { [Key] public int ID { get; set; } [Required, Remote("isValid", "MyController", ErrorMessage = "not valid")] public string toBeRemoteChecked { get; set; } } public class MapToA { [Key] public int Map_ID { get; set; } [Required] public int modelAID { get; set; } [Required] public int valueToMap { get; set; } } public class CreateModelA { public ModelA modelA { get; set; }; public int valueToMap { get; set; }; } 

当我编辑ModelA的实例时, ModelA中的值无关紧要(并且在大多数情况下, mapToA的多个实例具有相同的modelA id),但toBeRemoteChecked的远程validation仍然很重要。

我的问题:validation方法的绑定:

 public ActionResult isValid(string toBeRemoteChecked) { ... } 

如果我保持原样,它在编辑ModelAModelA ,但在我通过CreateModelA创建ModelA没有(我总是在toBeRemoteChecked得到null值)。 当我使用BindPrefix时

 public ActionResult isValid([Bind(Prefix = "modelA.toBeRemoteChecked")] string toBeRemoteChecked) { ... } 

它在我创建ModelA时工作,但在我编辑它ModelA没有。

当我尝试通过在@Html的htmlAttributes中添加... @Name = "toBeRemoteChecked" ... (而不是由HTML帮助程序创建的modelA.toBeRemoteChecked)来更改Create.cshtml中的“ @Html.TextBoxFor ,然后validation工作正常,但是值与表的绑定会丢失,当值保存到数据库时我得到错误(空值)。

那么,如何实现创建和编辑的不同绑定?

到目前为止,我的解决方法是创建ModelACreateModelA : IValidatableObject并在我的public IEnumerable Validate(ValidationContext validationContext)方法中检查成员toBeRemoteChecked 。 但是那个在表单顶部而不是在TextFor框的位置显示错误消息。

那么:最佳解决方案:如何在两种情况下进行远程validation的绑定?

第二好:如何在它所属的对象附近显示IValidatableObject的错误消息(并在手头获取错误消息,而不是在提交后)

不同的想法或解决方案:欢迎。

谢谢。

一个有趣的问题,与此问题类似,因此我在Codeplex报告了一个问题,但尚未解决。 该链接包括对jquery.validate.js文件的建议修改,该文件将解决此问题(它会jquery.validate.js前缀),但这意味着您需要在更新脚本时进行维护,因此不太理想。

一种选择是将CreateModelA更改为inheritance自ModelA ,只需添加int valueToMap属性,这样就不会有前缀 – 总是使用@Html.TextBoxFor(m => m.toBeRemoteChecked)而不是@Html.TextBoxFor(m => m.modelA.toBeRemoteChecked)

此外, [Remote]是仅客户端validation,这意味着您仍需要在发布时在服务器中执行validation。 所以你可以接受你没有对属性进行客户端validation,而是在属性的POST方法中添加ModelState错误并返回视图,以便它显示在关联的ValidationMessageFor()元素中

附注:您的模型具有[Key]属性的事实表明这是数据模型,而不是视图模型, [Remote]是视图特定属性。 您应该使用视图模型,尤其是在编辑数据时。 (参考MVC中的ViewModel是什么? )

我找到了一个没有inheritance(并且没有视图模型)的解决方案,只需对代码进行少量更改即可解决我的绑定问题。

有两种绑定远程validation的方法,您可以只传递必须远程检查的成员

 public ActionResult isValid(string toBeRemoteChecked) { ... } 

或者您可以传递该成员的类的实例。

 public ActionResult isValid(ModelA modelA) { ... } 

当然,在第二个变体中,您必须使用modelA.toBeRemoteChecked替换modelA.toBeRemoteChecked 。 在第二个版本中,绑定适用于两种情况 – 编辑时以及在上面的上下文中创建ModelA实例时。 为了使绑定工作,远程validation方法的参数名称与CreateModelA中的成员名称匹配是至关重要的,即在我的情况下是modelA

如果你有一个非常复杂的模型,你可以使用bind / include初始化参数modelA和你想要使用的成员,即在我的情况下我会使用

 public ActionResult isValid([Bind(Include = "toBeRemoteChecked")] ModelA modelA) { ... } 

默认情况下(没有Include),所有其他成员将保持为null或具有默认值 – 因此,只有在需要其他成员进行validation时才需要使用Include – 在我的情况下,省略Include时也会如此