c# - 基于其他值的自定义验证

标签 c# asp.net-mvc validation validationattribute

我制作了一份餐厅预订表,其中询问餐厅名称、用餐日期和人数。

我有一个预订舱位,其中包含 ID、餐厅 ID、日期和人数:

public class Booking
{
    public int Id { get; set; }
    public int IDRestaurant{ get; set; }
    [CustomPlaceValidator]
    public int Nbpeople { get; set; }
    [CustomDateValidator]
    public DateTime Date { get; set; }
}

还有一个 Resto 类,其中有 ID、姓名、电话号码和表号:

public class Resto
{
    public int Id { get; set; }
    [Required(ErrorMessage = "Le nom du restaurant doit être saisi")]
    public string Nom { get; set; }
    [Display(Name = "Téléphone")]
    [RegularExpression(@"^0[0-9]{9}$", ErrorMessage = "Le numéro de téléphone est incorrect")]
    public string Telephone { get; set; }
    [Range(0, 9999)]
    public int Size { get; set; }
}

我想对每个新预订进行验证,以确保餐厅未满员。 为此,在验证预订的“人数”字段时,我需要“餐厅名称”字段的值和“日期”字段的值,然后检索该日期该餐厅的所有预订,检查人数总和是否远低于餐厅容纳人数。

public class CustomPlaceValidator : ValidationAttribute
{
    private IDal dal = new Dal();
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        int nb = 0;
        if (dal.GetAllBooking() != null)
        {
            foreach (var booking in dal.GetAllBooking())
                nb += booking.Nbpeople;
            if (nb ..... ) return ValidationResult.Success;
            return new ValidationResult("The restaurant is full for this date.");
        }
        return ValidationResult.Success;

    }

}

(这是一个草案,测试显然还没有完成)

我怎样才能获得其他属性的值(value)来进行验证?

最佳答案

这不适用于验证属性。首先,验证属性应该是独立的,或者至少是独立的。由于这里的逻辑取决于两个不同的属性(人数和预订日期),验证属性需要太多的领域知识才能执行必要的验证。换句话说,它不可重用,如果不可重用,那么使用属性就没有意义。

其次,验证属性不应该执行诸如进行数据库查询之类的操作。 Controller 应该单独负责与您的 DAL 一起工作。当您开始在应用程序中乱扔数据库访问时,您将在很短的时间内开始遇到各种问题。如果您使用 DI 容器将 DAL 注入(inject)到需要的地方,那么在 Controller 外部使用它的问题就不那么大了,重要的是,属性确实不能很好地与依赖项注入(inject)配合使用。您可以使其与某些 DI 容器一起使用,但这绝非易事,而且您以后可能会后悔。因此,这确实不应该是验证属性处理的事情。

我认为最好的方法是简单地在 Controller 上创建一个私有(private)/ protected 方法来处理此验证。像这样的东西:

public void ValidateCapacity(Booking booking)
{
    var restaurant = dal.GetRestaurant(booking.IDRestaurant);
    var existingBookings = dal.GetBookings(booking.IDRestaurant, booking.Date);
    var available = restaurant.Size - existingBookings.Sum(b => b.Nbpeople);
    if (booking.Nbpeople > available)
    {
        ModelState.AddModelError("Nbpeople", "There is not enough capacity at the restaurant for this many people on the date you've selected");
    }
}

然后,在预订的后操作中,只需在检查 ModelState.IsValid 之前调用此方法即可。

关于c# - 基于其他值的自定义验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44848134/

相关文章:

c# - 如何摆脱由 MVC 属性路由引起的这个错误?

ruby-on-rails - rails 3 - belongs_to :uniqueness

c# - 验证 ABN(澳大利亚商业编号)

c# - 为什么有时无法收到使用 Azure SendGrid 从 ASP.Net core Web 应用程序发送的电子邮件

javascript - 创建 MVC 格式的动态元素

c# - 如何跳过 `foreach` 循环的迭代?

asp.net-mvc - asp.net mvc 中编辑器模板中复杂类型的 ModelMetadata

使用拦截器进行WCF参数验证

c# - System.Text.Encoding.GetEncoding ("iso-8859-1") 抛出 PlatformNotSupportedException?

c# 哪里可以找到System.Windows.Controls.dll