MVC 2에서 모델 검증 중에 idataerRorinfo가 무시됩니까?
-
21-09-2019 - |
문제
현재 프로젝트를 MVC 2로 마이그레이션했으며 기본 모델 바인딩 및 검증을 사용할 때 IdataErrorInfo가 작동하지 않는 것 같습니다. 잘라내나요?
해결책
요약
이 오류를 MVC 2 문제 추적기에 게시했습니다. http://aspnet.codeplex.com/workitem/view.aspx?workitemid=4891
다음 미리보기 릴리스에서 해결됩니다.
MVC 1.0의 DefaultModelBinder :
protected virtual void OnPropertyValidated(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor, object value)
{
IDataErrorInfo model = bindingContext.Model as IDataErrorInfo;
if (model != null)
{
string str = model[propertyDescriptor.Name];
if (!string.IsNullOrEmpty(str))
{
string key = CreateSubPropertyName(bindingContext.ModelName, propertyDescriptor.Name);
bindingContext.ModelState.AddModelError(key, str);
}
}
}
MVC 2.0 베타의 DefaultModelBinder :
protected virtual void OnPropertyValidated(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor, object value)
{
ModelMetadata metadata = bindingContext.PropertyMetadata[propertyDescriptor.Name];
metadata.Model = value;
string prefix = CreateSubPropertyName(bindingContext.ModelName, metadata.PropertyName);
foreach (ModelValidator validator in metadata.GetValidators(controllerContext))
{
foreach (ModelValidationResult result in validator.Validate(bindingContext.Model))
{
bindingContext.ModelState.AddModelError(CreateSubPropertyName(prefix, result.MemberName), result.Message);
}
}
if ((bindingContext.ModelState.IsValidField(prefix) && (value == null)) && !TypeHelpers.TypeAllowsNullValue(propertyDescriptor.PropertyType))
{
bindingContext.ModelState.AddModelError(prefix, GetValueRequiredResource(controllerContext));
}
}
defaultModelBinder는 여전히 오류 속성을 사용하기 때문에 IdataErrorInfo이 [String ColumnName] 속성을 사용하지 않습니다. 적어도 불일치입니다.
편집하다
나는 반사판을 사용하여 DataErrorinFopropertyModelValidator가 사용되지 않는 것 같았으므로 내 자신의 클래스를 만들었습니다.
public class DataErrorInfoModelPropertyValidatorProvider : ModelValidatorProvider
{
// Methods
public override IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context)
{
if (metadata == null)
{
throw new ArgumentNullException("metadata");
}
if (context == null)
{
throw new ArgumentNullException("context");
}
var validators = new List<ModelValidator>();
validators.Add(new DataErrorInfoPropertyModelValidator(metadata, context));
return validators;
}
internal sealed class DataErrorInfoPropertyModelValidator : ModelValidator
{
// Methods
public DataErrorInfoPropertyModelValidator(ModelMetadata metadata, ControllerContext controllerContext)
: base(metadata, controllerContext)
{
}
public override IEnumerable<ModelValidationResult> Validate(object container)
{
if (container != null)
{
IDataErrorInfo info = container as IDataErrorInfo;
if (info != null)
{
string str = info[Metadata.PropertyName];
if (!string.IsNullOrEmpty(str))
{
ModelValidationResult[] resultArray = new ModelValidationResult[1];
ModelValidationResult result = new ModelValidationResult();
result.Message = str;
resultArray[0] = result;
return resultArray;
}
}
}
return Enumerable.Empty<ModelValidationResult>();
}
}
}
그런 다음 사용했습니다.
ModelValidatorProviders.Providers.Add(new DataErrorInfoModelPropertyValidatorProvider());
그리고 그것은 작동합니다 :) 이것은 단지 임시 솔루션입니다. 최종 MVC 2에서 수정해야합니다.
편집하다
나도 바뀌었다 if (base.Metadata.Model != null)
if (container! = null)로 Validate()
의 방법 DataErrorInfoPropertyModelValidator
.
다른 팁
확실히 MVC 2 미리보기 2. DefaultModelBinder.OnPropertyValidating
그리고 OnModelUpdated
.
제휴하지 않습니다 StackOverflow