方法 : データ モデルの非組み込みデータ型に合わせてデータ フィールドの外観と動作をカスタマイズする
更新 : 2008 年 7 月
ASP.NET Dynamic Data では、System.ComponentModel.DataAnnotations.DataTypeAttribute 属性を使用して、特定のデータ型を特定のデータ モデル フィールドに割り当てることができます。この方法は、Dynamic Data によって推論される CLR 型ではなく、より具体的にデータ フィールドの型を割り当てる必要がある場合などに役立ちます。
たとえば、電子メール アドレスを含んだテキスト フィールドを、特殊な種類のテキストとして定義された電子メール型として指定できます。このフィールドを処理するテキスト フィールド テンプレートは、この属性によって指定された情報を使用して、電子メール型の表示と編集に特化した UI を作成します。EmailAddress() 属性でマークされたテキスト フィールドを、System.Web.UI.WebControls.HyperLink コントロールとして表示させることも可能です。
特定のデータ型に対して特殊な処理を指定する方法としては、カスタム フィールド テンプレートと UIHint を組み合わせて使用する方法もあります。DataTypeAttribute 属性では、複数の型に対して 1 つのフィールド テンプレートを使用できます。
通常、DataTypeAttribute 属性と UIHint 属性は、使いやすい方を任意に選んで使用できます。UIHint プロパティの使用方法については、「方法 : ASP.NET Dynamic Data の既定のフィールド テンプレートをカスタマイズする」を参照してください。
このトピックでは、DataTypeAttribute 属性の使用方法を説明します。
DataTypeAttribute とデータ フィールドとを関連付けるには
カスタマイズするデータ フィールドがある ASP.NET Web サイトを開きます。
メモ : Dynamic Data に必要な Web サイト構成が済んでいる必要があります。
ソリューション エクスプローラで、App_Code フォルダを右クリックし、[新しい項目の追加] をクリックします。
[インストールされているテンプレート] の [クラス] をクリックします。
[名前] ボックスにファイルの名前を入力します。
作成するクラスの名前は、テーブルを表すエンティティ クラス名と一致させる必要があります。たとえば、Customer テーブルを使用する場合は、「Customer」というクラス名にします。
クラス定義に Partial キーワード (Visual Basic の場合) または partial キーワード (Visual C# の場合) を追加して部分クラスにします。
Imports キーワード (Visual Basic の場合) または using キーワード (Visual C# の場合) を使用して、System.ComponentModel 名前空間と System.ComponentModel.DataAnnotations 名前空間への参照を追加します。次に例を示します。
using System.ComponentModel; using System.ComponentModel.DataAnnotations;
Imports System.ComponentModel Imports System.ComponentModel.DataAnnotations
属性を適用する各データ フィールドのプロパティ アクセサを追加します。
Customer テーブルのフィールドに対応する 3 つのプロパティのプロパティ アクセサを作成する方法の例を次に示します。
public class CustomerMetaData { public object PasswordHash { get; set; } public object PasswordSalt { get; set; } public object ModifiedDate { get; set; } }
Public Class CustomerMetaData Public PasswordHash As Object Public PasswordSalt As Object Public ModifiedDate As Object End Class
部分クラスの関連メタデータ クラスとして機能する別のクラスを作成します。このクラスには、まだ使用されていない任意の名前を付けることができます。たとえば、CustomerMetaData という名前のクラスを、Customer クラスの関連メタデータ クラスとして作成できます。
部分クラス定義に MetadataTypeAttribute 属性を追加します。属性のパラメータには、前の手順で作成した関連メタデータ クラスの名前を使用します。
[MetadataType(typeof(CustomerMetaData))] public partial class Customer { }
<MetadataType(GetType(CustomerMetaData))> _ Partial Public Class Customer End Class
メタデータ クラスで、表示または動作の変更対象となる各フィールドに DataAnnotations 属性を追加します。
次の例は、完成した Customer テーブルの部分クラスと、CustomerMetaData という名前の関連メタデータ クラスを示しています。メタデータ クラスには、データベースのフィールドに対応するパブリック クラス フィールドが存在します。PasswordHash フィールドおよび PasswordSalt フィールドに指定された ScaffoldColumnattribute 属性は、false に設定されています。これにより、フィールドが Dynamic Data によって表示されるのを防いでいます。ModifiedDate フィールドには DataType 属性が指定され、その値が DataType.Date に設定されています。このように指定することで、このフィールドのデータが短い日付形式で表示されます。
using System.ComponentModel; using System.ComponentModel.DataAnnotations; [MetadataType(typeof(CustomerMetaData))] public partial class Customer { } public class CustomerMetaData { [ScaffoldColumn(false)] public object PasswordHash { get; set; } [ScaffoldColumn(false)] public object PasswordSalt { get; set; } [DataTypeAttribute(DataType.Date)] public object ModifiedDate { get; set; } }
Imports Microsoft.VisualBasic Imports System.ComponentModel Imports System.ComponentModel.DataAnnotations <MetadataType(GetType(CustomerMetaData))> _ Partial Public Class Customer End Class Public Class CustomerMetaData <ScaffoldColumn(False)> _ Public PasswordSalt As Object <DataTypeAttribute(DataType.Date)> _ Public PasswordSalt As Object <DataTypeAttribute(DataType.Date)> _ Public ModifiedDate As Object End Class
部分クラス、メタデータ クラス、および属性が正常に機能することを確認するために、アプリケーションを実行してテーブルを表示します。
フィールド テンプレートを変更してカスタマイズされたデータ属性を使用するには
カスタマイズするフィールド テンプレートを開きます。組み込みのテンプレートをカスタマイズする場合は、データ型に対応するフィールド テンプレートを開きます。
たとえば、文字列表示用のフィールド テンプレートをカスタマイズする場合は、DynamicData\FieldTemplates ディレクトリの Text.ascx を開きます。
必要に応じて、マークアップを変更します。
分離コード ファイルで、OnDataBinding メソッドをオーバーライドします。このメソッドは、フィールド テンプレート コントロールが表示するデータを取得したタイミングで呼び出されます。このメソッドで、フィールド テンプレートの派生元の FieldTemplateUserControl クラスの MetadataAttributes プロパティから、現在のデータ フィールドの属性を取得します。これで、フィールドに指定された属性に応じて、データの書式を設定したり、データを加工したりできます。
たとえば、このトピックの前半で変更したデータ フィールドであれば、Text.ascx フィールド テンプレートに次のコードを使用することによって表示できます。
Imports System Imports System.Data Imports System.Configuration Imports System.Collections Imports System.Collections.Specialized Imports System.Linq Imports System.Web Imports System.Web.Security Imports System.Web.UI Imports System.Web.UI.WebControls Imports System.Web.UI.WebControls.WebParts Imports System.Web.UI.HtmlControls Imports System.Xml.Linq Imports System.Web.DynamicData Imports System.ComponentModel.DataAnnotations Partial Class TextField Inherits System.Web.DynamicData.FieldTemplateUserControl Private Function getNavUrl() As String Dim metadata = MetadataAttributes.OfType(Of DataTypeAttribute).FirstOrDefault() If (metadata Is Nothing) Then Return FieldValueString End If Dim url As String = FieldValueString Select Case metadata.DataType Case DataType.Url url = FieldValueString If (url.StartsWith("http://", StringComparison.OrdinalIgnoreCase) Or _ url.StartsWith("https://", StringComparison.OrdinalIgnoreCase)) Then Return url End If Return "http://" + FieldValueString Case DataType.EmailAddress Return "mailto:" + FieldValueString Case Else Throw New Exception("Unknow DataType") End Select End Function Protected Overrides Sub OnDataBinding(ByVal e As System.EventArgs) MyBase.OnDataBinding(e) If (String.IsNullOrEmpty(FieldValueString)) Then Return End If Dim metadata = MetadataAttributes.OfType(Of DataTypeAttribute).FirstOrDefault() If (metadata Is Nothing Or String.IsNullOrEmpty(FieldValueString)) Then Dim literal As New Literal() literal.Text = FieldValueString Controls.Add(literal) Return End If If (metadata.DataType = DataType.Url Or _ metadata.DataType = DataType.EmailAddress) Then Dim hyperlink As New HyperLink hyperlink.Text = FieldValueString hyperlink.href = getNavUrl() hyperlink.Target = "_blank" Controls.Add(hyperlink) Return End If If (metadata.DataType = DataType.Custom And _ String.Compare(metadata.CustomDataType, "BoldRed", True) = 0) Then Dim lbl As New Label() lbl.Text = FieldValueString lbl.Font.Bold = True lbl.ForeColor = System.Drawing.Color.Red Controls.Add(lbl) End If End Sub End Class
using System; using System.Data; using System.Configuration; using System.Collections; using System.Collections.Specialized; using System.Linq; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; using System.Xml.Linq; using System.Web.DynamicData; using System.ComponentModel.DataAnnotations; public partial class TextField : System.Web.DynamicData.FieldTemplateUserControl { string getNavUrl() { var metadata = MetadataAttributes.OfType<DataTypeAttribute>().FirstOrDefault(); if (metadata == null) return FieldValueString; switch (metadata.DataType) { case DataType.Url: string url = FieldValueString; if (url.StartsWith("http://", StringComparison.OrdinalIgnoreCase) || url.StartsWith("https://", StringComparison.OrdinalIgnoreCase)) return url; return "http://" + FieldValueString; case DataType.EmailAddress: return "mailto:" + FieldValueString; default: throw new Exception("Unknown DataType"); } } protected override void OnDataBinding(EventArgs e) { base.OnDataBinding(e); if (string.IsNullOrEmpty(FieldValueString)) return; var metadata = MetadataAttributes.OfType<DataTypeAttribute>().FirstOrDefault(); if (metadata == null || string.IsNullOrEmpty(FieldValueString)) { Literal literal = new Literal(); literal.Text = FieldValueString; Controls.Add(literal); return; } if (metadata.DataType == DataType.Url || metadata.DataType == DataType.EmailAddress) { HyperLink hyperlink = new HyperLink(); hyperlink.Text = FieldValueString; hyperlink.href = getNavUrl(); hyperlink.Target = "_blank"; Controls.Add(hyperlink); return; } if (metadata.DataType == DataType.Custom && string.Compare(metadata.CustomDataType, "BoldRed", true) == 0) { Label lbl = new Label(); lbl.Text = FieldValueString; lbl.Font.Bold = true; lbl.ForeColor = System.Drawing.Color.Red; Controls.Add(lbl); } } }
このコードでは、まず、現在のフィールドの属性が取得されます。フィールドに指定された属性を調べ、その結果に応じて異なるロジックが実行されます。たとえば、Custom() の判定を行い、CustomDataType() プロパティが "BoldRed" であることが確認できれば、そのフィールドにカスタムの BoldRed 属性が指定されていると判断できます。その場合は、赤色のテキストとして設定された Label コントロールにデータを表示する UI が作成されます。
使用例
非組み込みデータ型向けに、データ フィールドの外観と動作をカスタマイズする方法を次の例に示します。このコードでは、AdventureWorksLT データベースに存在する Customer テーブルの EmailAddress、SalesPerson、および LastName の各フィールドについて、Dynamic Data による表示がカスタマイズされます。
Imports System.ComponentModel
Imports System.ComponentModel.DataAnnotations
<MetadataType(GetType(CustomerMetaData))> _
Partial Public Class Customer
End Class
Public Class CustomerMetaData
<ScaffoldColumn(False)> _
Public PasswordHash As Object
<ScaffoldColumn(False)> _
Public PasswordSalt As Object
<DataTypeAttribute(DataType.Date)> _
Public ModifiedDate As Object
<DataTypeAttribute(DataType.EmailAddress)> _
Public EmailAddress As Object
<DataTypeAttribute(DataType.Url)> _
Public SalesPerson As Object
<DataTypeAttribute("BoldRed")> _
<DisplayName("Last")> _
Public ReadOnly Property LastName() As Object
Get
Return ""
End Get
End Property
End Class
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
[MetadataType(typeof(CustomerMetaData))]
public partial class Customer {
}
public class CustomerMetaData {
[ScaffoldColumn(false)]
public object PasswordHash { get; set; }
[ScaffoldColumn(false)]
public object PasswordSalt { get; set; }
[DataTypeAttribute(DataType.Date)]
public object ModifiedDate { get; set; }
[DataTypeAttribute(DataType.EmailAddress)]
public object EmailAddress { get; set; }
[DataTypeAttribute(DataType.Url)]
public object SalesPerson { get; set; }
[DisplayName("Last")]
[DataTypeAttribute("BoldRed")]
[RegularExpression(@"^[a-zA-Z''-'\s]{1,40}$",
ErrorMessage = "Characters are not allowed.")]
public object LastName { get; set; }
}
この例では、EmailAddress プロパティの DataTypeAttribute 属性が EmailAddress() に設定されます。SalesPerson プロパティの DataTypeAttribute 属性は Url() に設定されます。また、LastName プロパティの DataTypeAttribute 属性は BoldRed に設定されます。BoldRed は、カスタム プロパティとして定義されています。
コードのコンパイル方法
このコード例をコンパイルするには、以下が必要です。
Microsoft Visual Studio 2008 Service Pack 1 または Visual Web Developer 2008 Express Edition Service Pack 1。
AdventureWorksLT サンプル データベース。SQL Server のサンプル データベースをダウンロードしてインストールする方法については、CodePlex サイトの「Microsoft SQL Server Product Samples: Database」を参照してください。実行している SQL Server のバージョン (Microsoft SQL Server 2005 または Microsoft SQL Server 2008) に対応した正しいバージョンのサンプル データベースをインストールしてください。
動的なデータ ドリブン Web サイト。これにより、カスタマイズするデータ フィールドおよびオーバーライドするメソッドを持つクラスと、データベースのデータ コンテキストを作成できます。詳細については、「Walkthrough: Creating a New Dynamic Data Web Site using Scaffolding」を参照してください。
参照
処理手順
方法 : ASP.NET Dynamic Data の既定のフィールド テンプレートをカスタマイズする
履歴の変更
日付 |
履歴 |
理由 |
---|---|---|
2008 年 7 月 |
トピックを追加 |
SP1 機能変更 |