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) { ... }
如果我保持原样,它在编辑ModelA
时ModelA
,但在我通过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工作正常,但是值与表的绑定会丢失,当值保存到数据库时我得到错误(空值)。
那么,如何实现创建和编辑的不同绑定?
到目前为止,我的解决方法是创建ModelA
和CreateModelA
: 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时也会如此