vb.net MVC - 更改比较属性错误消息

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13453089/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-17 11:13:00  来源:igfitidea点击:

MVC - Change Compare attribute error message

asp.net-mvcvb.net

提问by cw_dev

In my MVC application I have the ability to get the error message from a text file instead of using the default error message. This works perfectly on the Required attribute (both Serverside and Clientside).

在我的 MVC 应用程序中,我能够从文本文件中获取错误消息,而不是使用默认错误消息。这在 Required 属性(服务器端和客户端)上非常有效。

I now need to do the same with the Compareattribute, but I can't figure out how to override the Compare attribute.

我现在需要对Compare属性做同样的事情,但我不知道如何覆盖 Compare 属性。

For reference, this is how I am doing it with the Required attribute (I would like similar code to this to work with the Compareattribute)...

作为参考,这就是我使用 Required 属性的方式(我希望与此类似的代码与Compare属性一起使用)...

Public Class RequiredFieldAttribute
    Inherits ValidationAttribute
    Implements IClientValidatable

    Private innerAttribute As New RequiredAttribute()
    Private errormessagecontrolid As String

    Public Sub New(ErrorMessageControlID As String)

        Me.errormessagecontrolid = ErrorMessageControlID

    End Sub

    Protected Overrides Function IsValid(value As Object, validationContext As ValidationContext) As ValidationResult

        If Not innerAttribute.IsValid(value) Then
            Return New ValidationResult(ErrorMsgs.Text(Me.errormessagecontrolid))
        End If

        Return ValidationResult.Success

    End Function

    Public Function GetClientValidationRules(metadata As ModelMetadata, context As ControllerContext) As IEnumerable(Of ModelClientValidationRule) Implements IClientValidatable.GetClientValidationRules

        Dim result = New List(Of ModelClientValidationRule)

        Dim rule = New ModelClientValidationRule() With {.ErrorMessage = ErrorMsgs.Text(Me.errormessagecontrolid), .ValidationType = "required"}

        result.Add(rule)

        Return result

    End Function

End Class

Above, ErrorMsgs.Text is the function that retieves the message from the text file. Against my model I then apply something like this...

上面,ErrorMsgs.Text 是从文本文件中检索消息的函数。针对我的模型,我然后应用这样的东西......

<RequiredField("AccountDetailsPostcodeError")>
Public Property PostCode As String

The system then looks in the Text file for an entry called AccountDetailsPostcodeError.

然后系统在文本文件中查找名为 AccountDetailsPostcodeError 的条目。

How can I achieve the same with the Compare attribute. At the moment I have a hard coded error message like this...

如何使用比较属性实现相同的效果。目前我有一个像这样的硬编码错误消息......

    <Compare("WebPassword", ErrorMessage:="The password and confirmation do not match.")>
    Public Property ConfirmWebPassword As String

Edit: The suggested fix below may work in C#, but won't work in VB.NET, hence my more complex requirement to override the Compare attribute. I just don't know how to correctly override it.

编辑:下面建议的修复程序可能适用于 C#,但不适用于 VB.NET,因此我需要更复杂的覆盖比较属性。我只是不知道如何正确覆盖它。

回答by SynerCoder

Why use a text file for your translations and messages, .NET has build in options for translations. You can use resources. The advantage of using resources is that resources are type safe, they are checked as compile time. Where your textfile can become corrupt / missing.

为什么要使用文本文件进行翻译和消息,.NET 已内置翻译选项。您可以使用资源。使用资源的好处是资源是类型安全的,它们在编译时被检查。您的文本文件可能损坏/丢失的地方。

The following guide helps you with setting up resources in a Mvc project:

以下指南可帮助您在 Mvc 项目中设置资源:

Step one

步骤1

Edit the default assembly language:

