[英]Date validator in Blazor Server Side
我的 blazor 服务器端组件有一个简单的输入 model。 我想对两个 DateTime 属性使用内置验证。
[DataType(DataType.Date)]
public DateTime? FromDate { get; set; }
[DataType(DataType.Date)]
public DateTime? ToDate { get; set; }
我怎么能只接受 ToDate > FromDate?
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()
{
}
}
IValidatableObject
解决方案: 要进行更复杂的验证检查,您的 model 可以继承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) });
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.