Asp.net mvc 在GetClientValidationRules中查找复杂对象的属性值
有一个复杂的视图模型需要在客户端上进行验证。简化:Asp.net mvc 在GetClientValidationRules中查找复杂对象的属性值,asp.net-mvc,asp.net-mvc-4,Asp.net Mvc,Asp.net Mvc 4,有一个复杂的视图模型需要在客户端上进行验证。简化: public class Survey { public List<Question> Questions { get; set; } } public class Question { public List<Answer> Answers { get; set; } } public class Answer { public string FieldName { get; set; } [Re
public class Survey
{
public List<Question> Questions { get; set; }
}
public class Question
{
public List<Answer> Answers { get; set; }
}
public class Answer
{
public string FieldName { get; set; }
[Required("Please use a number")]
public int Number { get; set; }
}
但是,在GetClientValidationRules
方法中,metadata.Model为null
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(
ModelMetadata metadata,
ControllerContext context)
{
// metadata.Model is null here!
ModelMetadata answerFieldNameValue = ModelMetadataProviders.Current
.GetMetadataForProperties(
metadata.Model,
metadata.ContainerType)
.FirstOrDefault(p => p.PropertyName == "FieldName");
// and, therefore, answerFieldNameValue.Model is null too!
}
public IEnumerable GetClientValidationRules(
模型元数据,
ControllerContext(上下文)
{
//metadata.Model在此为空!
ModelMetadata answerFieldNameValue=ModelMetadataProviders.Current
.GetMetadataForProperties(
元数据。模型,
metadata.ContainerType)
.FirstOrDefault(p=>p.PropertyName==“FieldName”);
//因此,answerFieldNameValue.Model也为空!
}
如果我返回此方法的第一行,并从上下文.Controller.ViewData.Model
获取任何答案
,并将其分配给元数据.Model
,则答案字段名value.Model
将包含正确的字符串,即答案的字段名
如何使此metadata.Model在到达此处时具有适当的值?或者用其他方法来解决这个问题?明白了。下面的代码是我的解决方案,灵感来自 公共类CustomModelMetadataProvider:DataAnnotationsModelMetadataProvider { 私有对象标签; 受保护的重写ModelMetadata CreateMatadata(IEnumerable属性、类型containerType、Func modelAccessor、类型modelType、字符串propertyName) { ModelMetadata ModelMetadata=base.CreateMetadata(属性、containerType、modelAccessor、modelType、propertyName); 对象模型=null; if(modelacessor!=null) { model=modelacessor(); } if(typeof(SurveyQuestionVM).IsAssignableFrom(containerType)&&propertyName==“TreeViewLabel”) { lastQuestionLabel=模型; } if(类型为(调查和SWERVM).IsAssignableFrom(容器类型)) { modelMetadata.AdditionalValues.Add(“问题标签”,lastQuestionLabel); } 返回模型元数据; } }
看看这个主题,它根据模型状态(与您的主要关注点相关)执行一些条件验证。模型是从context.Controller.ViewData.model中提取的。fieldname值应该是
(String)model.GetType().GetProperty(“fieldname”).GetValue(model,null)
是的,我可以理解@joelmdev做了什么,但这不符合这个问题的目的,因为问题在数据库中,应该有一个答案作为上下文,它是属性所在的对象。你能发布完整的模型和完整的CustomRequiredAttribute类的代码吗?它有点大,如果你需要的话,我可以通过skype发送。嗨@Bomboca,我也有同样的问题。能否分享一下你对这个问题的解决方案?非常感谢SurveyQuestionVM
和SurveyAnswerVM
。你能添加它们的定义吗?
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(
ModelMetadata metadata,
ControllerContext context)
{
// metadata.Model is null here!
ModelMetadata answerFieldNameValue = ModelMetadataProviders.Current
.GetMetadataForProperties(
metadata.Model,
metadata.ContainerType)
.FirstOrDefault(p => p.PropertyName == "FieldName");
// and, therefore, answerFieldNameValue.Model is null too!
}
public class CustomModelMetadataProvider : DataAnnotationsModelMetadataProvider
{
private object lastQuestionLabel;
protected override ModelMetadata CreateMetadata(IEnumerable<Attribute> attributes, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName)
{
ModelMetadata modelMetadata = base.CreateMetadata(attributes, containerType, modelAccessor, modelType, propertyName);
object model = null;
if (modelAccessor != null)
{
model = modelAccessor();
}
if (typeof(SurveyQuestionVM).IsAssignableFrom(containerType) && propertyName == "TreeViewLabel")
{
lastQuestionLabel = model;
}
if (typeof(SurveyAnswerVM).IsAssignableFrom(containerType))
{
modelMetadata.AdditionalValues.Add("QuestionLabel", lastQuestionLabel);
}
return modelMetadata;
}
}