2013-02-06 5 views
7

私のViewModel内のプロパティにMAXLENGTHを設定していないStringLengthのここでテキストボックス

@Html.EditorFor(model => model.Extension) 

そして、それはレンダリング:

<input class="text-box single-line" data-val="true" data-val-length="The field Ext. must be a string with a maximum length of 6." data-val-length-max="6" id="Extension" name="Extension" type="text" value="" /> 

万一、これをテキストボックスにmaxlength属性を設定していますか?そうでない場合は、DataAttributesでどうすればいいですか?

+0

6文字以上の文字列を送信できるかどうか確認しましたか? –

+0

検証エラーが出ますが、実際にmaxlength属性を設定します。 –

+0

'TextBoxFor'に変更すると、HTMLオプションを渡すことができます。 –

答えて

4

私は 可能な場合は、これを制御するためのViewModelに設定された属性をしたいと思います。

ASP.NET MVCは、これを行うための拡張可能なシステムを提供します。あなたが何をする必要があるのです:

  1. カスタムModelMetadataProviderを実装します。
  2. StringLengthAttributeまたはMaxLengthAttributeを探して、情報を抽出してModelMetadataに追加します。
  3. 情報を使用するカスタムのエディタテンプレートを提供します。

ステップ1:カスタムModelMetadataProviderを実装します。

ModelMetadataProviderから派生するクラスを作成します。通常はDataAnnotationsModelMetadataProviderから派生します。これはデフォルトの機能をいくつか提供します。つまり、CreateMetadataという1つのメソッドをオーバーライドするだけです。

ステップ2:情報を抽出します。

情報を取得するには、属性を探し、最大の長さの情報を抽出し、ModelMetadataAdditionalValues辞書に追加する必要があります。 ASP.NET MVCはあなたがGlobal.asaxApplication_Start方法でそれを登録する必要があり、これを使用するためには

public class CustomModelMetadataProvider : DataAnnotationsModelMetadataProvider 
{ 
    protected override ModelMetadata CreateMetadata(
     IEnumerable<Attribute> attributes, 
     Type containerType, 
     Func<object> modelAccessor, 
     Type modelType, 
     string propertyName) 
    { 
     // Call the base class implementation to create the default metadata... 
     var metadata = base.CreateMetadata(
      attributes, 
      containerType, 
      modelAccessor, 
      modelType, 
      propertyName); 

     // Extract the stringLengthAttribute (you can do the same for the 
     // MaxLengthAttribute if you want). 
     var attr = attributes 
      .OfType<StringLengthAttribute>() 
      .First(); 

     // This could be getting called on a property that doesn't have the 
     // attribute so make sure you check for null! 
     if (attr != null) 
     { 
      metadata.AdditionalValues["maxLength"] = attr.MaximumLength; 
     } 

     return metadata; 
    } 
} 

:実装は、この(これは全体の実装である)のようになります。

ModelMetadataProviders.Current = new CustomModelMetadataProvider(); 

ステップ3:カスタムエディタのテンプレートを作成します。

この情報を使用するビューを作成する必要があります。 Views\Shared\フォルダにStringという新しいビューを作成します。

String.cshtml

@{ 
    object maxLength; 
    if (!ViewData.ModelMetadata.AdditionalValues 
      .TryGetValue("maxLength", out maxLength)) 
    { 
     maxLength = 0; 
    } 

    var attributes = new RouteValueDictionary 
    { 
     {"class", "text-box single-line"}, 
     { "maxlength", (int)maxLength }, 
    }; 
} 

@Html.TextBox("", ViewContext.ViewData.TemplateInfo.FormattedModelValue, attributes) 

アプリケーションを実行すると、あなたが@Html.EditorForを呼び出して、次のHTML出力を取得します。

<input class="text-box single-line" id="Extension" maxlength="6" name="Extension" type="text" value="" /> 

あなたはそれがどのように動作するか、Brad Wilson has a series of blog postsその詳細をモデルメタデータ提供システムについての詳細をお知りになりたい場合は(これらは前にカミソリ・ビュー・エンジンに書き込まれたので、ビューの構文の一部は少しファンキーであるが、それ以外の情報音である)。

私は、拙速な解決策だったここで、似たように走った
+0

ベンジャミン、あなたは今日のマシンです! –

+0

問題はありません。うれしく思っています。 –

2

:あなたの.cshtmlファイルの先頭に

は、行を追加します。あなたのhtmlのそれ以下

@{ 
var max = ((System.ComponentModel.DataAnnotations.StringLengthAttribute)(typeof(MyType)) 
.GetProperty("MyProp") 
.GetCustomAttributes(typeof(System.ComponentModel.DataAnnotations.StringLengthAttribute), true)[0]).MaximumLength;  
} 

をしてEditorForを置き換えます:

@Html.TextBoxFor(model => model.Extension, htmlAttributes: new {maxlength=max }) 

私は最終的に私はむしろちょうどスクリプトでそれを行うだろうと決めた。

<script> 
    $(function() 
    { 
     var max = $("#myinput").attr("data-val-length-max"); 
     $("#myinput").attr("maxlength", max); 
    }); 
</script> 

スクリプトを追加したくない場合は、最初の例で動作するはずです。あなたは反射のものを使用してカミソリの見解を汚染しないように、ラムダ構文を使用してHTMLヘルパーの延長に包まれたブラッドの回答に基づいて

+0

このコードは機能しますが、Razorビューをヘルパーのようなものを使用してきれいに保つことができます。私の答えはその例を参照してください。 – djule5

4

基本的には、:

using System; 
using System.ComponentModel.DataAnnotations; 
using System.Linq; 
using System.Linq.Expressions; 
using System.Reflection; 
using System.Web.Mvc; 

public static class HtmlHelper 
{ 
    public static int? MaxLength<TModel, TProperty>(
     this HtmlHelper<TModel> htmlHelper, 
     Expression<Func<TModel, TProperty>> expression) 
    { 
     MemberExpression memberExpression = (MemberExpression)expression.Body; 

     PropertyInfo property = typeof(TModel) 
      .GetProperty(memberExpression.Member.Name); 

     StringLengthAttribute attribute = (StringLengthAttribute)property 
      .GetCustomAttributes(typeof(StringLengthAttribute), true) 
      .FirstOrDefault(); 

     if (attribute != null) 
     { 
      return attribute.MaximumLength; 
     } 

     return null; 
    } 
} 

は、このようなようにそれを使用します。

@Html.TextBoxFor(x => x.Name, new { maxlength = Html.MaxLength(x => x.Name) }) 

ここで、xはあなたのモデルを指します。

StringLengthAttributeがプロパティに対して宣言されていない場合、nullが返され、maxlength属性がtextbox要素で空になります。

方法にアクセスできるように、あなたのカミソリのページでの使用を忘れないでください。

@using HtmlHelper 

また、コンパイルエラーを解決する方法では、null以外の結果を使用する必要があります。

関連する問題