据我了解,.NET Core中的ModelState返回这样的结构:
{
"Field1": [ "error1", "error2" ],
"Field2.NestedField": [ "error1", "error2 ],
"CollectionField[3]": [ "error1", "error2"]
}
现在,如果我在控制器中进行其他一些自定义验证(例如,数据库查询是否存在ID引用的实体),则需要将密钥设置为字符串。
我只是不知道如何构建获取这些格式的密钥。 这种格式有名称吗?
使用名称确实会给出字段名称,而不会给出父字段。
是否有一种简单的方法来生成这些名称?
答案 0 :(得分:1)
使用名称确实会给出字段名称,而不会给出父字段。
您可以像这样将nameof
连接起来:
nameof(MyModelType.EmbeddedObject) + "." + nameof(MyModel.EmbeddedObject.Id)
产生EmbeddedObject.Id
的就像nameof
总是产生表达式链的最后一段。只需通过每个表达式更深入地挖掘一个层次来构建字符串。
您也可以编写LINQ表达式帮助器:
public static string GetFullPropertyPath<TModel,TProp>(Expression<Func<TModel,TProp>> expr)
{
return String.Join(".", GetMemberList(expr.Body as MemberExpression));
}
public static List<string> GetMemberList(MemberExpression expression)
{
var result = new List<string>();
if (expression.Expression is MemberExpression memberExpression)
{
result.AddRange(GetMemberList(memberExpression));
}
result.Add(expression.Member.Name);
return result;
}
GetMemberList
返回不带参数的所选成员链。因此,如果您提供诸如m => m.EmbeddedObject.Id
之类的表达式,它将返回[ "EmbeddedObject", "Id" ]
,当与.
结合使用时将产生EmbeddedObject.Id
。
GetFullPropertyPath
仅返回表达式中以.
字符开头的成员列表。 Here是一个在线演示程序,因为它不允许使用is MemberExpression memberExpression
语法。
作为旁注,我还建议尝试使用FluentValidation library,尽管它生成的结构化验证响应稍有不同,但我认为它比内置的属性验证功能要多得多。