ASP.NET MVC绑定与远程验证

out*_*ind 6 c# asp.net validation asp.net-mvc asp.net-mvc-4

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

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; };
}
Run Code Online (Sandbox Code Playgroud)

当我编辑一个实例时ModelA,值MapToA无关紧要(在大多数情况下,有多个mapToA具有相同modelAid的实例),但远程验证toBeRemoteChecked仍然很重要.

我的问题:验证方法的绑定:

public ActionResult isValid(string toBeRemoteChecked) { ... }
Run Code Online (Sandbox Code Playgroud)

如果我原样保留它,它在编辑a时工作ModelA,但不是在我创建一个ModelAvia时CreateModelA(我总是得到null值toBeRemoteChecked).当我使用BindPrefix时

public ActionResult isValid([Bind(Prefix = "modelA.toBeRemoteChecked")] string toBeRemoteChecked) { ... }
Run Code Online (Sandbox Code Playgroud)

它在我创建时正在工作ModelA,但在我编辑时却没有.

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

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

到目前为止,我的解决方法是使ModelACreateModelA : IValidatableObject和检查会员toBeRemoteChecked在我的public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)方法.但是那个在表单顶部而不是在TextFor框的位置显示错误消息.

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

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

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

谢谢.

out*_*ind 2

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

远程验证绑定有两种方式,您可以只传递需要远程检查的成员

public ActionResult isValid(string toBeRemoteChecked) { ... }
Run Code Online (Sandbox Code Playgroud)

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

public ActionResult isValid(ModelA modelA) { ... }
Run Code Online (Sandbox Code Playgroud)

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

如果您有一个非常复杂的模型,您可以modelA使用绑定/包含来使用您想要使用的成员初始化参数,即在我的情况下我会使用

public ActionResult isValid([Bind(Include = "toBeRemoteChecked")] ModelA modelA) { ... }
Run Code Online (Sandbox Code Playgroud)

默认情况下(不包含),所有其他成员将保持为空或具有默认值 - 因此,仅当您还需要其他成员进行验证时才需要使用 Include - 在我的情况下,在省略 Include 时我会拥有相同的值)