1. 程式人生 > 其它 >記錄一次RestFul風格的api-12(資料驗證)

記錄一次RestFul風格的api-12(資料驗證)

具體實現:(資料的輸入)

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