use .NET MVC and code-first EF to implement of requested functionality. Business objects are relatively complex and I use System.ComponentModel.DataAnnotations.IValidatableObject
to validate business object.
Now I'm trying to find the way, how to show validation result from 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 view, I have Html.ValidationSummary();
.
How I can pass IEnumerable<ValidationResult>
to the ValidationSummary?
I tried to find an answer by googling, but all examples I found describes how to show validation summary using data annotations in Model and not in Business object.
Thanks
Add property, say BusinessError, in the model
in the View do the following
@Html.ValidationMessageFor(model => model.BusinessError)
Then in your controller whenever you have error do the following
ModelState.AddModelError("BussinessError", your error)
I would have a look at FluentValidation. It's a framework for validation without data annoations. I've used it with great success in some projects for complex validation, and it is also usable outside of the MVC-project.
Here is the sample code from their page:
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;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With