使用FluentValidation访问验证多个字段的数据库



我学会了如何使用流畅验证器,我想知道您是否可以帮助我解决一个问题。我有一个个人系统,在我的控制器中创建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);
}
  • 这个代码片段从存储库调用一个服务,该服务检查传递的模型(票据)是否与银行中已经存在的模型(票据)具有相同的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,我想知道是否有任何方法可以用它来做这件事,这样控制器就不会充满东西。我做了一些调查,但没有结果。我试图在验证类中实例化存储库(我将把代码放在下面),但我不知道如何对这3个字段进行验证,将模型传递给存储库。你能帮我吗?
  • 下面是使用FluentValidator的验证类的代码:
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;
}
}

流畅验证使用"必须"方法。以下是对您需要做的事情的简化

  1. 将_tickerepository的一个实例传递给验证器。这需要使用依赖注入。我假设你在控制器中这样做。您的验证器的构造函数将被修改如下:

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

这里有很多灵活性,所以仔细阅读文档。请注意,由于您正在处理模型(在方法中称为instance),因此您可以访问所有属性,并且一次可以检查多个内容。但您可能不希望这样做,因为这会使返回良好的错误消息变得更加困难。这种技术在实体框架中工作得很好,因为model.Id引用的数据对象将被缓存在dbContext中,并在需要时重用,所以它保存了一个查询。

请注意,我已经从内存中输入了很多这没有使用编译器或智能感知来获得正确的语法。基本流程应该可以工作。

相关内容

  • 没有找到相关文章

最新更新