Compartir a través de


Cómo: Personalizar la apariencia y el comportamiento de los campos de datos para tipos de datos no intrínsecos en el modelo de datos

Actualización: Julio de 2008

Al trabajar con datos dinámicos de ASP.NET, puede utilizar el atributo System.ComponentModel.DataAnnotations.DataTypeAttribute para asignar un tipo de datos a un campo de modelo de datos. Esto resulta útil si desea asignar a ese campo de datos un tipo que sea más específico que el tipo CLR, el cual deducen los datos dinámicos.

Por ejemplo, puede marcar un campo de texto que contiene direcciones de correo electrónico como un tipo de correo electrónico, el cual se definiría como un tipo de texto específico. La plantilla de campo de texto que procesa el campo puede utilizar la información proporcionada por este atributo para crear una interfaz de usuario especial para mostrar y editar el tipo de correo electrónico. Un campo de texto marcado con el atributo EmailAddress() se podría mostrar como un control System.Web.UI.WebControls.HyperLink.

También puede utilizar una plantilla de campo personalizada junto con el atributo UIHint para especificar el control especializado de tipos de datos específicos. El atributo DataTypeAttribute le permite utilizar una plantilla de campo para varios tipos.

La decisión de utilizar el atributo DataTypeAttribute o el atributo UIHint depende a menudo del estilo y de la comodidad. Para obtener información sobre cómo utilizar la propiedad UIHint, vea Cómo: Personalizar las plantillas de campos predeterminados de datos dinámicos de ASP.NET.

En este tema se describe cómo usar el atributo DataTypeAttribute.

Para asociar los atributos de tipo de datos a un campo de datos

  1. Abra el sitio web ASP.NET en el que desea personalizar los campos de datos.

    Nota:

    El sitio web se debe configurar para los datos dinámicos.

  2. En el Explorador de soluciones, haga clic con el botón secundario en la carpeta App_Code y, a continuación, haga clic en Agregar nuevo elemento.

  3. En Plantillas instaladas, haga clic en Clase.

  4. Escriba un nombre para el archivo en el cuadro Nombre.

    El nombre de la clase que cree deberá coincidir con el nombre de clase de entidad que representa la tabla. Por ejemplo, si está trabajando con la tabla Customer, asigne a la clase el nombre Customer.

  5. Agregue la palabra clave Partial de Visual Basic o la palabra clave partial de Visual C# a la definición de clase para convertirla en una clase parcial.

  6. Agregue referencias a los espacios de nombres System.ComponentModel y System.ComponentModel.DataAnnotations utilizando la palabra clave Imports de Visual Basic o la palabra clave using de Visual C#, tal y como se muestra en el siguiente ejemplo:

    using System.ComponentModel;
    using System.ComponentModel.DataAnnotations;
    
    Imports System.ComponentModel
    Imports System.ComponentModel.DataAnnotations 
    
  7. Agregue un descriptor de acceso de propiedad a cada campo de datos para el que desee proporcionar atributos.

    En el ejemplo siguiente se muestra cómo crear descriptores de acceso de propiedad para tres propiedades que corresponden a campos de la tabla 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. Cree otra clase que actuará como la clase de metadatos asociada de la clase parcial. Puede asignar a la clase cualquier nombre que aún no se utilice. Por ejemplo, puede crear una clase que tenga el nombre CustomerMetaData como la clase de metadatos asociada de la clase Customer.

  9. Agregue el atributo MetadataTypeAttribute a la definición de clase parcial. Para el parámetro del atributo, utilice el nombre de la clase de metadatos asociada que creó en el paso anterior.

    [MetadataType(typeof(CustomerMetaData))]
    public partial class Customer {
    
    }
    
    <MetadataType(GetType(CustomerMetaData))> _
    Partial Public Class Customer
    
    End Class
    
  10. En la clase de metadatos, agregue los atributos DataAnnotations a cada campo cuya presentación o comportamiento desee modificar.

    El ejemplo siguiente muestra una clase parcial acabada de la tabla Customer y una clase de metadatos asociada denominada CustomerMetaData. La clase de metadatos contiene campos de clase pública que coinciden con campos de base de datos. Los campos PasswordHash y PasswordSalt se marcan con el atributo ScaffoldColumnattribute, que está establecido en false. Esto evita que los datos dinámicos muestren los campos. El campo ModifiedDate se marca con el atributo DataType cuyo valor está establecido en DataType.Date. Esto especifica que los datos de este campo se muestren utilizando el formato de fecha corta.

    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. Para asegurarse de que la clase parcial, la clase de metadatos y los atributos están funcionando, ejecute la aplicación y muestre la tabla.

