基于其他值的自定义验证 [英] Custom validation based on other value

查看:92
本文介绍了基于其他值的自定义验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我为餐厅制作了一个预订表格,其中要求提供餐厅名称,用餐日期和人数.

I make a Booking form for restaurant, which asks for the name of the restaurant, the date of the meal and the number of person.

我有一个预订班,有一个ID,餐厅ID,日期和人数:

I have a booking class, which has an ID, an ID of the restaurant, a date and a number of people :

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

以及具有ID,名称,电话号码和表格编号的Resto类:

As well as a Resto class, which has an ID, a name, phone number and a number of table :

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

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

I would like to make a validation to check with each new reservation, that the restaurant is not full. To do this, when validating the "Number of persons" field of the Booking, I need the value of the "restaurant name" field and the value of the "date" field, and then retrieve all the bookings on this Restaurant at that date, and check whether the sum of the number of persons is much lower than the capacity of the restaurant.

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;

    }

}

(这是草稿,测试显然没有完成)

(It's a draft, the tests are not finished obviously)

我该如何利用其他专有财产的价值进行验证?

How can I have the value of the other proprieties for my validation ?

推荐答案

这不适用于验证属性.首先,验证属性应该是独立的,或者至少是独立的.由于此处的逻辑取决于两个属性(人数和预订日期),因此验证属性将需要过多的域知识才能执行必要的验证.换句话说,它是不可重用的,并且如果它不可重用,那么使用属性毫无意义.

This is not appropriate for a validation attribute. First, a validation attribute should be independent, or at least self-contained. Since the logic here depends on two different properties (the number of people and the date of the booking) a validation attribute would require too much knowledge of the domain in order to perform the necessary validation. In other words, it's not reusable, and if it's not reusable, then there's no point in using an attribute.

第二,验证属性不应执行类似查询数据库的操作.仅控制器应负责与DAL一起工作.当您开始在整个应用程序中乱扔数据库访问权限时,您将以很短的顺序开始遇到各种问题.如果您使用DI容器将DAL注入到需要的地方,那么在控制器外部使用它的问题就更少了,但 重要的是,属性确实不能很好地与依赖项注入配合使用.您可以使其与某些DI容器一起使用,但这绝非易事,您稍后可能会后悔.因此,再次,这实际上不应该是验证属性要处理的事情.

Second, a validation attribute should not do something like make a database query. The controller alone should be responsible for working with your DAL. When you start littering database access across your application, you're going to start running into all sorts of issues in very short order. If you use a DI container to inject your DAL where it needs to go, it's less problematic to use it outside of the controller, but importantly, attributes really don't play well with dependency injection. You can make it work with some DI containers, but it's never easy and you're probably going to regret it later. So, again, this really shouldn't be something a validation attribute handles.

我认为最好的方法是简单地在控制器上创建一个私有/受保护的方法来处理此验证.像这样:

The best approach in my opinion is to simply create a private/protected method on your controller to handle this validation. Something like:

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之前调用它即可.

Then, in your post action for the booking, simply call this before checking ModelState.IsValid.

这篇关于基于其他值的自定义验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