簡體   English   中英

使用 FluentValidation 訪問驗證多個字段的數據庫

[英]Use FluentValidation to access the database validating more than one field

我學會了如何使用流利的驗證器我想知道你是否可以幫助我解決一個問題。 我有一個個人系統,在我的 controller 中,create post 方法具有以下代碼:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create (TicketViewModel model)
{
    ICollection <Piece> pieces;
    try
    {
        if (ModelState.IsValid)
        {
            if (_ticketRepository.GetById (model.Id)! = null)
            {
                Console.WriteLine ("Ticket already exists!");
            }

            var _model = _mapper.Map <Ticket> (model);
            var count = _ticketRepository.FindAllByPiece (_model);

            if (count> 0)
            {
                ModelState.AddModelError ("", "This ticket already exists for this room. Check the piece, date and time.");
                pieces = _pieceRepository.FindAll ();
                model.Pieces = pieces;
                return View (model);
            }

            _ticketRepository.Insert (_model);
            model.Seats = RegistrationSeats (model.QuantityOfSeats);

            return RedirectToAction ("Index");
        }
        pieces = _pieceRepository.FindAll ();

        model.Pieces = pieces;

        return View (model);
    }
    catch (Exception ex)
    {
        Console.WriteLine (ex.Message);
        return View (model);
    }
}

請注意,在上面的代碼中,我有這樣的部分:

var count = _ticketRepository.FindAllByPiece (_model);    
if (count> 0)
{
    ModelState.AddModelError ("", "This ticket already exists for this room. Check the piece, date and time.");
    pieces = _pieceRepository.FindAll ();
    model.Pieces = pieces;
    return View (model);
}
  • 此代碼片段從存儲庫中調用一項服務,該服務檢查傳遞的 model(票證)是否具有與銀行中已有的相同的 partId、日期和時間表。 如果存在具有這些相同值的記錄,則他不會添加票證,直到該人創建與已經存在的票證不同的票證。
  • 以下是訪問銀行進行此搜索的服務代碼:
public int FindAllByPiece(Ticket model)
{
    return _saleTheaterTicketsContext.Tickets.Include(x => x.Piece).Where(x => x.PieceId == model.PieceId && x.Date == model.Date && x.Schedule == model.Schedule).Count();
}
  • 這很好用,並在視圖中顯示我在ModelState.AddModelError中添加的消息,我在視圖中這樣做:
<strong class = "text-danger">@ Html.ValidationSummary (true)</strong>
  • 我的問題是當我使用 FluentValidation 時,我想知道是否有任何方法可以做到這一點,這樣 controller 就不會充滿東西。 我做了一些研究,但無濟於事。 我嘗試在驗證 class 中實例化存儲庫(我將在下面放置代碼),但我不知道如何對這三個字段進行驗證,將 model 傳遞給存儲庫。 你能幫我嗎?
  • 這是使用 FluentValidator 驗證 class 的代碼:
public class TicketViewModelValidator: AbstractValidator <TicketViewModel>
{
    public TicketViewModelValidator ()
    {
        RuleFor (x => x.Price)
            .NotEmpty (). WithMessage ("Enter the price")
            .GreaterThan (0) .WithMessage ("The price must be greater than 0.00");
        RuleFor (x => x.QuantityOfSeats)
            .NotEmpty (). WithMessage ("Enter the number of seats")
            .GreaterThanOrEqualTo (10) .WithMessage ("The number of seats must be at least 10");
        RuleFor (x => x.Date)
            .NotEmpty (). WithMessage ("Enter Date")
            .Must (ValidDate) .WithMessage ("Date must be greater than or equal to today");
        RuleFor (x => x.Schedule)
            .NotEmpty (). WithMessage ("Enter time");
        RuleFor (x => x.PieceId)
            .NotEmpty (). WithMessage ("Select the part");
    }

    public static bool ValidDate (DateTime date)
    {
        if (date.Date> = DateTime.Now.Date)
        {
            return true;
        }

        return false;
    }
}

Fluent 驗證使用“Must”方法處理此問題。 以下是您需要做的簡化

  1. 將 _ticketRepository 的實例傳遞給驗證器。 這要求您使用依賴注入。 我假設您在 controller 中這樣做。 您的驗證器的構造函數將被修改為如下所示:

    public class TicketViewModelValidator: AbstractValidator <TicketViewModel>
    {
        private ITiekctRepository _ticketRepository;
    
        public TicketViewModelValidator (ITicketRepository ticketRepository)
        {
            _ticketRepository = ticketRepository;
            //...rules go here
        }
  1. 修改您的規則以檢查存儲庫是否符合您的條件。 例如,您可能會執行以下操作:
RuleFor(t => t.Id).NotEmpty().Must(BeUnique).WithMessage("A ticket must have an ID that is unique in the database").

然后像這樣定義一個“BeUnique”方法

    private bool BeUnique(TicketViewModelTicketViewModel instance)
    {
         // The instance is the model being validated.
         if (_ticketRepository.GetById (instance.Id) == null)
             return true
         return false;
    }

這里有很大的靈活性,因此請仔細閱讀文檔。 請注意,由於您正在處理 model(在方法中稱為實例),因此您可以訪問所有屬性並且一次可以檢查多個內容。 不過,您可能不想這樣做,因為它使返回良好的錯誤消息變得更加困難。 此技術適用於實體框架,因為 model.Id 引用的數據model.Id將緩存在 dbContext 中,並在以后需要時重用,因此它保存為查詢。

請注意,我從 memory 輸入了很多這樣的內容,而沒有使用編譯器或 Intellisense 來獲得正確的語法。 基本流程應該可以工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM