为 ModelState 字典生成键

Generate the keys for the ModelState dictionary

据我了解 .NET Core 中的 ModelState returns 这样的结构:

{
  "Field1": [ "error1", "error2" ],
  "Field2.NestedField": [ "error1", "error2 ],
  "CollectionField[3]": [ "error1", "error2"]
}

现在,如果我在控制器中进行一些额外的自定义验证(例如,数据库查询是否存在 id 引用的实体),我需要将键设置为字符串。

我就是想不通如何构建获取这些格式的密钥。 这种格式有名称吗?

使用 name of 确实只给出字段的名称而不是父字段。

是否有生成这些名称的简单方法?

Using name of does give only the name of the field but not the parent fields.

您可以像这样连接 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 return选择的成员链,没有参数。因此,如果您提供诸如 m => m.EmbeddedObject.Id 之类的表达式,它将 return [ "EmbeddedObject", "Id" ].s 结合时会产生 EmbeddedObject.Id.

GetFullPropertyPath 只是 return 表达式中用 . 字符连接的成员列表。 Here 是一个稍微修改过的在线演示,因为它不允许 is MemberExpression memberExpression 语法。

作为旁注,我还建议尝试 FluentValidation library,尽管它产生的结构验证响应略有不同 - 在我看来比内置属性验证更通用。