Created
May 17, 2017 09:14
-
-
Save hidegh/05d02e9c0d7c65c3acc18270fb9d34d4 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.ComponentModel.DataAnnotations; | |
using System.Linq; | |
using System.Web.Mvc; | |
namespace My.Web.Code.Binder | |
{ | |
/// <summary> | |
/// Inside Global.asax: | |
/// ModelValidatorProviders.Providers.Clear(); | |
/// ModelValidatorProviders.Providers.Add(new MvcDataAnnotationsModelValidatorProviderWithDependencyResolverSupport()); | |
/// </summary> | |
public class MvcDataAnnotationsModelValidatorProviderWithDependencyResolverSupport : DataAnnotationsModelValidatorProvider | |
{ | |
private readonly IServiceProvider serviceProvider; | |
public MvcDataAnnotationsModelValidatorProviderWithDependencyResolverSupport() : this (new MvcServiceProvider()) | |
{ | |
} | |
public MvcDataAnnotationsModelValidatorProviderWithDependencyResolverSupport(IServiceProvider serviceProvider) | |
{ | |
this.serviceProvider = serviceProvider; | |
RegisterDefaultAdapterFactory( | |
(metadata, context, attribute) => | |
new CustomDataAnnotationsModelValidator(serviceProvider, metadata, context, attribute) | |
); | |
RegisterDefaultValidatableObjectAdapterFactory( | |
(metadata, context) => new CustomValidatableObjectAdapter(serviceProvider, metadata, context) | |
); | |
} | |
// | |
// Internal (private) classes | |
// | |
private class MvcServiceProvider : IServiceProvider | |
{ | |
public object GetService(Type serviceType) | |
{ | |
return DependencyResolver.Current.GetService(serviceType); | |
} | |
} | |
private class CustomDataAnnotationsModelValidator : DataAnnotationsModelValidator | |
{ | |
private readonly IServiceProvider serviceProvider; | |
public CustomDataAnnotationsModelValidator(IServiceProvider serviceProvider, ModelMetadata metadata, ControllerContext context, ValidationAttribute attribute) | |
: base(metadata, context, attribute) | |
{ | |
this.serviceProvider = serviceProvider; | |
} | |
public override IEnumerable<ModelValidationResult> Validate(object container) | |
{ | |
ValidationContext context = new ValidationContext(container ?? Metadata.Model, serviceProvider, null); | |
context.DisplayName = Metadata.GetDisplayName(); | |
ValidationResult result = Attribute.GetValidationResult(Metadata.Model, context); | |
if (result != ValidationResult.Success) | |
{ | |
yield return new ModelValidationResult | |
{ | |
Message = result.ErrorMessage | |
}; | |
} | |
} | |
} | |
private class CustomValidatableObjectAdapter : ValidatableObjectAdapter | |
{ | |
private readonly IServiceProvider serviceProvider; | |
public CustomValidatableObjectAdapter(IServiceProvider serviceProvider, ModelMetadata metadata, ControllerContext context) : base(metadata, context) | |
{ | |
this.serviceProvider = serviceProvider; | |
} | |
public override IEnumerable<ModelValidationResult> Validate(object container) | |
{ | |
object model = Metadata.Model; | |
if (model == null) | |
{ | |
return Enumerable.Empty<ModelValidationResult>(); | |
} | |
IValidatableObject validatable = model as IValidatableObject; | |
if (validatable == null) | |
{ | |
throw new InvalidOperationException(); | |
} | |
ValidationContext validationContext = new ValidationContext(validatable, serviceProvider, null); | |
return ConvertResults(validatable.Validate(validationContext)); | |
} | |
private IEnumerable<ModelValidationResult> ConvertResults(IEnumerable<ValidationResult> results) | |
{ | |
foreach (ValidationResult result in results) | |
{ | |
if (result != ValidationResult.Success) | |
{ | |
if (result.MemberNames == null || !result.MemberNames.Any()) | |
{ | |
yield return new ModelValidationResult { Message = result.ErrorMessage }; | |
} | |
else | |
{ | |
foreach (string memberName in result.MemberNames) | |
{ | |
yield return new ModelValidationResult { Message = result.ErrorMessage, MemberName = memberName }; | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment