Condividi tramite


Procedura: personalizzare l'aspetto e il comportamento dei campi dati per tipi di dati non intrinseci nel modello di dati

Aggiornamento: Luglio 2008

Quando si utilizza ASP.NET Dynamic Data, è possibile utilizzare l'attributo System.ComponentModel.DataAnnotations.DataTypeAttribute per assegnare un tipo di dati a un campo del modello di dati. Questa operazione si rivela utile se si desidera assegnare un tipo più specifico di tale campo dati rispetto al tipo CLR dedotto da Dynamic Data.

Ad esempio, è possibile contrassegnare un campo di testo che contiene indirizzi di posta elettronica come tipo di posta elettronica, che verrebbe definito come tipo specifico di testo. Il modello di campo di testo che elabora il campo può utilizzare le informazioni fornite da questo attributo per creare un'interfaccia utente speciale per la visualizzazione e la modifica del tipo di posta elettronica. Un campo di testo contrassegnato con l'attributo EmailAddress() potrebbe essere visualizzato come controllo System.Web.UI.WebControls.HyperLink.

È anche possibile utilizzare un modello di campo personalizzato insieme all'attributo UIHint per definire una gestione specifica per determinati tipi di dati. L'attributo DataTypeAttribute consente di utilizzare un unico modello di campo per diversi tipi.

La decisione di utilizzare l'attributo DataTypeAttribute o l'attributo UIHint è spesso determinata da considerazioni di stile e praticità. Per informazioni sull'utilizzo della proprietà UIHint, vedere Procedura: personalizzare i modelli di campo predefiniti di ASP.NET Dynamic Data.

In questo argomento viene descritto come utilizzare l'attributo DataTypeAttribute.

Per associare attributi del tipo di dati a un campo dati

  1. Aprire il sito Web ASP.NET nel punto in cui si desidera personalizzare i campi dati.

    Nota:

    Il sito Web deve essere configurato per Dynamic Data.

  2. In Esplora soluzioni fare clic con il pulsante destro del mouse sulla cartella App_Code, quindi scegliere Aggiungi nuovo elemento.

  3. In Modelli installati fare clic su Classe.

  4. Nella casella Nome immettere un nome per il file.

    Il nome della classe creata deve corrispondere a quello della classe di entità che rappresenta la tabella. Ad esempio, se si utilizza la tabella Customer, assegnare alla classe il nome Customer.

  5. Aggiungere la parola chiave Partial in Visual Basic o la parola chiave partial in Visual C# alla definizione della classe per renderla una classe parziale.

  6. Aggiungere riferimenti agli spazi dei nomi System.ComponentModel e System.ComponentModel.DataAnnotations utilizzando la parola chiave Imports in Visual Basic o la parola chiave using in Visual C#, come illustrato nell'esempio seguente:

    using System.ComponentModel;
    using System.ComponentModel.DataAnnotations;
    
    Imports System.ComponentModel
    Imports System.ComponentModel.DataAnnotations 
    
  7. Aggiungere una funzione di accesso a proprietà per ogni campo dati per il quale si desidera fornire attributi.

    Nell'esempio riportato di seguito viene illustrato come creare funzioni di accesso a proprietà per tre proprietà che corrispondono ai campi nella tabella Customer.

    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
    
  8. Creare un'altra classe che fungerà da classe di metadati associata per la classe parziale. È possibile assegnare alla classe qualsiasi nome che non sia già utilizzato. Ad esempio, è possibile creare una classe con il nome CustomerMetaData come la classe di metadati associata per la classe Customer.

  9. Aggiungere l'attributo MetadataTypeAttribute alla definizione della classe parziale. Per il parametro dell'attributo utilizzare il nome della classe di metadati associata creata nel passaggio precedente.

    [MetadataType(typeof(CustomerMetaData))]
    public partial class Customer {
    
    }
    
    <MetadataType(GetType(CustomerMetaData))> _
    Partial Public Class Customer
    
    End Class
    
  10. Nella classe di metadati aggiungere attributi DataAnnotations a ogni campo di cui si desidera modificare la visualizzazione o il comportamento.

    Nell'esempio riportato di seguito vengono illustrate una classe parziale completata per la tabella Customer e una classe di metadati associata denominata CustomerMetaData. La classe di metadati contiene campi di classe pubblici che corrispondono ai campi del database. I campi PasswordHash e PasswordSalt vengono contrassegnati con l'attributo ScaffoldColumnattribute, impostato su false. In tal modo si impedisce la visualizzazione dei campi da parte di Dynamic Data. Il campo ModifiedDate viene contrassegnato con l'attributo DataType il cui valore è impostato su DataType.Date. In tal modo si specifica che i dati di questo campo vengono visualizzati mediante il formato di data breve.

    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
    
  11. Per assicurarsi che la classe parziale, la classe di metadati e gli attributi funzionino, eseguire l'applicazione e visualizzare la tabella.

