Skip to content

Instantly share code, notes, and snippets.

@RobinHerbots
Last active December 14, 2015 08:09
Show Gist options
  • Save RobinHerbots/5055542 to your computer and use it in GitHub Desktop.
Save RobinHerbots/5055542 to your computer and use it in GitHub Desktop.
MVC DataAnnotations - Validate submodel in model with separate result in ModelState
public class MvcApplication : HttpApplication
{
protected void Application_Start()
{
ModelValidatorProviders.Providers.Add(new RecursiveModelValidatorProvider());
....
public class Model
{
[Required]
public string Name { get; set; }
[ValidateObjectAttribute] // set market attribute
public AddressModel Address { get; set; }
}
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Diagnostics;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace ModelValidation
{
public class RecursiveModelValidator : ModelValidator
{
public RecursiveModelValidator(ModelMetadata metadata, ControllerContext context, ValidateObjectAttribute attribute) : base(metadata, context) { }
public override IEnumerable<ModelValidationResult> Validate(object container)
{
if (Metadata.Model != null)
{
foreach (ModelMetadata propertyMetadata in Metadata.Properties)
{
foreach (ModelValidator propertyValidator in propertyMetadata.GetValidators(ControllerContext))
{
foreach (ModelValidationResult propertyResult in propertyValidator.Validate(Metadata.Model))
{
yield return new ModelValidationResult
{
MemberName = propertyMetadata.PropertyName,
Message = propertyResult.Message
};
}
}
}
}
else {
if (Metadata.IsRequired)
{
yield return new ModelValidationResult
{
MemberName = Metadata.ModelType.ToString(),
Message = "The model may not be null."
};
}
}
}
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace ModelValidation
{
/// <summary>
/// ModelValidatorProvider to enable recursive validation of submodels in the current model
/// </summary>
public class RecursiveModelValidatorProvider : AssociatedValidatorProvider
{
protected override IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context, IEnumerable<Attribute> attributes)
{
foreach (Attribute attribute in attributes)
{
if (attribute is ValidateObjectAttribute)
yield return new RecursiveModelValidator(metadata, context, (ValidateObjectAttribute)attribute);
}
}
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
namespace ModelValidation
{
public class ValidateObjectAttribute : Attribute
{
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment