7

私は MVC4 で作業しており、Uppercase属性を使用してモデルを定義したいと考えています。Uppercase 属性が存在すると、モデル値がサーバーに到着したときに大文字に変換されるという考えです。

現時点では、モデル内に次のコードがあります。

    [Required]
    [Display(Name="Account Code")]
    [StringValidation(RegExValidation.AccountCode, Uppercase=true)]
    public string Account
    {
        get { return _account; }
        set
        {
            if (value != null)
                _account = value.ToUpper();
        }
    }

しかし、私が本当に欲しいのはこれです:

    [Required]
    [Display(Name="Account Code")]
    [StringValidation(RegExValidation.AccountCode)]
    [Uppercase]
    public string Account { get; set; }

ValidationAttributeモデルがサーバーにヒットしたときに確実に起動されるように、Uppercase 属性を として作成する必要があると思います。しかし、私は実際にデータを検証していないので、それは少し間違っているようです. より良い方法はありますか?

また、属性の呼び出し順序を保証する方法はありますか? StringValidationカスタム属性が起動する前に、データを大文字に変換したいと本当に思っています。これは、正規表現パターンのテキストの大文字と小文字をチェックするためです。

これに少し背景を追加するために、データを大文字にするコードを追加する必要性を減らしたいと思います。涅槃は、モデル バインディングまたは検証段階のいずれかで、サーバーへの途中でデータを更新する単一の属性になります。次に、この属性を属性で参照してStringValidation、そのチェックで使用される RegEx 値を修正できます。また、カスタムTextBoxForヘルパー メソッドでこの属性を検索text-transform: uppercaseして、クライアント側で正しく表示されるように追加することもできます。

誰かがそこに何かアイデアを持っていますか?

4

4 に答える 4

5

私はこれをある程度まで機能させることができたので、他の人が評価するための私の解決策を次に示します。

注目すべき点は、属性のModelmetadata内部を取得できなかったため、完全な解決策を達成できなかったことです。StringValidation.IsValid()ここで私が抱えていた特定の問題は、メタデータを取得できたが、PropertyNameそこからDisplayName. そこには複数のオプションがありましたが、私のプロパティのいくつかに同じものがあるという事実は、それが私が実際に検証していたものDisplayNameであるかどうか確信が持てなかったことを意味します.ProprtyName

のコードは次のValidationAttributeとおりです。

public class StringValidationAttribute : ValidationAttribute, IClientValidatable, IMetadataAware {

    private bool _uppercase;

    public StringValidationAttribute(bool uppercase = false) {
         _uppercase = uppercase;
    }

    ...

    public void OnMetadataCreated(ModelMetadata metadata)
    {
        metadata.AdditionalValues["Uppercase"] = _uppercase;
    }
}

次に、新しいIModelBinder実装を作成しました。

public class StringBinder : IModelBinder
{
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {           
        ValueProviderResult result = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);

        if (result == null)
            return null;

        if (bindingContext.ModelMetadata.AdditionalValues.ContainsKey("Uppercase")) {
            if ((bool)bindingContext.ModelMetadata.AdditionalValues["Uppercase"]])
                return result.AttemptedValue.ToUpper();
        }

        return result.AttemptedValue;
    }
}

そしてそれを私のGlobal.asaxファイルに登録しました:

ModelBinders.Binders.Add(typeof(string), new StringBinder());

これまでのコードでは、MVC に入力された文字列入力はStringValidationAttribute、モデルにアタッチされていて、大文字インジケーターが設定されている場合、大文字に変換されます。

次に、html フォームも大文字にしたいという私の願望を実現するために、新しいEditorTemplate名前付きを実装しましたstring.cshtml。このビューで、次を追加しました。

RouteValueDictionary htmlAttributes = new RouteValueDictionary();
if ((bool)ViewData.ModelMetadata.AdditionalValues["Uppercase"]) {
    htmlAttributes.Add("class", "Uppercase");
}
@Html.TextBox("", Model, htmlAttributes)

CSSを次のように使用します。

.Uppercase {
    text-transform: uppercase;
}

この投稿が他の人に役立つことを願っています。

于 2013-07-24T16:48:04.253 に答える
0

注: 現在使用しているアプローチを発見するまで、これを読んで上記のすべてを試してみたが失敗したため、この投稿に追加しています。

テキスト データを強制的に大文字にフォーマットする場合、通常は 2 つのプロセスを使用します。1. ビューで 2. コントローラーで

  1. ビューレイヤーで、ユーザーがデータが大文字形式で使用されることを認識できるようにします。これは、EditorFor HTML ヘルパーで使用される htmlAttributes によってダウンすることができます。

    @HTML.EditorFor(model => model.Access_Code, new { htmlAttributes = new  Style= "text-transform:uppercase"}})
    

これにより、ユーザーが表示および入力したデータのみが大文字になり、サーバーに送信されるデータは強制されません。これを行うには、コントローラーの関連するメソッドにコードが必要です。

  1. コントローラーに戻されるオブジェクトのターゲット属性に ToUpper() メソッドを追加します。これを示す架空の例を次に示します。

    public ActionResult verify(int? id)
          {
            var userData = db.user.Where (i=> i.userID == id).Single();
    
            userData.Access_Code = userData.Access_Code.ToUpper();
    
       ...
     }
    
于 2015-11-13T20:12:02.843 に答える