2

私のMVCアプリケーションでは、デフォルトのエラーメッセージを使用する代わりに、テキストファイルからエラーメッセージを取得することができます。これは、Required属性(サーバー側とクライアント側の両方)で完全に機能します。

Compare属性で同じことを行う必要がありますが、Compare属性をオーバーライドする方法がわかりません。

参考までに、これは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

上記のErrorMsgs.Textは、テキストファイルからメッセージを取得する関数です。私のモデルに対して、私はこのようなものを適用します...

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

次に、システムはテキストファイルでAccountDetailsPostcodeErrorというエントリを探します。

Compare属性を使用して同じことを実現するにはどうすればよいですか。現時点では、このようなハードコードされたエラーメッセージがあります...

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

編集:以下の推奨される修正はC#では機能する可能性がありますが、VB.NETでは機能しないため、Compare属性をオーバーライドするためのより複雑な要件があります。正しくオーバーライドする方法がわかりません。

4

2 に答える 2

13

翻訳とメッセージにテキストファイルを使用する理由、.NETには翻訳用のオプションが組み込まれています。リソースを使用できます。リソースを使用する利点は、リソースがタイプセーフであり、コンパイル時にチェックされることです。テキストファイルが破損/欠落する可能性がある場所。

次のガイドは、Mvcプロジェクトでリソースを設定するのに役立ちます。

第一歩

デフォルトのアセンブリ言語を編集します。

  • (C#)プロパティ>アセンブリ情報>ニュートラル言語
  • (VB)私のプロジェクト>アセンブリ情報>中立言語

この言語をデフォルトの言語に設定します。(この例では、を使用しますEnglish (United States)

ステップ2

プロジェクトにリソースファイルを追加します。このファイルを呼び出しますResource.resx。このファイルを開きます。アクセス修飾子をに変更し、Publicリソース文字列の追加を開始します。例えば: デフォルトの英語リソース

ステップ3

別のリソースファイルをサポートする言語を互いに追加しますがResource.LANGUAGE.resx、LANGUAGEが他のカルチャ名に置き換えられている場所に名前を付けます。カルチャ名については、次のURLを確認できます:http://msdn.microsoft.com/en-us/goglobal/bb896001.aspx

次に、新しいリソースファイルにローカライズされた文字列を入力します。例えば: 英語リソース

ステップ4

次に、モデルで属性のデフォルトのローカリゼーションサポートを使用できます。

例えば:

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#

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;
}

ローカリゼーションの場合、属性は静的プロパティの名前と、プロパティを取得する静的クラスのタイプを知っている必要があります(上記を参照)。

ステップ5

次に、ビューでを使用し@Html.ValidationSummary()てすべてのエラーメッセージを取得するか、を使用します

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

特定のエラーメッセージを取得します。

表示属性には、次のものを使用できます。

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

言語の変更

最後になりましたが、ステップ1で定義した中立言語の代わりに、を編集しWeb.configてグローバリゼーションタグを次のように変更することで、アプリの言語を変更できます。


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

コードから言語を変更したい場合は、System.Threading.Thread.CurrentThread.CurrentUICultureこれに関する情報を編集する必要があります。グーグルまたは別のSOの質問をお勧めします。


サンプルプロジェクト

この質問に対して、私はすぐにサンプルプロジェクトを作成して、正確な答えを提供しました。プロジェクトはここで見つけることができます:
MvcVBTest.V1.zip


アップデート

リソースを使用せずに単一のテキストファイルを使用する場合は、リソースフレームワークが使用するのと同じ概念を使用できます。参照できる静的プロパティを持つクラスが必要です。

この目的のために、私は次のことをしました:

  1. Resources(Resources.vb) というクラスを作成しました。
  2. このクラスでは、というサブクラスを追加しましたResource
  3. このクラスの静的コンストラクターで、次resource.xmlの配列にマップしたものを開きます。Resource
  4. 次に、この配列はに変換されますDictionary(Of String, String)
  5. xml内のすべてのアイテムに対して静的なgetプロパティを作成しました。そして辞書から正しいアイテムを返しました
  6. クラスのResourceTypeパラメータを変更しましたUserModel

そしてもちろん、少しクリーンアップします。古いリソースを削除したり、globalizationタグをから削除したりできますweb.config

resource.xmlこれで、すべてのテキストがキーと値のペアとして見つかります。別の行を追加するには、それをXMLに追加し、Resourceクラス内にその行のプロパティを作成します。

サンプルプロジェクト

この更新では、サンプルプロジェクトを更新しました:
MvcVBTest.V2.zip

于 2012-11-23T12:20:22.237 に答える
0

このようなものを使ってみませんか?

<RequiredField(ErrorMessage=GetErrorMessage())>

エラーメッセージを受け取る静的関数を作成するだけです。GetErrorMessage関数のパラメーターを取得して、返すメッセージを決定することもできます。

于 2012-11-19T12:54:54.570 に答える