Blazor服务器端的日期验证器



我的blazor服务器端组件有一个简单的输入模型。我想对两个DateTime属性使用内置验证。

[DataType(DataType.Date)]
public DateTime? FromDate { get; set; }
[DataType(DataType.Date)]
public DateTime? ToDate { get; set; }

我怎么只能接受ToDate>起始日期?

使用自定义ValidationAttribute的解决方案:

DateMustBeAfterAttribute.cs:

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public class DateMustBeAfterAttribute : ValidationAttribute
{
public DateMustBeAfterAttribute(string targetPropertyName)
=> TargetPropertyName = targetPropertyName;
public string TargetPropertyName { get; }
public string GetErrorMessage(string propertyName) =>
$"'{propertyName}' must be after '{TargetPropertyName}'.";
protected override ValidationResult? IsValid(
object? value, ValidationContext validationContext)
{
var targetValue = validationContext.ObjectInstance
.GetType()
.GetProperty(TargetPropertyName)
?.GetValue(validationContext.ObjectInstance, null);

if ((DateTime?)value < (DateTime?)targetValue)
{
var propertyName = validationContext.MemberName ?? string.Empty;
return new ValidationResult(GetErrorMessage(propertyName), new[] { propertyName });
}
return ValidationResult.Success;
}
}

DateMustBeBeforeAttribute.cs:

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public class DateMustBeBeforeAttribute : ValidationAttribute
{
public DateMustBeBeforeAttribute(string targetPropertyName)
=> TargetPropertyName = targetPropertyName;
public string TargetPropertyName { get; }
public string GetErrorMessage(string propertyName) =>
$"'{propertyName}' must be before '{TargetPropertyName}'.";
protected override ValidationResult? IsValid(
object? value, ValidationContext validationContext)
{
var targetValue = validationContext.ObjectInstance
.GetType()
.GetProperty(TargetPropertyName)
?.GetValue(validationContext.ObjectInstance, null);
if ((DateTime?)value > (DateTime?)targetValue)
{
var propertyName = validationContext.MemberName ?? string.Empty;
return new ValidationResult(GetErrorMessage(propertyName), new[] { propertyName });
}
return ValidationResult.Success;
}
}

用法:

public class DateTimeModel
{
[Required]
[DateMustBeBefore(nameof(ToDate))]
[DataType(DataType.Date)]
public DateTime? FromDate { get; set; }
[Required]
[DateMustBeAfter(nameof(FromDate))]
[DataType(DataType.Date)]   
public DateTime? ToDate { get; set; }
}

字段被链接,因此当其中任何一个字段发生更改时,我们需要通知EditContext以重新验证另一个字段。

示例EditForm:

<EditForm EditContext="editContext" OnInvalidSubmit="@HandleValidSubmit">
<DataAnnotationsValidator />
<ValidationSummary />
<p>
<label>
From Date:
<InputDate TValue="DateTime?"
Value="dateTimeModel.FromDate"
ValueChanged="HandleFromDateChanged"
ValueExpression="() => dateTimeModel.FromDate" />
</label>
<ValidationMessage For="@(() => dateTimeModel.FromDate)" />
</p>
<p>
<label>
To Date:
<InputDate TValue="DateTime?"
Value="dateTimeModel.ToDate"
ValueChanged="HandleToDateChanged"
ValueExpression="() => dateTimeModel.ToDate" />
</label>
<ValidationMessage For="@(() => dateTimeModel.ToDate)" />
</p>
<button type="submit">Submit</button>
</EditForm>
@code {
private EditContext? editContext;
private DateTimeModel dateTimeModel = new();
protected override void OnInitialized()
{
editContext = new EditContext(dateTimeModel);
}
private void HandleFromDateChanged(DateTime? fromDate)
{
dateTimeModel.FromDate = fromDate;
if (editContext != null && dateTimeModel.ToDate != null)
{
FieldIdentifier toDateField = editContext.Field(nameof(DateTimeModel.ToDate));
editContext.NotifyFieldChanged(toDateField);
}
}
private void HandleToDateChanged(DateTime? toDate)
{
dateTimeModel.ToDate = toDate;
if (editContext != null && dateTimeModel.FromDate != null)
{
FieldIdentifier fromDateField = editContext.Field(nameof(DateTimeModel.FromDate));
editContext.NotifyFieldChanged(fromDateField);
}
}
private void HandleValidSubmit()
{
}
}

Blazor小提琴示例

带有演示的GitHub存储库

使用IValidatableObject的解决方案:

要进行更复杂的验证检查,您的模型可以继承IValidatableObject接口并实现Validate方法:

public class ExampleModel : IValidatableObject
{
[DataType(DataType.Date)]
public DateTime? FromDate { get; set; }
[DataType(DataType.Date)]
public DateTime? ToDate { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (ToDate < FromDate)
{
yield return new ValidationResult("ToDate must be after FromDate", new[] { nameof(ToDate) });
}
}
}

Blazor小提琴示例

相关内容

  • 没有找到相关文章

最新更新