.NET MVC Custom Validation (no data annotation)

Use .NET MVC and Code EF to implement the requested functionality. Business objects are relatively complex, and I use System.ComponentModel.DataAnnotations.IValidatableObjectto validate a business object.
Now I'm trying to find a way to show the result of validation from a business object using MVC ValidationSummary without using data annotations. For example (very simplified):

Business Object:

    public class MyBusinessObject : BaseEntity, IValidatableObject
    {
        public virtual IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
        {
           return Validate();
        }
        public IEnumerable<ValidationResult> Validate()
        {
           List<ValidationResult> results = new List<ValidationResult>();

           if (DealType == DealTypes.NotSet)
           {
                results.Add(new ValidationResult("BO.DealType.NotSet", new[] { "DealType" }));
           }

           return results.Count > 0 ? results.AsEnumerable() : null;
        }
    }

Now in my MVC controller I have something like this:

    public class MyController : Controller
    {
        [HttpPost]
        public ActionResult New(MyModel myModel)
        {
           MyBusinessObject bo = GetBoFromModel(myModel);
           IEnumerable<ValidationResult> result = bo.Validate();
           if(result == null)
           {
               //Save bo, using my services layer
               //return RedirectResult to success page
           }

           return View(myModel);
        }
    }

In mind, I have Html.ValidationSummary();.
How can I pass IEnumerable<ValidationResult>to ValidationSummary?

I tried to find the answer on googling, but all the examples that I found describe how to show a validation summary using data annotations in the model, and not in the business object.

thank

+5
4

, BusinessError,

  @Html.ValidationMessageFor(model => model.BusinessError)

, ,

ModelState.AddModelError("BussinessError", your error)
+11

FluentValidation. . , MVC-.

:

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.Company).NotNull();
    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;
+2

Entity Framework should throw DbEntityValidationExceptionif there are validation errors. You can then use the exception to add errors to ModelState.

try
{
     SaveChanges();
}
catch (DbEntityValidationException ex)
{
     AddDbErrorsToModelState(ex);
}
return View(myModel);

protected void AddDbErrorsToModelState(DbEntityValidationException ex)
{
     foreach (var validationErrors in ex.EntityValidationErrors)
     {
          foreach (var validationError in validationErrors.ValidationErrors)
          {
               ModelState.AddModelError(validationError.PropertyName, validationError.ErrorMessage);
          }
     }
}
+1
source

One way to pass the contents of IEnumerate and use Html.ValidationSummary is to update the ModelState.

You can find a good discussion on how to update ModelState here .

0
source

All Articles