【问题标题】:ASP.NET MVC Model Validation Error Localization ContextASP.NET MVC 模型验证错误本地化上下文
【发布时间】:2013-02-21 13:37:46
【问题描述】:

首先,我必须说我了解基于数据注释的模型验证在 ASP.NET MVC4 中是如何工作的,并且我已经使用DataAnnotationsModelValidatorProvider 成功实现了它。所以我不需要帮助来设置它。

但是当涉及到HtmlHelpers 时,我正在努力尝试找出错误消息的上下文。通过说context,我的意思是我们正在谈论哪个错误。哪个属性返回了错误?

我能得到的是错误的Key 和当前的ErrorMessage,但至少我知道,没有任何东西可以传达我们正在谈论的错误。无论是Required 属性还是其他属性,我都找不到如何区分它们的方法。

让我们稍微打开场景。我有自定义 HtmlHelpers 来渲染 ContentEditable 元素。例如Html.ContentEditableValidationMessageFor(m => m.firstName);。它会输出如下内容:

<span contenteditable="true" data-valmsg-for="firstName" data-valmsg-replace="Please provide first name" class="field-validation-error">Please provide first name</span>

现在,我确实有一个 jQuery 插件来处理和持久化 contenteditable 元素中的更改,并将它们持久化到后端。但是,UI 没有任何内容可以说明我们正在谈论的错误消息。人类可以很容易地看到它是 RequiredAttribute,但在编程上没有数据可以将它与某些 MinLengthAttribute 区分开来。

在这种情况下,如果我只是使用 data-valmsg-for="firstName" 作为本地化的键,那么对于与同一属性有关的所有错误都会返回相同的错误消息。

四舍五入

ModelState 可用时,为 ModelError 发出唯一 ID 的最佳做法是什么?考虑到我正在使用 ASP.NET MVC4 和 DataAnnotationsModelValidatorProvider

我可以想出很多方法来“一起破解”,但我想使用 ModelState 和 MVC 提供的任何东西。如果这一切都归结为编写自定义ModelValidatorProvider,那么我完全愿意接受。只要它是最好和最可持续的方式。我完全赞成现在做更多,以后做更少,而不是现在破解它并永远破解它以保持它的工作

【问题讨论】:

  • 这对我来说是一个非常有趣的问题。您使用反射进行黑客攻击的基础是什么?和你一样,“你可以通过反射来做到这一点”这句话通常意味着为自己设置的代码不可避免地会维护得很差。会一直关注这个...
  • 你想要客户端还是服务器端的数据?
  • 你有什么进展吗?
  • 我将尽快发布我当前基于反射的实现,因为我们没有得到任何可以被认为是最佳实践的东西。我也在考虑将此作为请求提交给 MVC 团队。

标签: asp.net-mvc data-annotations modelstate asp.net-mvc-validation model-validation


【解决方案1】:

您能否提供一些关于需要知道哪个规则触发了验证错误的背景信息,这可能是您尝试做一些您不应该做的事情的情况吗?

一般来说,出于多种原因,我使用 FluentValidation (http://fluentvalidation.codeplex.com/wikipage?title=mvc) 来代替数据注释验证,包括整理模型、单元测试验证逻辑、允许包括业务逻辑在内的更复杂的验证。如果您可以免费使用 3rd 方库,我会看看它,因为它总是解决我过去遇到的任何验证问题。

它允许您编写通过流畅的 API 处理模型验证的 c# 代码。它有一个 MVC 扩展,可以为您连接一切,因此除了创建模型验证类之外,从那时起几乎没有影响。上面的代码 sn-p 的一个示例是......

RuleFor(modelname => modelname.FirstName).NotEmpty().WithMessage("lease provide first name");

【讨论】:

    【解决方案2】:

    即使实现ModelValidatorProvider 也无济于事,它只是一种基于模型元数据提供ModelValidators 的机制。在调用控制器操作ModelValidators 中的模型绑定过程期间,结果只是ModelValidationResult,其中仅包含MemberName 和文本Message

    我认为通过检查如下错误消息来找出哪个 ModelValidator 失败是一种肮脏的方法:

    var modelErrors = ModelState.Where(m => m.Value.Errors.Count > 0).Select(m => new { Name=m.Key , Errors=m.Value.Errors});
    

    通过检查 modelErrors 中每个键的 ErrorMessage 和 ValidatorProvider 错误消息,您可以找出错误属于哪个 Validator。

    【讨论】:

    • 谢谢。但是我已经通过反射使用了一种肮脏的方式来获取正在验证的 Model 属性的任何 ValidationAttributes。它正在寻找输出与当前填充在 ModelState 中的 errorMessage 相同的属性的 ErrorResourceKey。这样我可以连接属性名称和错误资源键以获得属性错误的唯一键。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-01
    • 1970-01-01
    • 2011-08-27
    • 2015-02-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多