我有使用DataContract的数据类,并使用System.ComponentModel.DataAnnotations实现了字段验证。
在我的课堂上,type属性使某些字段相关,而另一些字段则不适用。也就是说,某些字段(取决于type属性)将变为无效,而另一些字段将有效。
我正在努力寻找一种好的模式,以优雅的方式验证这种情况。我愿意接受这种情况,这可能意味着我需要将我的课程分成几部分以适应这种多态性。虽然不确定如何。
只要相关,这些数据类将被序列化并存储在ServiceFabric可靠集合上。从API角度来看,可以进行更多验证。
到目前为止,我正在端点控制器中以这种方式(我认为还不令人满意)执行验证。
if (voucher.ServiceType == ServiceType.VaccineCompany)
{
if (voucher.Asignee == null)
{
throw new ArgumentNullException("Asignee is required for company vaccine voucher");
}
if (!voucher.BookingTime.HasValue)
{
throw new ArgumentNullException("Booking time is required for company vaccine voucher");
}
if (!voucher.FixedPrice.HasValue)
{
throw new ArgumentNullException("Fixed price is required for company vaccine voucher");
}
if (voucher.Discount.HasValue)
{
throw new ArgumentNullException("Discount is not a valid argument for company vaccine type voucher");
}
}
if (voucher.ServiceType == ServiceType.Vaccine)
{
if (voucher.Asignee != null)
{
throw new ArgumentException("Invalid argument asignee");
}
if (voucher.BookingTime.HasValue)
{
throw new ArgumentNullException("Invalid argument booking time");
}
if (voucher.FixedPrice.HasValue && voucher.Discount.HasValue)
{
throw new ArgumentException("Fixed price and discount cannot be set simultaneously");
}
}
这是模型的样子:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Runtime.Serialization;
namespace Remoting.VoucherService
{
[DataContract]
public sealed class Voucher
{
[Required(ErrorMessage = "Code is required")]
[DataMember(Name = "code")]
public string Code { get; set; }
[Required(ErrorMessage = "Description is required")]
[DataMember(Name = "description")]
public string Description { get; set; }
[Required(ErrorMessage = "ServiceType is required")]
[DataMember(Name = "serviceType")]
public ServiceType ServiceType { get; set; }
[DataMember(Name = "discount")]
public double? Discount { get; set; }
[DataMember(Name = "fixedPrice")]
public double? FixedPrice { get; set; }
[DataMember(Name = "isValid")]
public bool Valid {
get { return TimesUsed < MaxUsage; }
set { }
}
[DataMember(Name = "maxUsage")]
public uint MaxUsage { get; set; } = 1;
[DataMember(Name = "asignee")]
public string Asignee;
[DataMember(Name = "bookingTime")]
public DateTime? BookingTime;
[DataMember(Name = "timesUsed")]
public uint TimesUsed { get; set; } = 0;
public void IncreaseUsage()
{
TimesUsed += 1;
}
private ExtensionDataObject data;
public ExtensionDataObject ExtensionData
{
get => data;
set => data = value;
}
}
}
我希望有人能为我提供一些见识!