我的模型ModelA
包含成员toBeRemoteChecked
,模型MapToA
包含成员valueToMap
。每当我创建ModelA
的实例时,我还需要MapToA
的实例,因此我有一个模型CreateModelA
,其中包含成员modelA
和成员{{1} }。提交表单后,我将valueToMap
添加到数据库表modelA
并创建并添加一个实例ModelA
,其中包含一个MapToA
和{{ 1}}。在代码方面
modelA
当我编辑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
的{{1}}个实例不止一个相同的MapToA
ID),但mapToA
的远程验证仍然很重要。
我的问题:验证方法的绑定:
modelA
如果我原样保留,则在编辑toBeRemoteChecked
时有效,但在我通过public ActionResult isValid(string toBeRemoteChecked) { ... }
创建ModelA
时却无效(我总是得到空值)在ModelA
)。当我使用BindPrefix
CreateModelA
当我创建toBeRemoteChecked
时它正在工作,但在我编辑它时却没有。
当我尝试更改"名称"在Create.cshtml中,通过在public ActionResult isValid([Bind(Prefix = "modelA.toBeRemoteChecked")] string toBeRemoteChecked) { ... }
的htmlAttributes中添加ModelA
(而不是由HTML帮助程序创建的... @Name = "toBeRemoteChecked" ...
,然后验证正在运行,但是值与表的绑定失败,当值保存到数据库时,我得到错误(空值)。
那么,我如何实现创建和编辑的不同绑定?
到目前为止,我的解决方法是制作modelA.toBeRemoteChecked
和@Html.TextBoxFor
ModelA
并检查CreateModelA
方法中的成员: IValidatableObject
。但是那个在表单顶部而不是在TextFor框的位置显示错误消息。
所以:最佳解决方案:如何在两种情况下进行远程验证的绑定?
第二好:如何在它所属的对象附近显示toBeRemoteChecked
的错误消息(并立即获取错误消息,而不是在提交后)
不同的想法或解决方案:欢迎。
感谢。
答案 0 :(得分:3)
一个有趣的问题,与this question类似,因此我在Codeplex报告了一个问题,但尚未解决。该链接包括对jquery.validate.js
文件的建议修改,它将解决此问题(它会删除前缀),但这意味着您需要在更新脚本时进行维护,因此不太理想。
一种选择是将CreateModelA
更改为继承自ModelA
,只需添加int valueToMap
属性,以便您永远不会有前缀 - 您始终使用@Html.TextBoxFor(m => m.toBeRemoteChecked)
代替@Html.TextBoxFor(m => m.modelA.toBeRemoteChecked)
此外,[Remote]
仅是客户端验证,这意味着您仍需要在发布时在服务器中执行验证。所以你可以接受你没有对该属性进行客户端验证,而是在属性的POST方法中添加ModelState
错误并返回视图,以便它显示在关联的ValidationMessageFor()
元素
附注:您的模型具有[Key]
属性的事实表明这是一个数据模型,而不是视图模型,[Remote]
是一个视图特定属性。您应该使用视图模型,尤其是在编辑数据时。 (参考What is ViewModel in MVC?)
答案 1 :(得分:2)
我找到了一个没有继承(并且没有视图模型)的解决方案,只需对代码进行少量更改即可解决我的绑定问题。
远程验证有两种绑定方式,您可以只传递必须远程检查的成员
public ActionResult isValid(string toBeRemoteChecked) { ... }
或者您可以传递该成员的类的实例。
public ActionResult isValid(ModelA modelA) { ... }
当然,在第二个版本中,您必须将toBeRemoteChecked
替换为modelA.toBeRemoteChecked
。在第二个版本中,绑定在两种情况下都有效 - 在编辑时以及在上面的上下文中创建ModelA
的实例时。为了使绑定工作,远程验证方法的参数名称与CreateModelA
中的成员名称匹配至关重要,在我的情况下,即modelA
。
如果你有一个非常复杂的模型,你可以使用bind / include初始化你想要使用的成员参数modelA
,即在我的情况下我会使用
public ActionResult isValid([Bind(Include = "toBeRemoteChecked")] ModelA modelA) { ... }
默认情况下(没有Include),所有其他成员将保持为null或具有默认值 - 因此,只有在需要其他成员进行验证时才需要使用Include - 在我的情况下,省略时我也会这样做包括)