Blazor:使用同一模型验证多个表单

Blazor: validating multiple forms with the same model

我的 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; }

不幸的是,当第一个表单显示并提交时,缺少的字段被验证,验证失败。有什么方法可以不拆分模型或使用自定义验证吗?

我通过从 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;
    }
}

请求示例:

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; }
}

然后是你的消费components/pages

@page "/Form1"

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

@code {
    private Form1 _form1 = new()
}