在控制器中,我可以执行数据库查找等,并添加一些与模型属性关联的错误消息:
public ActionResult CreateJob(CreateJobModel viewModel)
{
var call = FindCall(viewModel.CallNumber);
if (call == null)
{
ModelState.AddModelError("CallNumber", "Idiot User!");
}
}
我不喜欢CallNumber是一个字符串,理想情况下它应该直接引用viewModel.CallNumber,如果我更改了该属性的名称,它也应该被更改。
我如何实现这一目标?
我认为代码最终会出现这样的情况,它会采用属性访问表达式:
AddModelFieldError(() => viewModel.CallNumber, "Idiot User!");
但是我不确定如何创建这样的方法,或者在需要错误消息的子/内部属性的情况下。
答案 0 :(得分:7)
我会编写自己的通用扩展方法:
public static class ModelStateDictionaryHelper
{
public static void AddModelError<TViewModel>(
this ModelStateDictionary me,
Expression<Func<TViewModel, object>> lambdaExpression, string error)
{
me.AddModelError(GetPropertyName(lambdaExpression), error);
}
private static string GetPropertyName(Expression lambdaExpression)
{
IList<string> list = new List<string>();
var e = lambdaExpression;
while (true)
{
switch (e.NodeType)
{
case ExpressionType.Lambda:
e = ((LambdaExpression)e).Body;
break;
case ExpressionType.MemberAccess:
var propertyInfo = ((MemberExpression)e).Member as PropertyInfo;
var prop = propertyInfo != null
? propertyInfo.Name
: null;
list.Add(prop);
var memberExpression = (MemberExpression)e;
if (memberExpression.Expression.NodeType != ExpressionType.Parameter)
{
var parameter = GetParameterExpression(memberExpression.Expression);
if (parameter != null)
{
e = Expression.Lambda(memberExpression.Expression, parameter);
break;
}
}
return string.Join(".", list.Reverse());
default:
return null;
}
}
}
private static ParameterExpression GetParameterExpression(Expression expression)
{
while (expression.NodeType == ExpressionType.MemberAccess)
{
expression = ((MemberExpression)expression).Expression;
}
return expression.NodeType == ExpressionType.Parameter ? (ParameterExpression)expression : null;
}
}
和用法:
ModelState.AddModelError<CreateJobModel>(x => x.CallNumber,
"some kind attention");
它看起来与您询问的版本略有不同,但我希望它可以替代。
答案 1 :(得分:4)
从C#6开始,您可以使用nameof
运算符。
public ActionResult CreateJob(CreateJobModel viewModel)
{
var call = FindCall(viewModel.CallNumber);
if (call == null)
{
ModelState.AddModelError(nameof(CreateJobModel.CallNumber), "Idiot User!");
}
}