Gewusst wie: Anpassen der Darstellung und des Verhaltens von Datenfeldern für nicht systeminterne Datentypen im Datenmodell
Aktualisiert: Juli 2008
Wenn Sie mit ASP.NET Dynamic Data arbeiten, können Sie das System.ComponentModel.DataAnnotations.DataTypeAttribute-Attribut verwenden, um einem Datenmodellfeld einen Datentyp zuzuweisen. Dies bietet sich an, wenn Sie einen Typ zuweisen möchten, der sich besser für dieses Datenfeld eignet als der von Dynamic Data abgeleitete CLR-Typ.
Sie können beispielsweise ein Textfeld, das E-Mail-Adressen enthält, als E-Mail-Typ markieren, der als spezieller Texttyp definiert würde. Die Textfeldvorlage, die das Feld verarbeitet, kann mit den von diesem Attribut bereitgestellten Informationen eine spezielle Benutzeroberfläche zum Anzeigen und Bearbeiten des E-Mail-Typs erstellen. Ein Textfeld, das mit dem EmailAddress()-Attribut markiert wird, könnte als System.Web.UI.WebControls.HyperLink-Steuerelement angezeigt werden.
Sie können eine benutzerdefinierte Feldvorlage auch mit dem UIHint-Attribut verwenden, um eine besondere Behandlung für bestimmte Datentypen anzugeben. Mit dem DataTypeAttribute-Attribut können Sie eine Feldvorlage für mehrere Typen verwenden.
Die Entscheidung für die Verwendung des DataTypeAttribute-Attributs oder des UIHint-Attributs ist häufig eine Frage des Formats und der Bequemlichkeit. Informationen zur Verwendung der UIHint-Eigenschaft finden Sie unter Gewusst wie: Anpassen von ASP.NET Dynamic Data-Standardfeldvorlagen.
Unter diesem Thema wird die Verwendung des DataTypeAttribute-Attributs beschrieben.
So ordnen Sie Datentypattribute einem Datenfeld zu
Öffnen Sie die ASP.NET-Website, auf der Sie Datenfelder anpassen möchten.
Hinweis: Die Website muss für Dynamic Data konfiguriert sein.
Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf den Ordner App_Code, und klicken Sie dann auf Neues Element hinzufügen.
Klicken Sie unter Installierte Vorlagen auf Klasse.
Geben Sie im Feld Name einen Namen für die Datei ein.
Der Name der Klasse, die Sie erstellen, muss mit dem Namen der Entitätsklasse übereinstimmen, die die Tabelle darstellt. Wenn Sie z. B. mit der Customer-Tabelle arbeiten, nennen Sie die Klasse Customer.
Fügen Sie das Partial-Schlüsselwort in Visual Basic bzw. das partial-Schlüsselwort in Visual C# der Klassendefinition hinzu, um eine partielle Klasse zu erstellen.
Fügen Sie dem System.ComponentModel-Namespace und dem System.ComponentModel.DataAnnotations-Namespace mithilfe des Imports-Schlüsselworts in Visual Basic oder des using-Schlüsselworts in Visual C# Verweise hinzu, wie im folgenden Beispiel gezeigt:
using System.ComponentModel; using System.ComponentModel.DataAnnotations;
Imports System.ComponentModel Imports System.ComponentModel.DataAnnotations
Fügen Sie einen Eigenschaftenaccessor für jedes Datenfeld hinzu, für das Sie Attribute bereitstellen möchten.
Im folgenden Beispiel ist dargestellt, wie Eigenschaftenaccessoren für drei Eigenschaften erstellt werden, die Feldern in der Customer-Tabelle entsprechen.
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
Erstellen Sie eine andere Klasse, die als zugeordnete Metadatenklasse für die partielle Klasse fungiert. Sie können der Klasse einen beliebigen Namen geben, der noch nicht verwendet wird. Sie können z. B. eine Klasse mit dem Namen CustomerMetaData als zugeordnete Metadatenklasse für die Customer-Klasse erstellen.
Fügen Sie der partiellen Klassendefinition das MetadataTypeAttribute-Attribut hinzu. Verwenden Sie als Parameter für das Attribut den Namen der zugeordneten Metadatenklasse, die Sie im vorhergehenden Schritt erstellt haben.
[MetadataType(typeof(CustomerMetaData))] public partial class Customer { }
<MetadataType(GetType(CustomerMetaData))> _ Partial Public Class Customer End Class
In der Metadatenklasse fügen Sie DataAnnotations-Attribute jedem Feld hinzu, dessen Anzeige oder Verhalten Sie ändern möchten.
Im folgenden Beispiel wird eine fertige partielle Klasse für die Customer-Tabelle und die zugeordnete Metadatenklasse CustomerMetaData dargestellt. Die Metadatenklasse enthält öffentliche Klassenfelder, die mit Datenbankfeldern übereinstimmen. Das PasswordHash-Feld und das PasswordSalt-Feld werden mit dem ScaffoldColumnattribute-Attribut markiert, das auf false festgelegt wird. Dadurch wird verhindert, dass die Felder von Dynamic Data angezeigt werden. Das ModifiedDate-Feld wird mit dem DataType-Attribut markiert, dessen Wert auf DataType.Date festgelegt wird. Dies gibt an, dass die Daten für dieses Feld mit dem kurzen Datumsformat angezeigt werden.
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
Um sicherzustellen, dass die partielle Klasse, die Metadatenklasse und die Attribute funktionieren, führen Sie die Anwendung aus und zeigen die Tabelle an.
So ändern Sie eine Feldvorlage für die Verwendung benutzerdefinierter Datenattribute
Öffnen Sie die Feldvorlage, die Sie anpassen möchten. Wenn Sie eine integrierte Vorlage anpassen möchten, öffnen Sie die Feldvorlage, die dem Datentyp entspricht, dem Dynamic Data die Daten zuordnet.
Wenn Sie z. B. die Feldvorlage anpassen, die zum Anzeigen von Zeichenfolgen verwendet wird, öffnen Sie Text.ascx im Verzeichnis DynamicData\FieldTemplates.
Ändern Sie gegebenenfalls das Markup.
Überschreiben Sie in der Code-Behind-Datei die OnDataBinding-Methode, die aufgerufen wird, wenn das Feldvorlagensteuerelement die anzuzeigenden Daten abruft. Rufen Sie in der Methode das bzw. die Attribute für das aktuelle Datenfeld aus der MetadataAttributes-Eigenschaft der FieldTemplateUserControl-Klasse ab, aus der die Feldvorlage stammt. Anschließend können Sie die Daten gemäß den Attributen, mit denen das Feld markiert ist, formatieren oder bearbeiten.
Im folgenden Beispiel ist der Code dargestellt, der in der Feldvorlage Text.ascx zum Anzeigen der Datenfelder verwendet werden kann, die früher in diesem Thema geändert wurden.
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); } } }
Der Code ruft die Attribute für das aktuelle Feld ab. Er testet die Attribute und führt in Abhängigkeit von dem Attribut, mit dem das Feld markiert wurde, eine andere Logik aus. Der Code kann beispielsweise festlegen, dass das Feld mit dem benutzerdefinierten BoldRed-Attribut markiert wird, indem er auf Custom() testet und dann prüft, ob die CustomDataType()-Eigenschaft "BoldRed" lautet. Wenn dies der Fall ist, erstellt der Code eine Benutzeroberfläche zum Anzeigen der Daten in einem Label-Steuerelement, das als roter Text formatiert ist.
Beispiel
Im folgenden Beispiel ist veranschaulicht, wie die Darstellung und das Verhalten von Datenfeldern für nicht systeminterne Datentypen angepasst werden. Der Code passt die Anzeige der Felder EmailAddress, SalesPerson und LastName in der Customer-Tabelle der AdventureWorksLT-Datenbank durch Dynamic Data an.
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; }
}
Im Beispiel wird das DataTypeAttribute-Attribut auf EmailAddress() für die EmailAddress-Eigenschaft festgelegt. Das DataTypeAttribute-Attribut wird auf Url() für die SalesPerson-Eigenschaft festgelegt, und das DataTypeAttribute-Attribut wird auf BoldRed für die LastName-Eigenschaft festgelegt. BoldRed ist als benutzerdefinierte Eigenschaft definiert.
Kompilieren des Codes
Zum Kompilieren des Beispielcodes benötigen Sie Folgendes:
Microsoft Visual Studio 2008 Service Pack 1 oder Visual Web Developer 2008 Express Edition Service Pack 1
Die AdventureWorksLT-Beispieldatenbank. Informationen über das Herunterladen und Installieren der SQL Server-Beispieldatenbank finden Sie auf der CodePlex-Website unter Microsoft SQL Server Product Samples: Database. Vergewissern Sie sich, dass Sie die richtige Version der Beispieldatenbank für die von Ihnen verwendete SQL Server-Version (Microsoft SQL Server 2005 oder Microsoft SQL Server 2008) installieren.
Eine dynamische datengesteuerte Website. So können Sie einen Datenkontext für die Datenbank erstellen und die Klasse erstellen, die das anzupassende Datenfeld und die zu überschreibenden Methoden enthält. Weitere Informationen hierzu finden Sie unter Walkthrough: Creating a New Dynamic Data Web Site using Scaffolding.
Siehe auch
Aufgaben
Gewusst wie: Anpassen von ASP.NET Dynamic Data-Standardfeldvorlagen
Änderungsprotokoll
Date |
Versionsgeschichte |
Grund |
---|---|---|
Juli 2008 |
Thema hinzugefügt. |
SP1-Featureänderung. |