【问题标题】:Blazor: validating multiple forms with the same modelBlazor:验证具有相同模型的多个表单
【发布时间】:2021-06-02 18:25:10
【问题描述】:

我的 Blazor 应用程序在不同的组件中有两种表单。两种形式都使用相同的视图模型。尽管模型相同,但组件中显示的字段不同。例如。第一个组件的表单没有 UnitPrice 字段,但第二个有。我使用一个简单的验证:

    [Required(ErrorMessage = "Unit Price is required.")]
    [Range(0.01, double.MaxValue, ErrorMessage = "Unit Price must be greater than 0")]
    public double UnitPrice { get; set; }

很遗憾,在显示并提交第一个表单时,对缺少的字段进行了验证,并且验证失败。有什么方法可以在不拆分模型或使用自定义验证的情况下做到这一点?

【问题讨论】:

  • 老实说,这似乎是一种设计气味。可能有两个视图模型具有一个带有公共字段的接口,如果它确实是具有完全相同上下文的字段
  • @BenSampica 你能澄清你的建议吗?
  • 封装变化的内容。表单有公共字段,可以通过接口来表达。但是,每次使用该表单的上下文都不同,这在您的情况下是正确的,因为您有不同的字段。随着时间的推移和这种形式的不断发展,当您尝试在一个类中协调两个不同的用例时,事情会变得越来越难看。
  • @Ben Sampica 我明白了。你想把你的建议作为一个简单的例子,并让它成为我标记的答案吗?

标签: validation blazor-server-side


【解决方案1】:

根据要求提供示例:

public interface IForm
{
    int FormStatus { get; set; }
    // Your other fields that are always shared on this form...
}

public class Form1 : IForm
{
    public int FormStatus { get; set; }

    [Required(ErrorMessage = "Unit Price is required.")]
    [Range(0.01, double.MaxValue, ErrorMessage = "Unit Price must be greater than 0")]
    public decimal UnitPrice { get; set; }
}

public class Form2 : IForm
{
    public int FormStatus { get; set; }
    
    [Required]
    public string Name { get; set; } 
    // I made this up but it demonstrates the idea of encapsulating what differs.
}

您共享的 Blazor 组件将类似于。

// SharedFormFields.razor

<input type="text" @bind-Value="_form.FormStatus">

@code {
    [Parameter] private IForm Form { get; set; }
}

然后是你的消费组件/页面

@page "/Form1"

<EditContext Model=_form1>
   <SharedFormFields Form=_form1>
   <input type="number" @bind-Value="_form1.UnitPrice">
</EditContext

@code {
    private Form1 _form1 = new()
}

【讨论】:

  • 非常感谢。我不会有任何共享组件,因为表单 1 的所有字段都是可编辑的,而表单 2 的所有字段都是只读的,除了 2 个特定于表单的字段。此外,就我而言,几乎所有字段都是共享的,除了上面提到的两个。你的方法应该是一样的,对吧?另外,从表格 1 派生表格 2 不是更好吗,因为表格 1 的字段是表格 2 的字段的子集?
  • 我认为你走在正确的道路上。但是,我个人不会走继承路线,而是坚持实现接口,因为 Form2 作为 Form1 的子类可能会在两者之间引入意外陷阱,因为它们仍然是单独的用例。从表面上看,它们通过属性共享共同点,但一个用例涉及提交数据并使用属性对其进行验证,而另一个用例只是只读显示数据,没有验证。
【解决方案2】:

我通过从 IValidatableObject 派生我的视图模型并实现它来使用条件验证:

public class MyViewModel : IValidatableObject
{
...
    public double UnitPrice { get; set; }

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        var result = new List<ValidationResult>();

        if (StatusId >= (int)Models.Status.ReadyForReview) // my condition
        {
            if (UnitPrice == 0)
            {
                result.Add(new ValidationResult("Unit Price is required."));
            }
            else if (UnitPrice < 0)
            {
                result.Add(new ValidationResult("Unit Price must be greater than 0."));
            }
        }

        return result;
    }
}

【讨论】:

    猜你喜欢
    • 2016-06-18
    • 2021-04-28
    • 2016-03-11
    • 1970-01-01
    • 1970-01-01
    • 2011-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多