【问题标题】:Dynamically add forms and have validation work动态添加表单并进行验证工作
【发布时间】:2016-07-11 17:16:23
【问题描述】:

我有一个 ViewModel 有多个字段的情况(例如):

public class myVM
{
     [Required(errorMessage="SomeMessage")]
     public string Name;

     [Required(errorMessage="SomeMessage")]
     public string Address;

     [Required(errorMessage="SomeMessage")]
     public string PhoneNumber;
}

在现实世界中它有点复杂。

用户可以选择他们在页面上要编辑的内容、姓名信息、地址信息、电话号码信息等。

这些选项中的每一个都对应于一个部分视图,该视图加载了每个部分的表单。

我遇到的问题是,如果用户继续并选择他们只想编辑名称部分,因此只呈现名称表单,他们仍然会收到地址和电话号码的验证消息...

我知道为什么会发生这种情况,只是不确定最好的解决方法是什么?

更新。

注意上面说的不清楚,这些表单部分(Partial views)全部加载到一个BIG表单中。

类似这样的:

@using (Html.BeginForm())
{

    @Html.ValidationSummary(false)

    Html.RenderPartial("Partials/_AddressForm", Model.Address);
    Html.RenderPartial("Partials/_Phonenumber", Model.PhoneNumber);

    <input type="submit" value="SAVE"/>

}

生成的表单被发送回一个执行 ModelState.IsValid 的操作 - 这当然会验证整个模型。

【问题讨论】:

  • 为每个案例创建单独的虚拟机。
  • 我是按照这些思路思考的,但是可能不清楚的是,这些都是相同形式的元素。我将更新示例。
  • 这样写可不是个好习惯。您可以read here 对 MVC 中的验证问题进行非常完整的概述。
  • 这就是我要问的问题。我要求用户选择他们要填写的表单的哪些部分,然后根据该选择进行验证。这就是我要问的 - 我怎样才能做到这一点?我知道这不是最佳实践,但这不可能吗?也许不是我上面展示的方式 - 有什么想法可以实现吗?
  • 正如我已经提到的,最好创建单独的 ViewModel。替代方案 - 摆脱属性验证并以控制器自定义方式验证您的模型

标签: c# asp.net-mvc validation


【解决方案1】:

在 Webforms 中,您将使用验证组,其中有一堆表单控件,所有这些控件都需要根据按下的不同按钮进行验证。

您可以通过实现这样的自定义验证注释来使用单个视图模型来实现这一点:

public class RequiredIfISaySo : ValidationAttribute//, IClientValidatable
{
    public RequiredIfISaySo(int RequiredReason)
    {
        _reqReason = RequiredReason;
    }

    private RequiredAttribute _reqAttribute = new RequiredAttribute();
    private int _reqReason;

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        if (_reqReason == 1)
        { 
            if (!_reqAttribute.IsValid(value))
            {
                return new ValidationResult(this.ErrorMessage, new[] { validationContext.MemberName });
            }
        }

        return ValidationResult.Success;
    }
}

然后您可以像这样注释您的模型:

 [RequiredIfISaySo(3, ErrorMessage = "NAME REQUIRED")]
    public string Name { get; set; }

    [RequiredIfISaySo(2, ErrorMessage = "PHONE REQUIRED")]
    public string Phone { get; set; }

    [RequiredIfISaySo(1, ErrorMessage ="ADDRESS REQUIRED")]
    public string Address { get; set; }

我可能会将该 int 更改为更易于阅读的内容,并对其进行更改,以便您可以传递一个数组而不是单个值(这样您就可以在验证中重叠(即验证 1 或 2 的任何内容)通过了。

对于奖励积分,您还可以通过实现(已注释掉的)IClientValidatable 接口将其与客户端验证挂钩。

【讨论】:

    猜你喜欢
    • 2011-07-13
    • 2013-09-18
    • 2021-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-07
    • 2020-06-13
    相关资源
    最近更新 更多