【问题标题】:Get the "Key" for a strongly typed model in the controller在控制器中获取强类型模型的“密钥”
【发布时间】:2012-08-17 17:37:20
【问题描述】:

所以我正在尝试在控制器中获取模型对象的密钥,以便可以向其中添加 AddModelError

在我看来,我使用

@Html.ValidationMessageFor(model => model.Email)

获取Key 名称以添加到控制器中的等效代码是什么,以便它附加到此ValidationMessage。

【问题讨论】:

    标签: c# asp.net-mvc


    【解决方案1】:

    您可以使用与 HtmlHelpers 功能相同的扩展,并且适用于嵌套属性:

    public static class ModelStateExtensions
    {
      public static void AddModelError<TModel>(this ModelStateDictionary dictionary, Expression<Func<TModel, object>> expression, string errorMessage)
      {
        dictionary.AddModelError(ExpressionHelper.GetExpressionText(expression), errorMessage);
      }
    }
    

    所以你可以这样使用它:

    ModelState.AddModelError<TModel>(i => i.Person.Name, "test");
    

    相当于

    ModelState.AddModelError("Person.Name", "test");
    

    它将生成与 Html 相同的 Id。在 MVC 源代码中,他们做了一些额外的清理工作,但使用正常的名称应该不成问题。

    【讨论】:

    • 刚刚使用这个遇到了错误。如果属性是结构,则表达式看起来像 Convert(property) 因为表达式返回一个对象。在这种情况下,表达式文本的计算结果为空字符串。我建议将函数更改为 public static void AddModelError(this ModelStateDictionary dictionary, Expression> expression, string errorMessage) 并像 ModelState.AddModelError((TModel i) => i 一样调用它。 Person.Name,“测试”)
    【解决方案2】:
    ModelState.AddModelError("Email", "the email is invalid");
    

    但通常这不是您应该在控制器中手动执行的操作,但您应该使用验证器。例如,您可以使用一些验证数据注释属性来装饰此 Email 属性,或者如果您像我一样使用 FluentValidation.NET => 这样您不应该问自己有关键的问题,而是专注于实际的验证逻辑。

    【讨论】:

    • 钥匙永远是名字吗?我认为这是生成的,所以并不总是保证是对象名称?
    • 总是等于字段名。请小心,因为如果您重命名该字段(即使使用 ReSharper),它也不会更新此字符串,因为它们只是巧合匹配。幸运的是,我相信使用未知键不会产生任何不利影响(比如让你的页面抛出异常),它相当于使用null
    猜你喜欢
    • 1970-01-01
    • 2015-08-16
    • 2013-10-14
    • 1970-01-01
    • 1970-01-01
    • 2021-01-14
    • 1970-01-01
    • 1970-01-01
    • 2012-04-09
    相关资源
    最近更新 更多