gpt4 book ai didi

c# - 在 ASP.NET/MVC 中验证复杂案例的最佳实践?

转载 作者:行者123 更新时间:2023-11-30 20:53:35 26 4
gpt4 key购买 nike

我们总是被告知 Controller 应该是瘦的,并且验证应该在 Model 中完成,而不是 Controller。但是请考虑以下示例。

这是一个简单的 ModelController,用于处理来自编辑屏幕的 POST,我们可以在编辑屏幕上编辑 Person 对象。

public class PersonEditModel
{
[Required(ErrorMessage = "No ID Passed")]
public int ID { get; set; }

[Required(ErrorMessage = "First name Required")]
[StringLength(50,ErrorMessage = "Must be under 50 characters")]
public string FirstName { get; set; }

[Required(ErrorMessage = "Last name Required")]
[StringLength(50,ErrorMessage = "Must be under 50 characters")]
public string LastName { get; set; }
}

public class PersonController : Controller
{
// [HttpGet]View, [HttpGet]Edit Controller methods omitted for brevity

[HttpPost]
public ActionResult Edit(PersonEditModel model)
{
// save changes to the record
return RedirectToAction("View", "Person", new { ID = model.ID});
}
}

模型 在这里执行两种类型的验证。它验证 FirstNameLastName,但它验证用于访问记录的私钥 (ID)想改变。此验证是否也应在 Model 中完成?

如果我们随后想要扩展验证(正如我们应该的那样)以包括检查该记录是否存在怎么办?

通常,我会在 Controller 中验证这一点:

[HttpPost]
public ActionResult Edit(PersonEditModel model)
{
using(DatabaseContext db = new DatabaseContext())
{
var _person = db.Persons.Where(x => x.ID == model.ID);
if(_person == null)
{
ModelState.AddError("This person does not exist!");
// not sure how we got here, malicious post maybe. Who knows.
// so since the ID is invalid, we return the user to the Person List
return RedirectToAction("List", Person");
}
// save changes
}
// if we got here, everything likely worked out fine
return RedirectToAction("View", "Person", new { ID = model.ID});
}

这是不好的做法吗?我是否应该检查记录是否存在于模型中某种复杂的自定义验证方法中?我应该把它完全放在别的地方吗?

更新

相关说明。 ViewModel 是否应该包含填充数据的方法?

哪一个是更好的做法 - 这个

public class PersonViewModel
{
public Person person { get; set; }

public PersonViewModel(int ID){
using(DatabaseContext db = new DatabaseContext())
{
this.person = db.Persons.Where(x => x.ID == ID);
}
}
}

[HttpPost]
public ActionResult View(int ID)
{
return View("View", new PersonViewModel(ID));
}

还是这个?

public class PersonViewModel
{
public Person person { get; set; }
}

[HttpPost]
public ActionResult View(int ID)
{
PersonViewModel model = new PersonViewModel();
using(DatabaseContext db = new DatabaseContext())
{
model.person = db.Persons.Where(x => x.ID == ID);
}
return View("View", model);
}

最佳答案

我通常更喜欢 FluentValidation出于所有目的。它还有一个 Nuget在 VS 中开箱即用地安装它。

示例验证码来自 here :

using FluentValidation;

public class CustomerValidator: AbstractValidator<Customer> {
public CustomerValidator() {
RuleFor(customer => customer.Surname).NotEmpty();
RuleFor(customer => customer.Forename).NotEmpty().WithMessage("Please specify a first name");
RuleFor(customer => customer.Discount).NotEqual(0).When(customer => customer.HasDiscount);
RuleFor(customer => customer.Address).Length(20, 250);
RuleFor(customer => customer.Postcode).Must(BeAValidPostcode).WithMessage("Please specify a valid postcode");
}

private bool BeAValidPostcode(string postcode) {
// custom postcode validating logic goes here
}
}

Customer customer = new Customer();
CustomerValidator validator = new CustomerValidator();
ValidationResult results = validator.Validate(customer);

bool validationSucceeded = results.IsValid;
IList<ValidationFailure> failures = results.Errors;

看到了吗?使用简洁的方法使用 Fluent Validation 验证任何类型的模型都非常容易。可以考虑通过FluentValidation Documentation .

在哪里验证?

假设您有如下模型:

public class Category
{
public int ID { get; set; }
public string Name { get; set; }
virtual public ICollection<Image> Images { get; set; }
}

然后,您将在类似的类库或最好是一个新的类库中定义另一个验证器模型来处理项目中所有模型的验证。

public class CategoryValidator : AbstractValidator<Category>
{
public CategoryValidator()
{
RuleFor(x => x.Name).NotEmpty().WithMessage("Category name is required.");
}
}

因此,您可以在单独的验证器模型中执行此操作,从而使您的方法和领域模型尽可能干净。

关于c# - 在 ASP.NET/MVC 中验证复杂案例的最佳实践?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19864181/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com