Para modificar una plantilla de campo para utilizar atributos de datos personalizados

  1. Abra la plantilla de campo que desee personalizar. Si desea personalizar una plantilla integrada, abra la plantilla de campo que corresponda al tipo de datos al que asignan los datos dinámicos.

    Por ejemplo, si está personalizando la plantilla de campo que se utiliza para mostrar las cadenas, abra Text.ascx en el directorio DynamicData\FieldTemplates.

  2. Si es necesario, cambie el marcado.

  3. En el archivo de código subyacente, invalide el método OnDataBinding, que se llama cuando el control de plantilla de campo obtiene los datos que se desean mostrar. En el método, obtenga el atributo o atributos del campo de datos actual a partir de la propiedad MetadataAttributes de la clase FieldTemplateUserControl de la que procede la plantilla de campo. A continuación, puede dar formato o procesar los datos según los atributos con los que está marcado el campo.

    En el ejemplo siguiente se muestra el código que se puede utilizar en la plantilla de campo Text.ascx para mostrar los campos de datos que se modificaron anteriormente en este tema.

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

    El código obtiene los atributos del campo actual. Prueba los atributos y ejecuta una lógica diferente, dependiendo del atributo con el que está marcado el campo. Por ejemplo, el código puede determinar si el campo está marcado con el atributo personalizado BoldRed comprobando Custom() y, a continuación, probando que la propiedad CustomDataType() es "BoldRed". Si lo es, el código crea una interfaz de usuario para mostrar los datos en un control Label que tiene un estilo de texto rojo.

Ejemplo

En el ejemplo siguiente se muestra cómo personalizar el aspecto del campo de datos y el comportamiento de los tipos de datos no intrínsecos. El código personaliza cómo muestran los datos dinámicos los campos EmailAddress, SalesPerson y LastName de la tabla Customer de la base de datos 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; }
} 

En el ejemplo, el atributo DataTypeAttribute está establecido en EmailAddress() para la propiedad EmailAddress. El atributo DataTypeAttribute está establecido en Url() para la propiedad SalesPerson y el atributo DataTypeAttribute está establecido en BoldRed para la propiedad LastName. BoldRed se define como una propiedad personalizada.

Compilar el código

Para compilar el código de ejemplo, necesita:

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

  • La base de datos de ejemplo AdventureWorksLT. Para obtener información sobre la forma de descargar e instalar la base de datos de ejemplo de SQL Server, vea Microsoft SQL Server Product Samples: Database en el sitio CodePlex. Asegúrese de que instala la versión correcta de la base de datos de ejemplo para la versión de SQL Server que esté ejecutando (Microsoft SQL Server 2005 o Microsoft SQL Server 2008).

  • Un sitio web dinámico controlado por datos. De este modo, se puede crear un contexto de datos para la base de datos y crear la clase que contiene el campo de datos que se va a personalizar y los métodos que se van a invalidar. Para obtener más información, vea Walkthrough: Creating a New Dynamic Data Web Site using Scaffolding.

Vea también

Tareas

Cómo: Personalizar las plantillas de campos predeterminados de datos dinámicos de ASP.NET

Historial de cambios

Fecha

Historial

Motivo

Julio de 2008

Se ha agregado un tema.

Cambio de características de SP1.