Per modificare un modello di campo in modo da utilizzare attributi di dati personalizzati

  1. Aprire il modello di campo che si desidera personalizzare. Se si desidera personalizzare un modello incorporato, aprire il modello di campo che corrisponde al tipo di dati a cui Dynamic Data esegue il mapping dei dati.

    Ad esempio, se si personalizza il modello di campo utilizzato per visualizzare le stringhe, aprire Text.ascx nella directory DynamicData\FieldTemplates.

  2. Se necessario, modificare il markup.

  3. Nel file code-behind eseguire l'override del metodo OnDataBinding, chiamato quando il controllo del modello di campo ottiene i dati da visualizzare. Nel metodo ottenere l'attributo o gli attributi per il campo dati corrente dalla proprietà MetadataAttributes della classe FieldTemplateUserControl da cui deriva il modello di campo. È quindi possibile formattare o elaborare i dati in base agli attributi con cui è contrassegnato il campo.

    Nell'esempio riportato di seguito viene illustrato il codice utilizzabile nel modello di campo Text.ascx per visualizzare i campi dati precedentemente modificati in questo argomento.

    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);
            }
    
        }
    
    }
    

    Gli attributi per il campo corrente vengono ottenuti nel codice, che li testa ed esegue una logica diversa a seconda dell'attributo con cui è stato contrassegnato il campo. Ad esempio, il codice può determinare che il campo è contrassegnato con l'attributo BoldRed personalizzato eseguento il test di Custom() e verificando che la proprietà CustomDataType() è "BoldRed". In tal caso, il codice crea un'interfaccia utente per visualizzare i dati in un controllo Label che ha l'aspetto di un testo di colore rosso.

Esempio

Nell'esempio riportato di seguito viene illustrato come personalizzare l'aspetto e il comportamento dei campi dati per tipi di dati non intrinseci. Nel codice viene personalizzato il modo in cui Dynamic Data visualizza i campi EmailAddress, SalesPerson e LastName della tabella Customer del database AdventureWorksLT.

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; }
} 

Nell'esempio l'attributo DataTypeAttribute è impostato su EmailAddress() per la proprietà EmailAddress. L'attributo DataTypeAttribute è impostato su Url() per la proprietà SalesPerson e l'attributo DataTypeAttribute è impostato su BoldRed per la proprietà LastName. BoldRed viene definita come proprietà personalizzata.

Compilazione del codice

Per compilare il codice di esempio, è necessario quanto segue:

  • Microsoft Visual Studio 2008 Service Pack 1 o Visual Web Developer 2008 Express Edition Service Pack 1. 

  • Database di esempio AdventureWorksLT. Per informazioni su come scaricare e installare il database di esempio di SQL Server, vedere Microsoft SQL Server Product Samples: Database (informazioni in lingua inglese) nel sito Web CodePlex. Assicurarsi di installare la versione del database di esempio appropriata per la versione di SQL Server in esecuzione (Microsoft SQL Server 2005 o Microsoft SQL Server 2008).

  • Sito Web basato su dati dinamici, che consente di creare un contesto dati per il database nonché la classe che contiene il campo dati da personalizzare e i metodi di cui eseguire l'override. Per ulteriori informazioni, vedere la classe Walkthrough: Creating a New Dynamic Data Web Site using Scaffolding.

Vedere anche

Attività

Procedura: personalizzare i modelli di campo predefiniti di ASP.NET Dynamic Data

Cronologia delle modifiche

Date

History

Motivo

Luglio 2008

Argomento aggiunto.

Modifica di funzionalità in SP1.