記錄一次RestFul風格的api-12(資料驗證)
阿新 • • 發佈:2021-12-01
具體實現:(資料的輸入)
1.新增資料驗證。使用System.ComponentModel.DataAnnotations;
public class TouristRouteCreateDto { [Required(ErrorMessage="title 不可為空")] [MaxLength(100)] public string Title { get; set; } [Required] [MaxLength(1500)]
}
2.自定義資料驗證。
具體的dto如下:
public class TouristRouteCreateDto : IValidatableObject { [Required(ErrorMessage="title 不可為空")] [MaxLength(100)] public string Title { get; set; } [Required] [MaxLength(1500)] public string Description { get; set; } // 計算方式=原價*折扣 public decimal? Price { get; set; } //public decimal originalPrice { get; set; } //public double? DiscountPresent { get; set; }public DateTime CreateTime { get; set; } public DateTime? updateTime { get; set; } public DateTime? DepartureTime { get; set; } public string Features { get; set; } public string Fees { get; set; } public string Notes { get; set; } public ICollection<TouristRoutePictureForCreationDto> TouristRoutePictures { get; set; } = new List<TouristRoutePictureForCreationDto>(); public double? Rating { get; set; }//評分 public string TravelDays { get; set; } public string TripType { get; set; } public string DepartureCity { get; set; } public IEnumerable<ValidationResult> Validate( ValidationContext validationContext) { if (Title == Description) { yield return new ValidationResult( "路線名稱必須與路線描述不同", new[] { "TouristRouteCreateDto" } ); } } }
3.ValidationContext的自定義校驗ValidationAttribute
public class TouristRouteTitleMustBeDifferentFromDescriptionAttribute : ValidationAttribute { protected override ValidationResult IsValid( object value, ValidationContext validationContext ) { var touristRouteDto = (TouristRouteForCreationDto)validationContext.ObjectInstance; if (touristRouteDto.Title == touristRouteDto.Description) { return new ValidationResult( "路線名稱必須與路線描述不同", new[] { "TouristRouteCreateDto" } ); } return ValidationResult.Success; } }
[TouristRouteTitleMustBeDifferentFromDescriptionAttribute] public class TouristRouteForCreationDto //: IValidatableObject { [Required(ErrorMessage="title 不可為空")] [MaxLength(100)] public string Title { get; set; } [Required] [MaxLength(1500)] public string Description { get; set; } // 計算方式=原價*折扣 public decimal? Price { get; set; } //public decimal originalPrice { get; set; } //public double? DiscountPresent { get; set; } public DateTime CreateTime { get; set; } public DateTime? updateTime { get; set; } public DateTime? DepartureTime { get; set; } public string Features { get; set; } public string Fees { get; set; } public string Notes { get; set; } public ICollection<TouristRoutePictureForCreationDto> TouristRoutePictures { get; set; } = new List<TouristRoutePictureForCreationDto>(); public double? Rating { get; set; }//評分 public string TravelDays { get; set; } public string TripType { get; set; } public string DepartureCity { get; set; } //public IEnumerable<ValidationResult> Validate( // ValidationContext validationContext) //{ // if (Title == Description) // { // yield return new ValidationResult( // "路線名稱必須與路線描述不同", // new[] { "TouristRouteCreateDto" } // ); // } //} }
4,修改返回狀態碼422.(400->422)startup.cs中。
public void ConfigureServices(IServiceCollection services) { services.AddControllers(setupAction => { setupAction.ReturnHttpNotAcceptable = true; }).AddXmlDataContractSerializerFormatters() .ConfigureApiBehaviorOptions(setupAction => { setupAction.InvalidModelStateResponseFactory = context => { var problemDetail = new ValidationProblemDetails(context.ModelState) { Type = "", Title = "資料驗證失敗", Status = StatusCodes.Status402PaymentRequired, Detail = "請看詳細資訊", Instance = context.HttpContext.Request.Path }; problemDetail.Extensions.Add("traceId", context.HttpContext.TraceIdentifier); return new UnprocessableEntityObjectResult(problemDetail) { ContentTypes = { "application/problem+json" } }; }; }) ; services.AddTransient<ITouristRouteRepository, TouristRouteRepository>(); services.AddDbContext<AppDbContext>(options => { options.UseSqlServer(Configuration.GetConnectionString("delfault")); }); // 載入automapper的pofile的檔案 services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies()); }