ASP.NET MVC 2のデータ表示および編集テンプレート

テンプレートの表示および編集に関する一連の記事の翻訳。



  1. テンプレートの紹介。 ( オリジナル
  2. テンプレートのメタデータ。 ( オリジナル
  3. 組み込みテンプレート。 ( オリジナル
  4. 独自のテンプレートを作成します。 ( オリジナル
  5. マスターテンプレート。 ( オリジナル






パート1 はじめに



テンプレートの紹介



ASP.NET MVCの主な新しい革新の1つはテンプレートです。



テンプレートは、従来のASP.NETのダイナミックデータに似ています。 このタイプの既存のオブジェクトに基づいて、オブジェクトが単純なデータ(整数、10進数、文字列など)であるか、クラス代表であるかにかかわらず、システムはそれを表示または編集するためのマークアップを自動的に生成します。



Html.Display



要素を表示するために、3つの表示メソッドが使用されます(それぞれにいくつかのオーバーロードがあります)。





最初の方法は、ViewDataと、タイプが不明なモデルの両方からのデータを表示するために使用できます。



次の方法は、主にモデルからデータを転送するために使用されます。 さらに、このメソッドを使用して、たとえば、ソースデータの値を完全に無視することができます(モデル=> someOtherValue)。



最後の方法は、現在のモデルのヘルパーです。 DisplayForModelメソッドは、DisplayFor(モデル=>モデル)エントリと同等です。



モデルを使用して例を開始しましょう。



 パブリッククラス
 {
	パブリック文字列FirstName {get; セット;  }
	パブリック文字列LastName {get; セット;  }
	 public int Age {get; セット;  }
 } 


...次にアクション:



  pubilc ViewResultの詳細([DefaultValue(0)] int id)
 {
	戻りビュー([id]に連絡);
 } 


...そして最後に表示:



  <%@ Page Language = "C#"
	 MasterPageFile = "〜/ Views / Shared / Site.master"
	 Inherits = "System.Web.Mvc.ViewPage"%>

 <asp:Content ContentPlaceHolderID = "MainContent" runat = "server">
	 <%= Html.DisplayForModel()%>
 </ asp:コンテンツ> 


その結果、次のページが表示されます。



表示テンプレートの例

Html.editor



Html.Displayと同様に、オブジェクトを編集するためのhtmlを生成するために使用される3つのメソッドがあります。





ビューでDisplayForModelメソッドをEditorForModelに変更すると、ページは次のようになります。



編集テンプレートの例

ご覧のとおり、システムは文字列および整数値用のテキストボックスを生成しました。



本当に何が起こっているのですか?



MVC 2のテンプレートシステムには、いくつかの組み込みテンプレートが含まれています。



オブジェクトを表示するために、システムはリフレクションを使用してオブジェクトのすべてのプロパティを検索し、各プロパティのマークアップを生成します。



テンプレートを使用しない場合、マークアップは次のようになります。



  <%foreach(ViewData.ModelMetadata.Propertiesのvar prop){%>
	 <div class = "display-label"> <%= prop.GetDisplayName()%> </ div>
	 <div class = "display-field"> <%= Html.Display(prop.PropertyName)%> </ div>
 <%}%> 


現在、これは完全な実装ではないことに留意する必要があります。 ここで不足しているものを後で説明します。



これは、複雑なオブジェクトを表示するためのテンプレートの基礎です。現在のモデルのすべてのプロパティを調べ、それぞれがラベルを表示し、Html.Display()メソッドを呼び出してプロパティ値を表示します。



文字列を表示したい場合はどうなりますか? そして、次のことが起こります:



  <%= Html.Encode(モデル)%> 


繰り返しますが、これは実際のコードではありません。実際に起こることについては後で説明します。



テンプレートのオーバーライド



組み込みテンプレートには多くの利点がありますが、おそらく最も重要なことは、レンダリングのどこでもテンプレートを置き換えることができることです。



文字列のパターン置換の例を見てみましょう。 これを行うには、文字列を呼び出して〜/ Views / ControllerName / DisplayTemplatesフォルダーに配置する部分ビューを作成します



文字列テンプレートトを置き換える方法

ファイルには次のように記述します。

  <%@ Control Language = "C#" Inherits = "System.Web.Mvc.ViewUserControl"%>
 <%= Html.Encode(Model)%> <em>みなさん、こんにちは!</ em> 


表示されるページを更新します。



置き換えられた文字列の例

ご覧のとおり、新しいテンプレートは自動的にセットアップされたため、すべての行を調べる必要はありませんでした。 ただし、テンプレートはAgeプロパティにも適用されます。Ageプロパティのタイプは実際には整数ですが、これについては後ほど説明します。



編集用のテンプレートを作成する必要がある場合は、 EditorTemplatesフォルダーに配置する必要があります。



パート2 ModelMetadata



モデルの概念化



ASP.NET MVC 2で導入された新しいクラスの1つは、モデルメタデータです。 このクラスは、オブジェクトを表示するために必要な情報を提供するように設計されています。 また、主にテンプレートの作成に使用されますが、メタデータはテンプレート内だけでなく常に使用可能です。



モデルとは何ですか?



ModelMetadataを使用する場合、「モデル」の定義は少しぼやけています。



前の部分のモデルをもう一度考えてみましょう。



 パブリッククラス
 {
	パブリック文字列FirstName {get; セット;  }
	パブリック文字列LastName {get; セット;  }
	 public int Age {get; セット;  }
 } 


このモデル用に厳密に型指定されたビューを作成しました。 このビューでViewData.ModelMetadataを参照する場合、この場合のモデルはContactクラスのオブジェクトになります。



ただし、メタデータオブジェクトを使用すると、オブジェクトのすべてのプロパティに関する情報を取得できます。 各プロパティのModelMetadataオブジェクトのコレクションを取得できます。 この例のコンテキストでは、FirstName、LastName、Ageの3つの新しいメタオブジェクトを取得します。 FirstNameプロパティのメタデータを見ると、モデルのデータ型がstringであり、コンテナオブジェクトの型がContactであることがわかります。 したがって、複雑なオブジェクトのすべてのプロパティを再帰的に繰り返すことができます。



ModelMetadataはどこで入手できますか?



現在のモデルを使用します。



メタデータにアクセスする最も簡単な方法は、ViewDataプロパティを使用することです。 この場合、ModelMetadataはViewDataに表示されるモデルを記述します。 オブジェクトのテンプレートをレンダリングする場合、このメソッドは最も簡単です。



すでにあるメタデータプロパティの1つを取得します。



既にメタデータオブジェクトがある場合は、Propertiesプロパティを使用できます。これにより、各プロパティのModelMetadataオブジェクトのリストが返されます。



式を使用する



ModelMetadataクラスには、FromStringExpressionとFromLambdaExpressionの2つの静的メソッドがあります。 これらのメソッドは、式から対応するメタデータを取得するときに使用されます(たとえば、「PropertyName」または「m => m.PropertyName」)。 ほとんどの既存のHTMLヘルパーは、これらの2つのメソッドの一部として既に書き直されています。



彼らは何を持っていますか?



ModelMetadataの操作方法について説明する前に、ModelMetadataクラスのオブジェクトが提供する情報を見てみましょう。



モデルとそのコンテナに関連するプロパティ:





モデルのメタデータ





方法



SimpleDisplayTextのデフォルト値は、次の規則に従います。



ModelMetadataはどのように形成されますか?



ASP.NET MVC 2にカスタムメタデータシステムを追加しました。デフォルトでは、メタオブジェクトは属性から取得したデータに基づいて形成されます。



次の属性を使用して、メタデータモデルを形成します。





パート3。 組み込みテンプレート。



テンプレートアプローチ



組み込みテンプレートについて説明する前に、作業でのテンプレートの使用方法と、テンプレートを直接オーバーラップする方法について説明します。



パス



使用するテンプレートが決定されると、システムはいくつかのパスを調べます。 それぞれについて、必要な結果に応じて、「DisplayNames / TemplateName」または「EditorName / TemplateName」という名前のascxファイルを検索します。



検索は次の順序で実行されます。





(テンプレートを編集するには、DisplayTemplatesをEditorTemplatesに置き換えます。)



パターン名



テンプレート名は次の順序で検索されます。



タイプ名で検索する場合、名前空間のない単純な名前(Type.Nameなど)を意味します。 さらに、タイプがNullable <T>の場合、タイプTに対して検索が実行されます(つまり、ブールパターンは「bool」と「Nullable <bool>」の両方に使用されます)。 つまり、値型のテンプレートを作成している場合は、その型がNULL可能かどうかを考慮する必要があります。 以下は、ブール型の組み込みテンプレートを使用した例です。



クラスTemplateInfo



そして、実装を詳しく調べる前に言及する価値のある最後のものはTemplateInfoクラスです。 TemplateInfoは、モデルメタデータとは異なり、ViewDataから常にアクセスできるとは限りません。テンプレートにいる場合のみです。



TemplateInfoで使用される主なプロパティはFormattedModelValueです。 このフィールドの値は、モデルの文字列としての正しい形式の値(ModelMetadataで指定された形式に基づく)、またはモデルの元の値(文字列の形式が指定されていない場合)のいずれかです。



さらに使用するものがいくつかあります(TemplateDepthプロパティやVisitedメソッドなど)。 しかし、私はそれらを理解するにつれて、それらの意味を説明します。



組み込みの表示テンプレート



システムがデータを表示するために使用するテンプレート名は9つあります:「ブール」、「10進数」、「EmailAddress」、「HiddenInput」、「Html」、「オブジェクト」、「ストリング」、「テキスト」および「Url」 それらの2つ(「テキスト」と「文字列」)は等しく実装されています。 それらの一部には、テンプレートを編集するための対応する類似物がありますが、一部はありません。



ASP.NET MVCの組み込みテンプレートはコードに実装されていますが、例として、.ascxファイルの機能を書き直しました。 これにより、それらをよりよく理解でき、これらのテンプレートの独自のバージョンを簡単に作成できます。



DisplayTemplate / String.ascx



  <%@ Control Language = "C#" Inherits = "System.Web.Mvc.ViewUserControl"%>
 <%= Html.Encode(ViewData.TemplateInfo.FormattedModelValue)%> 


驚きはありません。モデルを表示するだけで、その中の特別なhtml文字を置き換えます。



DisplayTemplates / Html.ascx



  <%@ Control Language = "C#" Inherits = "System.Web.Mvc.ViewUserControl"%>
 <%= ViewData.TemplateInfo.FormattedModelValue%> 


このテンプレートは、「Html」タイプがコンテンツがhtmlであり、したがってエンコードされてはならないことを意味するため、前のテンプレートよりも少し単純です。 XSS攻撃を避けるために、エンドユーザーからデータを受信する場合、このタイプを使用する場合は注意してください!



DisplayTemplates / EmailAddress.ascx



  <%@ Control Language = "C#" Inherits = "System.Web.Mvc.ViewUserControl"%>
 <a href="mailto:<%= Html.AttributeEncode(Model) %> "> <%= Html.Encode(ViewData.TemplateInfo.FormattedModelValue)%> </a> 


このテンプレートは、モデルがメールアドレスであると想定し、モデルへのリンクを自動的に作成します。 モデルは電子メールアドレスに使用され、FormattedModelValueは表示に使用されることに注意してください。



DisplayTemplates / Url.ascx



  <%@ Control Language = "C#" Inherits = "System.Web.Mvc.ViewUserControl"%>
 <a href="mailto:<%= Html.AttributeEncode(Model) %> "> <%= Html.Encode(ViewData.TemplateInfo.FormattedModelValue)%> </a> 


前の例のように機能します。



DisplayTemplates / HiddenInput.ascx



  <%@ Control Language = "C#" Inherits = "System.Web.Mvc.ViewUserControl"%>
 <%if(!ViewData.ModelMetadata.HideSurroundingHtml){%>
 <%= Html.Encode(ViewData.TemplateInfo.FormattedModelValue)%>
 <%}%> 


このテンプレートは、上記の[HiddenInput]属性と組み合わせて使用​​されます。 ユーザーがHideSurroundHtmlプロパティを明示的に指定していない場合にのみ、表示値を生成します。



DisplayTemplates / Decimal.ascx



  <%@ control language = "C#" inherits = "System.Web.Mvc.ViewUserControl"%>
 <script runat = "server">
プライベートオブジェクトFormattedValue
 {
	得る
	 {
		 if(ViewData.TemplateInfo.FormattedModelValue == ViewData.ModelMetadata.Model)
		 {
			 return String.Format(System.Globalization.CultureInfo.CurrentCulture、 "{0:0.00}"、ViewData.ModelMetadata.Model);
		 }
		 return ViewData.TemplateInfo.FormattedModelValue;
	 }
 }
 </ script>
 <%= Html.Encode(FormattedValue)%> 


このテンプレートは主に通貨表現に使用されるため、このテンプレートは小数点以下2桁の10進数値を表示します。 そのようなフォーマットの状態に注意してください。



DisplayTemplates / Boolean.ascx



  <%@ Control Language = "C#" Inherits = "System.Web.Mvc.ViewUserControl"%>
 <script runat = "server">
	プライベートブール?  ModelValue
	 {
		得る
		 {
			ブール? 値= null;
			 if(ViewData.Model!= null)
			 {
				値= Convert.ToBoolean(ViewData.Model、System.Globalization.CultureInfo.InvariantCulture);
			 }
			戻り値;
		 }
	 }
 </ script>
 <%if(ViewData.ModelMetadata.IsNullableValueType){%>
 <select class = "list-box tri-state" disabled = "disabled">
	 <オプション値= "" <%= ModelValue.HasValue?  "": "selected = 'selected'"%>>
		設定なし</ option>
	 <オプション値= "true" <%= ModelValue.HasValue && ModelValue.Value?  "selected = 'selected'": ""%>>
		 True </ option>
	 <オプション値= "false" <%= ModelValue.HasValue &&!ModelValue.Value?  "selected = 'selected'": ""%>>
		偽</ option>
 </ select>
 <%} else {%>
 <input class = "check-box" disabled = "disabled" type = "checkbox"
	 <%= ModelValue.Value?  "checked = 'checked'": ""%> />
 <%}%> 


ブール型のテンプレートは、型がNULL入力可能かどうかに応じてマークアップを生成する必要があるという点で興味深いです。 null不可の場合、通常のチェックボックスが使用されます。そうでない場合、3つの値を持つドロップダウンリストが表示されます。



DisplayTemplates / Object.ascx



あなたに代わって多くの作業が行われているため、コードを見る前にこのテンプレートのロジックを説明する価値があります。



オブジェクトタイプのテンプレートの主な目標は、それぞれのHTMLマークアップとともに、複雑なオブジェクトのすべてのプロパティです。 さらに、NullDisplayTextモデルの値がnullの場合、その値を表示する責任があります。 そして、それはいわゆる「シャローダイブ」を提供し、必要なレベルのプロパティのみを表示します。 後ほど、このテンプレートの設定について説明します。これには、ディープダイブ操作の準備も含まれます。



  <%@ Control Language = "C#" Inherits = "System.Web.Mvc.ViewUserControl"%>

 <%if(Model == null){%>
	 <%= ViewData.ModelMetadata.NullDisplayText%>
 <%} else if(ViewData.TemplateInfo.TemplateDepth> 1){%>
	 <%= ViewData.ModelMetadata.SimpleDisplayText%>
 <%} else {%>
	 <%foreach(ViewData.ModelMetadata.Properties.Whereのvar prop(pm => pm.ShowForDisplay &&!ViewData.TemplateInfo.Visited(pm))){%>
		 <%if(prop.HideSurroundingHtml){%>
			 <%= Html.Display(prop.PropertyName)%>
		 <%} else {%>
			 <%if(!String.IsNullOrEmpty(prop.GetDisplayName())){%>
				 <div class = "display-label"> <%= prop.GetDisplayName()%> </ div>
			 <%}%>
			 <div class = "display-field"> <%= Html.Display(prop.PropertyName)%> </ div>
		 <%}%>
	 <%}%>
 <%}%> 


この例をもっと詳しく見てみましょう。



  <%if(Model == null){%>
	 <%= ViewData.ModelMetadata.NullDisplayText%>
 <%} 


この場所ではすべてが明確であり、モデルがnullの場合はNullDisplayTextが表示されます。



  else if(ViewData.TemplateInfo.TemplateDepth> 1){%>
	 <%= ViewData.ModelMetadata.SimpleDisplayText%>
 <%} 


この時点で、プロパティのネストのレベルを制限します(「浅いダイビング」、浅いダイビング)。 TemplateInfoクラスは、テンプレートのネストの深さを追跡します。 トップレベルのTemplateDepthプロパティは1です。



 その他{%>
	 <%foreach(ViewData.ModelMetadata.Properties.Whereのvar prop(pm => pm.ShowForDisplay 
				 &&!ViewData.TemplateInfo.Visited(pm))){%> 


これは、オブジェクトのプロパティを通るメインループです。 表示すべきでないことを示すプロパティは無視されます。 プロパティフィルターの別の部分は、無限再帰を防ぐために、このオブジェクトが以前にレンダリングされたかどうかをTemplateInfoに尋ねます。



  <%if(prop.HideSurroundingHtml){%>
	 <%= Html.Display(prop.PropertyName)%>
 <%} 


このプロパティがtrueに設定されている場合、テンプレートは、不必要なhtmlマークアップなしで、表示するようプロパティに要求するだけです。



  <%if(!String.IsNullOrEmpty(prop.GetDisplayName())){%>
	 <div class = "display-label"> <%= prop.GetDisplayName()%> </ div>
 <%}%>
 <div class = "display-field"> <%= Html.Display(prop.PropertyName)%> </ div> 


この時点で、プロパティに表示名があるかどうかが確認され、表示名がある場合はdivで囲まれて表示されます。 次に、プロパティのレンダリングが開始されます。



組み込みの編集テンプレート



編集テンプレートは、値を編集する機能が含まれているため、表示テンプレートよりも少し複雑です。 既存のHTMLヘルパーの上に構築されます。 合計で7つの編集テンプレートがあります:「ブール」、「10進数」、「非表示入力」、「マルチラインテキスト」、「オブジェクト」、「パスワード」、「ストリング」。



多くの場合、htmlヘルパーの要素名として空の文字列が渡されます。 これは通常間違っていますが、テンプレートの場合、プロパティの「コンテキスト」があります。 これにより、ネストプロパティの階層(「Contact.HomeAddress.City」など)を維持できるため、複雑なオブジェクトを操作しやすくなります。



名前をhtmlヘルパーに渡すと、「City」というオブジェクトのプロパティを編集するためのテキストボックスをください。 しかし、テンプレートが住所用ではなく、複雑なオブジェクトではなく、都市用であり、文字列用である場合はどうなりますか? 空の文字列を名前として渡すと、htmlヘルパーに「自分で編集するためのテキストボックスをください」と伝えます。



EditorTemplates / String.ascx



  <%@ Control Language = "C#" Inherits = "System.Web.Mvc.ViewUserControl"%>
 <%= Html.TextBox( ""、ViewData.TemplateInfo.FormattedModelValue、
		新しい{@class = "text-box single-line"})%> 


繰り返しますが、これは理解しやすい最も簡単なテンプレートなので、行から始めましょう。 このテンプレートは、システムにテキストボックス(それ自体を編集するため)を取得したいことを伝え、編集されたプロパティのフォーマットされた値で開始します。 さらに、このテキストボックスには、2つのCSSクラス「text-box」と「single-line」を使用します。



EditorTemplates / Password.ascx



  <%@ Control Language = "C#" Inherits = "System.Web.Mvc.ViewUserControl"%>
 <%= Html.Password( ""、ViewData.TemplateInfo.FormattedModelValue、
		新しい{@class = "テキストボックスの単一行パスワード"})%> 


パスワードを入力するためのパターンは、パスワードヘルパーメソッドを呼び出して別のCSSクラス(「パスワード」)を使用することを除いて、文字列のパターンに似ています。



EditorTemplates / MultilineText.ascx



  <%@ Control Language = "C#" Inherits = "System.Web.Mvc.ViewUserControl"%>
 <%= Html.TextArea( ""、ViewData.TemplateInfo.FormattedModelValue.ToString()、
					 0、0、新規{@class = "text-box multi-line"})%> 


繰り返しますが、驚きはありません。 TextAreaメソッドを呼び出して、0に等しい行と列の数を指定し(CSSを使用するため)、クラス「single-line」の代わりにクラス「multi-line」を使用します。



EditorTemplates / HiddenInput.ascx



  <%@ Control Language = "C#" Inherits = "System.Web.Mvc.ViewUserControl"%>
 <script runat = "server">
	プライベートオブジェクトModelValue
	 {
		得る
		 {
			 if(モデルはSystem.Data.Linq.Binary)
			 {
				 return Convert.ToBase64String(((System.Data.Linq.Binary)Model).ToArray());
			 }
			 if(モデルはバイト[])
			 {
				 return Convert.ToBase64String((byte [])Model);
			 }
			モデルを返す;
		 }
	 }
 </ script>
 <%if(!ViewData.ModelMetadata.HideSurroundingHtml){%>
	 <%= Html.Encode(ViewData.TemplateInfo.FormattedModelValue)%>
 <%}%>
 <%= Html.Hidden( ""、ModelValue)%> 


ご覧のとおり、表示テンプレートよりもはるかに複雑です。 ModelValueプロパティは、モデルがバイト配列かバイナリlinq2sqlオブジェクトかを判断し、base64を使用して文字列に変換します。 次に、結果を非表示フィールドに書き込みます。



EditorTemplates / Decimal.ascx



  <%@ Control Language = "C#" Inherits = "System.Web.Mvc.ViewUserControl"%>
 <script runat = "server">
	プライベートオブジェクトModelValue
	 {
		得る
		 {
			 if(ViewData.TemplateInfo.FormattedModelValue == ViewData.ModelMetadata.Model)
			 {
				 return String.Format(System.Globalization.CultureInfo.CurrentCulture、
							 「{0:0.00}」、ViewData.ModelMetadata.Model);
			 }
			 return ViewData.TemplateInfo.FormattedModelValue;
		 }
	 }
 </ script>
 <%= Html.TextBox( ""、ModelValue、new {@class = "text-box single-line"})%> 


Decimalのテンプレートは、表示用の対応するテンプレートに似ていますが、編集用のテキストボックスが生成される点が異なります。



EditorTemplates / Boolean.ascx



  <%@ control language = "C#" inherits = "System.Web.Mvc.ViewUserControl"%>

 <script runat = "server">
	プライベートリスト<SelectListItem> TriStateValues
	 {
		得る
		 {
			新しいリスト<SelectListItem>を返す{
				新しいSelectListItem {Text = "Not Set"、
									 値= String.Empty、
									 選択=!Value.HasValue}、
				新しいSelectListItem {Text = "True"、
									 値= "true"、
									 選択= Value.HasValue && Value.Value}、
				新しいSelectListItem {Text = "False"、
									 値= "false"、
									 選択= Value.HasValue &&!Value.Value}、
			 };
		 }
	 }
	プライベートブール? 価値
	 {
		得る
		 {
			ブール? 値= null;
			 if(ViewData.Model!= null)
			 {
				値= Convert.ToBoolean(ViewData.Model、
							 System.Globalization.CultureInfo.InvariantCulture);
			 }
			戻り値;
		 }
	 }
 </ script>

 <%if(ViewData.ModelMetadata.IsNullableValueType){%>
	 <%= Html.DropDownList( ""、TriStateValues、new {@class = "list-box tri-state"})%>
 <%} else {%>
	 <%= Html.CheckBox( ""、Value ?? false、new {@class = "check-box"})%>
 <%}%> 


このテンプレートは、表示用の対応するテンプレートにも似ています。



EditorTemplates / Object.ascx



  <%@ Control Language = "C#" Inherits = "System.Web.Mvc.ViewUserControl"%>
 <%if(ViewData.TemplateInfo.TemplateDepth> 1){%>
	 <%= ViewData.ModelMetadata.SimpleDisplayText%>
 <%}
	その他{%>    
	 <%foreach(ViewData.ModelMetadata.Properties.Whereのvar prop(pm => pm.ShowForEdit
					 &&!ViewData.TemplateInfo.Visited(pm))){%>
		 <%if(prop.HideSurroundingHtml){%>
			 <%= Html.Editor(prop.PropertyName)%>
		 <%} else {%>
			 <%if(!String.IsNullOrEmpty(Html.Label(prop.PropertyName).ToHtmlString())){%>
				 <div class = "editor-label"> <%= Html.Label(prop.PropertyName)%> </ div>
			 <%}%>
			 <div class = "editor-field">
				 <%= Html.Editor(prop.PropertyName)%>
				 <%= Html.ValidationMessage(prop.PropertyName、 "*")%>
			 </ div>
		 <%}%>
	 <%}%>
 <%}%> 


同様に、このテンプレートはあまり変更されておらず、ValidationMessageメソッドへの呼び出しのみが追加されています。



パート4。 独自のテンプレートを作成する



さらに例として、次のモデル、コントローラー、およびプレゼンテーションが使用されます。



モデル/ SampleModel.cs



  System.ComponentModel.DataAnnotationsを使用します。
 System.Web.Mvcを使用します。

パブリッククラスSampleModel
 {
	 public static SampleModel Create()
	 {
		新しいSampleModelを返す
		 {
			ブール= true
			 EmailAddress = "admin@contoso.com"、
			 10進数= 21.1234M、
			整数= 42、
			非表示=「編集不可」、
			 HiddenAndInvisible = "編集不可"、
			 Html = "これは<b> HTML </ b>対応です"、
			 MultilineText = "この\ r \ nhas \ r \ nmultiple \ r \ nlines"、
			 NullableBoolean = null、
			パスワード= "supersecret"、
			文字列=「単純な文字列」、
			 Url = "http://www.microsoft.com/"、
		 };
	 }

	 public boolブール値{get; セット;  }

	 [DataType(DataType.EmailAddress)]
	パブリック文字列EmailAddress {get; セット;  }

	 public decimal Decimal {get; セット;  }

	 [HiddenInput]
	パブリックストリングHidden {get; セット;  }

	 [HiddenInput(DisplayValue = false)]
	パブリック文字列HiddenAndInvisible {get; セット;  }

	 [DataType(DataType.Html)]
	パブリックストリングHtml {get; セット;  }

	 [必須]
	 [範囲(10、100)]
	 public int Integer {get; セット;  }

	 [DataType(DataType.MultilineText)]
	パブリックストリングMultilineText {get; セット;  }

	パブリックブール?  NullableBoolean {get; セット;  }

	 [DataType(DataType.Password)]
	パブリックストリングパスワード{get; セット;  }

	 public string String {get; セット;  }

	 [DataType(DataType.Url)]
	パブリック文字列Url {get; セット;  }

	 [DisplayFormat(NullDisplayText = "(null value)")]
	 public ChildModel ChildModel {get; セット;  }
 } 


モデル/ ChildModel.cs



  System.ComponentModel.DataAnnotationsを使用します。

 [DisplayColumn( "FullName")]
パブリッククラスChildModel
 {
	 [必須、StringLength(25)]
	パブリック文字列FirstName {get; セット;  }

	 [必須、StringLength(25)]
	パブリック文字列LastName {get; セット;  }

	 [ScaffoldColumn(false)]
	パブリックストリングFullName 
	 {
		得る
		 {
			 Return FirstName + "" + LastName;
		 }
	 }
 } 


コントローラー/ HomeController.cs



  System.Web.Mvcを使用します。

パブリッククラスHomeController:コントローラー
 {
	 static SampleModel model = SampleModel.Create();

	パブリックViewResultインデックス()
	 {
		戻りビュー(モデル);
	 }

	パブリックViewResult編集()
	 {
		戻りビュー(モデル);
	 }

	 [HttpPost]
	 [ValidateInput(false)]
	パブリックActionResult編集(SampleModelを編集したモデル)
	 {
		 if(ModelState.IsValid)
		 {
			モデル= editedModel;
			 return RedirectToAction( "詳細");
		 }

		 Return View(editedModel);
	 }
 } 


ビュー/ホーム/ Index.aspx



  <%@ Page Language = "C#" MasterPageFile = "〜/ Views / shared / Site.master" Inherits = "ViewPage <SampleModel>"%>

 <asp:Content ContentPlaceHolderID = "MainContent" runat = "server">
	 <h3>詳細</​​ h3>
	 <fieldset style = "padding:1em; margin:0; border:solid 1px#999;">
		 <%= Html.DisplayForModel()%>
	 </ fieldset>
	 <p> <%= Html.ActionLink( "編集"、 "編集")%> </ p>
 </ asp:コンテンツ> 


ビュー/ホーム/ Edit.aspx



  <%@ Page Language = "C#" MasterPageFile = "〜/ Views / shared / Site.master" Inherits = "ViewPage <SampleModel>"%>

 <asp:コンテンツID = "Content2" ContentPlaceHolderID = "MainContent" runat = "server">
	 <h3>編集</ h3>
	 <%using(Html.BeginForm()){%>
		 <fieldset style = "padding:1em; margin:0; border:solid 1px#999;">
			 <%= Html.ValidationSummary( "壊れたもの:")%>
			 <%= Html.EditorForModel()%>
			 <入力タイプ= "送信"値= "送信" />
		 </ fieldset>
	 <%}%>
	 <p> <%= Html.ActionLink( "Details"、 "Index")%> </ p>
 </ asp:コンテンツ> 


デフォルトの表示テンプレート



デフォルトのテンプレートを使用してアプリケーションを実行すると、次のページが表示されます。



デフォルトの表示テンプレート

編集用のページは次のようになります。



デフオルトの編集

テーブルを使用します



名前と値のペアが1行で表示されるように、マークアップをテーブル形式で作成しましょう。 編集用のテンプレートには、必須フィールドにアスタリスクが表示されることに注意してください。



ビュー/共有/ DisplayTemplates / Object.ascx



  <%@ Control Language = "C#" Inherits = "System.Web.Mvc.ViewUserControl"%>
 <%if(Model == null){%>
	 <%= ViewData.ModelMetadata.NullDisplayText%>
 <%} else if(ViewData.TemplateInfo.TemplateDepth> 1){%>
	 <%= ViewData.ModelMetadata.SimpleDisplayText%>
 <%} else {%>
	 <table cellpadding = "0" cellspacing = "0" border = "0">
	 <%foreach(ViewData.ModelMetadata.Properties.Whereのvar prop(pm => pm.ShowForDisplay &&!ViewData.TemplateInfo.Visited(pm))){%>
		 <%if(prop.HideSurroundingHtml){%>
			 <%= Html.Display(prop.PropertyName)%>
		 <%} else {%>
			 <tr>
				 <td>
					 <div class = "display-label" style = "text-align:right;">
						 <%= prop.GetDisplayName()%>
					 </ div>
				 </ td>
				 <td>
					 <div class = "display-field">
						 <%= Html.Display(prop.PropertyName)%>
					 </ div>
				 </ td>
			 </ tr>
		 <%}%>
	 <%}%>
	 </ table>
 <%}%> 


その結果、次のフォームを取得します。



置換された表示テンプレート

ビュー/共有/ EditorTemplates / Object.ascx



  <%@ Control Language = "C#" Inherits = "System.Web.Mvc.ViewUserControl"%>
 <%if(ViewData.TemplateInfo.TemplateDepth> 1){%>
	 <%= ViewData.ModelMetadata.SimpleDisplayText%>
 <%} else {%>
	 <table cellpadding = "0" cellspacing = "0" border = "0">
	 <%foreach(ViewData.ModelMetadata.Properties.Whereのvar prop(pm => pm.ShowForEdit &&!ViewData.TemplateInfo.Visited(pm))){%>
		 <%if(prop.HideSurroundingHtml){%>
			 <%= Html.Editor(prop.PropertyName)%>
		 <%} else {%>
			 <tr>
				 <td>
					 <div class = "editor-label" style = "text-align:right;">
						 <%= prop.IsRequired?  "*": ""%>
						 <%= Html.Label(prop.PropertyName)%>
					 </ div>
				 </ td>
				 <td>
					 <div class = "editor-field">
						 <%= Html.Editor(prop.PropertyName)%>
						 <%= Html.ValidationMessage(prop.PropertyName、 "*")%>
					 </ div>
				 </ td>
			 </ tr>
		 <%}%>
	 <%}%>
	 </ table>
 <%}%> 


したがって、次のマークアップを作成しました。



編集テンプレートレートトの置き換え

浅いダイビングと深いダイビング(浅いダイビングと深いダイビング)



上記のスクリーンショットでは、ChildModelは(null値)と表示されています。これは、コードの属性を使用してこの値を設定しているためです。



編集モードであっても、このプロパティを変更することはできません。



最初の「if」条件を削除して編集テンプレートを変更すると、次のようになります。



編集テンプレートレトートの詳細

表示モードでは:



デイプレステンプレントへの浅い没入感

表示用のテンプレートを変更していないため、「shallow dive」(shallow dive)のロジックで結果が得られます。 モデルの[DisplayColumn]属性を使用し、FullNameプロパティを表示するように指定したため、フルネームが表示されます。



表示テンプレートを変更してディープダイブを使用すると、次の結果が得られます。



ディスプレイテンプレートに深く浸る

パート5 MasterPageテンプレート



最初に行う必要があるのは、テンプレートで使用されるMasterPageを定義することです。1つは編集テンプレート用で、もう1つは表示テンプレート用です。



DisplayTemplates / Template.master



 <%@ Master Language = "C#" Inherits = "System.Web.Mvc.ViewMasterPage"%>
<script runat = "server">
	保護されたオーバーライドvoid OnInit(EventArgs e){
		base.OnInit(e);
		if(ViewData.ModelMetadata.HideSurroundingHtml){
			TablePlaceholder.Visible = false;
		 }
		その他{
			Controls.Remove(データ);
			DataPlaceholder.Controls.Add(データ);
		 }
	 }
 </ script>
<asp:ContentPlaceHolder runat="server" id="Data" />
<asp:PlaceHolder runat="server" id="TablePlaceholder">
	<table cellpadding="0" cellspacing="0" border="0" width="100%">
		 <tr>
			<td style="width: 10em;">
				<div class="display-label" style="text-align: right;">
					<asp:ContentPlaceHolder runat="server" id="Label">
						<%= ViewData.ModelMetadata.GetDisplayName() %>
					</asp:ContentPlaceHolder>
				 </ div>
			 </ td>
			 <td>
				<div class="display-field">
					<asp:PlaceHolder runat="server" id="DataPlaceholder" />
				 </ div>
			 </ td>
		 </ tr>
	 </ table>
</asp:PlaceHolder> 


このページの動作の本質は、「ラベル」と「データ」と呼ばれる2つのContentPlaceHolderを定義することです。コンテンツ「Label」には、プロパティの名前と「Data」の値がそれぞれ表示されます。



このテンプレートは、Webフォームの1つの機能を使用します。OnInitメソッドでは、モデルにhtmlマークアップを使用するかどうかに応じて、ページを再編成します。



EditorTemplates / Template.master



 <%@ Master Language = "C#" Inherits = "System.Web.Mvc.ViewMasterPage"%>
<script runat = "server">
	保護されたオーバーライドvoid OnInit(EventArgs e){
		base.OnInit(e);
		if(ViewData.ModelMetadata.HideSurroundingHtml){
			TablePlaceholder.Visible = false;
		 }
		その他{
			Controls.Remove(データ);
			DataPlaceholder.Controls.Add(データ);
		 }
	 }
 </ script>
<asp:ContentPlaceHolder runat="server" id="Data" />
<asp:PlaceHolder runat="server" id="TablePlaceholder">
	<table cellpadding="0" cellspacing="0" border="0" width="100%">
		 <tr>
			<td style="width: 10em;">
				<asp:ContentPlaceHolder runat="server" id="Label">
					<div class="editor-label" style="text-align: right;">
						<%= ViewData.ModelMetadata.IsRequired ? "*" : "" %>
						<%= Html.Label("") %>
					 </ div>
				</asp:ContentPlaceHolder>
			 </ td>
			 <td>
				<div class="editor-field">
					<asp:PlaceHolder runat="server" id="DataPlaceholder" />
					<asp:ContentPlaceHolder runat = "server" ID = "Validation">
						<%= Html.ValidationMessage( ""、 "*")%>
					</ asp:ContentPlaceHolder>
				 </ div>
			 </ td>
		 </ tr>
	 </ table>
</ asp:PlaceHolder> 


編集用のテンプレートのバージョンは、バリデータメッセージ用に設計された3番目のプレースホルダーがあり、必須フィールドにマークが付けられている点でのみ異なります。



パターンを使用した単純型



単純型では、<asp:Content ...>サーバータグを使用してマスターテンプレートを使用します。



DisplayTemplates / String.aspx



 <%@ Page Language = "C#" MasterPageFile = "Template.Master" Inherits = "System.Web.Mvc.ViewPage"%>
<asp:Content ContentPlaceHolderID = "Data" runat = "server">
	<%= Html.Encode(ViewData.TemplateInfo.FormattedModelValue)%>
</ asp:コンテンツ> 


EditorTemplates / String.aspx



 <%@ Page Language = "C#" MasterPageFile = "Template.Master" Inherits = "System.Web.Mvc.ViewPage"%>
<asp:Content ContentPlaceHolderID = "Data" runat = "server">
	<%= Html.TextBox( ""、ViewData.TemplateInfo.FormattedModelValue、
新しい{@class = "text-box single-line"})%>
</ asp:コンテンツ> 


複合型テンプレート



複合型のテンプレートは、マスターテンプレートの一般的なマークアップを削除したため、はるかに単純になりました。残るのはロジックだけです。



DisplayTemplates / Object.aspx



 <%@ Page Language = "C#" Inherits = "System.Web.Mvc.ViewPage"%>
<%if(ViewData.TemplateInfo.TemplateDepth> 1){%>
	<%= ViewData.ModelMetadata.SimpleDisplayText%>
<%} else {%>
	<%foreach(ViewData.ModelMetadata.Properties.Whereのvar prop(pm => pm.ShowForDisplay &&!ViewData.TemplateInfo.Visited(pm))){%>
		<%= Html.Display(prop.PropertyName)%>
	<%}%>
<%}%> 


EditorTemplates / Object.aspx



 <%@ Page Language = "C#" Inherits = "System.Web.Mvc.ViewPage"%>
<%if(ViewData.TemplateInfo.TemplateDepth> 1){%>
	<%= ViewData.ModelMetadata.SimpleDisplayText%>
<%} else {%>
	<%foreach(ViewData.ModelMetadata.Properties.Whereのvar prop(pm => pm.ShowForEdit &&!ViewData.TemplateInfo.Visited(pm))){%>
		<%= Html.Editor(prop.PropertyName)%>
	<%}%>
<%}%> 


これらのテンプレートでは、マークアップがなく、ロジックのみがあるため、MasterPageを使用しないことに注意してください。単純型のテンプレートを呼び出すと、マークアップが生成されます。



おわりに



ASP.NET MVC 2はまだベータ版であり、リリースにより変更される可能性があります。ただし、主要なポイントは説明どおりに正確に維持され、この資料をマスターしたことで、最終バージョンのリリースに向けた準備が整います。






All Articles