生成ModelState字典的密钥

时间:2018-11-27 07:46:01

标签: asp.net asp.net-core .net-core asp.net-core-2.1 .net-core-2.1

据我了解,.NET Core中的ModelState返回这样的结构:

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

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

我只是不知道如何构建获取这些格式的密钥。 这种格式有名称吗?

使用名称确实会给出字段名称,而不会给出父字段。

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

1 个答案:

答案 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,尽管它生成的结构化验证响应稍有不同,但我认为它比内置的属性验证功能要多得多。