正在验证发送到Web API控制器的模型

本文关键字:API 控制器 模型 Web 验证 | 更新日期: 2023-09-27 18:00:31

在对Web API服务的调用中,我有以下类属性,需要发送到其控制器方法:

public class FindBookingRequestModel 
{
    public string ReservationNumber { get; set; }
    public string CreditCardNumber { get; set; }
    public string EmailAddress { get; set; }
    public string Origin { get; set; }
    public string Destination { get; set; }
    public DateTime? StartDate { get; set; }
}

根据每个用例,我有三个场景,其中我需要验证发送到web api控制器的模型,并确保填充了以下类属性,否则我需要抛出BadRequest异常。

  1. 用例:

    {
        "ReservationNumber": "WERTSDFFSDF",
        "CreditCardNumber" : "3333"
    }   
    
  2. 用例

    {
        "ReservationNumber" : "WERTSDFFSDF",
        "EmailAddress" : "somene@gmail",
        "Origin" : "FRA",
        "Destination" : "MUN"
    }
    
  3. 用例

    {
        "StartDate" : "2015-12-15",
        "EmailAddress" : "somene@gmail",
        "Origin" : "FRA",
        "Destination" : "MUN"
    }
    

因此,如果我们将此模型发送到控制器,则应该是一个错误:

{
    "ReservationNumber": "WERTSDFFSDF",
    "Origin" : "FRA",
} 

或者这个:

{
    "EmailAddress" : "somene@gmail",
     "StartDate" : "2015-12-15",
}

确保字段按照上述用例中的说明传递的最有效方法是什么?

正在验证发送到Web API控制器的模型

您可以实现IValidatableObject来执行跨属性验证,也可能值得考虑单个属性值验证。

我建议在可能的情况下对属性值使用正则表达式(只有当属性值不为null时才会运行正则表达式,因为您没有所有有效类型所需的任何字段,请避免使用[Required]属性),然后使用Validate方法进行跨属性验证:

public class FindBookingRequestModel : IValidatableObject
{
    [RegularExpression("[A-Z]+")]
    public string ReservationNumber { get; set; }
    [RegularExpression("...")] // Find a regex online
    public string CreditCardNumber { get; set; }
    [RegularExpression("...")] // Find a regex online
    public string EmailAddress { get; set; }
    [RegularExpression("[A-Z]{3}")]
    public string Origin { get; set; }
    [RegularExpression("[A-Z]{3}")]
    public string Destination { get; set; }
    public DateTime? StartDate { get; set; }
    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        if (!string.IsNullOrWhiteSpace(this.ReservationNumber) 
            && !string.IsNullOrWhiteSpace(this.Origin))
        {
            yield return new ValidationResult(
                "You cannot search using Reservation Number and Origin", 
                new[] { "ReservationNumber", "Origin" });
        }
        if (!string.IsNullOrWhiteSpace(this.EmailAddress) 
            && this.StartDate != null)
        {
            yield return new ValidationResult(
                "You cannot search using Email Address and Start Date", 
                new[] { "EmailAddress", "StartDate" });
        }
        yield break;
    }
}

如果有太多无效的组合,你可以这样做:

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        if (!string.IsNullOrWhiteSpace(this.ReservationNumber) 
            && !string.IsNullOrWhiteSpace(this.CreditCardNumber)
            && this.EmailAddress == null
            && this.Origin == null
            && this.Destination == null
            && this.StartDate == null)
        {
            // OK - Only reservation number and credit card number specified
            yield break;
        }
        /// ...
        yield return new ValidationResult(
            "Invalid combination of search terms");
    }