编辑默认汇编语言:

  • (C#) Properties > Assembly information > Neutral Language
  • (VB) My Project > Assembly information > Neutral Language
  • (C#) 属性 > 程序集信息 > 中性语言
  • (VB) 我的项目 > 汇编信息 > 中性语言

Set this language to your default language. (For this example I use English (United States))

将此语言设置为您的默认语言。(对于这个例子,我使用English (United States)

Step two

第二步

Add a resource file to your project. Call this file Resource.resx. Open this file. Change the Access Modifier to Publicand start adding resource strings. For example: Default English resources

将资源文件添加到您的项目中。调用这个文件Resource.resx。打开这个文件。将访问修饰符更改为Public并开始添加资源字符串。例如: 默认英文资源

Step three

第三步

Add for each other language you want to support another resource file but name them Resource.LANGUAGE.resxwhere LANGUAGE is replaced by the other culture name. For culture names you can check this url: http://msdn.microsoft.com/en-us/goglobal/bb896001.aspx

添加您想要支持另一个资源文件的其他语言,但将它们命名为Resource.LANGUAGE.resxLANGUAGE 替换为其他文化名称的地方。对于文化名称,您可以查看此网址:http: //msdn.microsoft.com/en-us/goglobal/bb896001.aspx

Then fill the new resource file with the localized strings. For example: English Resources

然后用本地化的字符串填充新的资源文件。例如: 英语资源

Step four

第四步

Then you can in your Models use the default localization support of the attributes:

然后你可以在你的模型中使用属性的默认本地化支持:

For example:

例如:

VB:

VB:

Imports System.ComponentModel.DataAnnotations
Public Class UserModel
    <Display(Name:="UserNameField", ResourceType:=GetType(My.Resources.Resource))>
    <Required(AllowEmptyStrings:=False, ErrorMessageResourceName:="RequiredUsername", ErrorMessageResourceType:=GetType(My.Resources.Resource))>
    Public Property UserName As String

    <Display(Name:="PasswordField", ResourceType:=GetType(My.Resources.Resource))>
    <MinLength(6, ErrorMessageResourceName:="PasswordLengthError", ErrorMessageResourceType:=GetType(My.Resources.Resource))>
    <Compare("PasswordAgain", ErrorMessageResourceName:="CompareError", ErrorMessageResourceType:=GetType(My.Resources.Resource))>
    <Required(AllowEmptyStrings:=False, ErrorMessageResourceName:="RequiredPassword", ErrorMessageResourceType:=GetType(My.Resources.Resource))>
    Public Property Password As String

    <Display(Name:="PasswordAgainField", ResourceType:=GetType(My.Resources.Resource))>
    <Required(AllowEmptyStrings:=False, ErrorMessageResourceName:="RequiredPasswordAgain", ErrorMessageResourceType:=GetType(My.Resources.Resource))>
    Public Property PasswordAgain As String
End Class

C#

C#

using System.ComponentModel.DataAnnotations;
public class UserModel
{
    [Display(Name = "UserNameField", ResourceType = typeof(My.Resources.Resource))]
    [Required(AllowEmptyStrings = False, ErrorMessageResourceName = "RequiredUsername", ErrorMessageResourceType = typeof(My.Resources.Resource))]
    public string UserName;

    [Display(Name = "PasswordField", ResourceType = typeof(My.Resources.Resource))]
    [MinLength(6, ErrorMessageResourceName = "PasswordLengthError", ErrorMessageResourceType = typeof(My.Resources.Resource))]
    [Compare("PasswordAgain", ErrorMessageResourceName = "CompareError", ErrorMessageResourceType = typeof(My.Resources.Resource))]
    [Required(AllowEmptyStrings = False, ErrorMessageResourceName = "RequiredPassword", ErrorMessageResourceType = typeof(My.Resources.Resource))]
    public string Password;

    [Display(Name = "PasswordAgainField", ResourceType = typeof(My.Resources.Resource))]
    [Required(AllowEmptyStrings = False, ErrorMessageResourceName = "RequiredPasswordAgain", ErrorMessageResourceType = typeof(My.Resources.Resource))]
    public string PasswordAgain;
}

For localization the attribute needs to know the name of the static property and the type of the static class where to get the property from (as seen above).

对于本地化,属性需要知道静态属性的名称和从何处获取属性的静态类的类型(如上所示)。

Step five

第五步

Then in your view use the @Html.ValidationSummary()to get all the error messages, or use

然后在您的视图中使用@Html.ValidationSummary()获取所有错误消息,或使用

  • VB@Html.ValidationMessageFor(Function(model) model.Property)
  • C#@Html.ValidationMessageFor(m => m.Property)
  • VB@Html.ValidationMessageFor(Function(model) model.Property)
  • C#@Html.ValidationMessageFor(m => m.Property)

to get specific error messages.

获取特定的错误消息。

For the display attribute you can use:

对于显示属性,您可以使用:

  • VB@Html.DisplayNameFor(Function(model) model.Property)
  • C#@Html.DisplayNameFor(m => m.Property)
  • VB@Html.DisplayNameFor(Function(model) model.Property)
  • C#@Html.DisplayNameFor(m => m.Property)


Changing the language

更改语言

And last but not least you can change the language of your app instead of your neutral language defined in step one by editing the Web.configand changing the globalization tag like so:

最后但并非最不重要的一点是,您可以通过编辑Web.config和更改全球化标签来更改应用程序的语言,而不是第一步中定义的中性语言,如下所示:


<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.web>
    <globalization uiCulture="nl" />
  </system.web>
</configuration>

If you want to change the language from code you should edit System.Threading.Thread.CurrentThread.CurrentUICulturefor information about this I suggest google or another SO question.

如果您想从代码中更改语言,您应该编辑System.Threading.Thread.CurrentThread.CurrentUICulture有关此的信息,我建议使用 google 或其他 SO 问题。



Example project

示例项目

For this question I quickly made an example project to provide an accurate answer. Project can be found here:
MvcVBTest.V1.zip

对于这个问题,我很快做了一个示例项目来提供准确的答案。项目可以在这里找到:
MvcVBTest.V1.zip



UPDATE

更新

If you don't want to use Resources but a single text file you can use the same concept the resource framework uses. You need a class that has static properties you can reference.

如果您不想使用资源而是使用单个文本文件,您可以使用资源框架使用的相同概念。您需要一个具有可以引用的静态属性的类。

For this purpose I did the following things:

为此,我做了以下几件事:

  1. I created a class called Resources(Resources.vb).
  2. In this class I added a sub class called Resource
  3. In the static constructor of this class I open resource.xmlwhich I have mapped to an array of Resource
  4. This array is then converted to an Dictionary(Of String, String)
  5. I created an static get property for every item in the xml. And returned the right item from the Dictionary
  6. I changed the ResourceTypeparameter in the UserModelclass
  1. 我创建了一个名为Resources(Resources.vb)的类。
  2. 在这个类中,我添加了一个名为的子类 Resource
  3. 在这个类的静态构造函数中,我打开resource.xml它映射到一个数组Resource
  4. 然后将该数组转换为 Dictionary(Of String, String)
  5. 我为 xml 中的每个项目创建了一个静态 get 属性。并从字典中返回正确的项目
  6. 我改变ResourceTypeUserModel类中的参数

And of course a little clean up. The old resources can be deleted and the globalizationtag can be removed from the web.config.

当然还有一点清理。可以删除旧资源,并且globalization可以从web.config.

Now all the text can be found in resource.xmlas key value pairs. To add another line, add it to the XML and create a property for it in the Resourceclass.

现在所有的文本都可以resource.xml作为键值对找到。要添加另一行,请将其添加到 XML 并在Resource类中为其创建属性。

Example project

示例项目

For this update I updated my example project:
MvcVBTest.V2.zip

对于此更新,我更新了我的示例项目:
MvcVBTest.V2.zip

回答by middelpat

Why not use something like this?

为什么不使用这样的东西?

<RequiredField(ErrorMessage=GetErrorMessage())>

Just create a static function that gets the error message for you. You can even take a parameter for your GetErrorMessage function so you can determine which message you'll want to return.

只需创建一个静态函数即可为您获取错误消息。您甚至可以为 GetErrorMessage 函数获取一个参数,以便您可以确定要返回的消息。