Compartilhar via


Como: Personalizar a validação de campo de dados no modelo de dados usando atributos personalizados

Dados dinâmicos do ASP.NET permite que você personalize e estenda a validação de campo de dados no nível de camada de dados.Este tópico mostra como você pode adicionar validação de campo de dados no modelo de dados, fazendo o seguinte:

  • Criando um atributo de validação personalizada.Este atributo permite criar metadados personalizados que você usar no modelo de dados para validação.

  • Aplicando o atributo de validação personalizada.Depois que o atributo personalizado é criado, você pode aplicá-lo para os campos de dados que você deseja validar.

Executar um exemplo desse recurso online.

Criação de um atributo de validação personalizada

Um atributo de validação personalizada permite que você criar metadados que você pode usar no modelo de dados para validar campos de dados.Você deve derivar o atributo personalizado do ValidationAttribute classe base.

Para criar um atributo de validação personalizada

  1. In O gerenciador de soluções, clicar com o botão direito do mouse na posta App_Code pasta e, em seguida, clique em Adicionar novo item.

  2. Em Adicionar novo item, clicar Classe.

    No Nome, digite o nome da validação personalizada atributo classe.Você pode usar qualquer nome que já não está sendo usado.Por exemplo, você pode inserir o nome CustomAttribute.vb em Visual C# ou CustomAttribute.vb em Visual Basic Para criar uma classe de atributos personalizado chamada CustomAttribute.

  3. Adicionar referências para o System, System.Web.Globalization, e System.ComponentModel.DataAnnotations espaços para nome usando o Imports palavra-chave em Visual Basic ou o using palavra-chave em Visual C#, conforme mostrado no exemplo a seguir:

    using System;
    using System.Globalization;
    using System.ComponentModel.DataAnnotations;
    
    Imports System
    Imports System.Globalization
    Imports System.ComponentModel.DataAnnotations
    
  4. Faça as seguintes alterações à definição de classe:

    • Fazer com que a classe não herdável.Adicionar o NotInheritable palavra-chave em Visual Basic ou o sealed palavra-chave em Visual C#.

    • Derivar a classe do ValidationAttribute tipo de base.

    • Aplicar o AttributeUsageAttribute o atributo à definição de classe para indicar como o atributo de validação personalizada deve ser usado.

    O exemplo a seguir mostra uma definição de classe.The AttributeUsageAttribute parâmetros são definidos para que o atributo de validação personalizada pode ser aplicado a propriedades ou campos apenas uma vez.

    [AttributeUsage(AttributeTargets.Property | 
      AttributeTargets.Field, AllowMultiple = false)]
    sealed public class CustomAttribute : ValidationAttribute
    {
    
    }
    
    <AttributeUsage(AttributeTargets.[Property] Or _
        AttributeTargets.Field, AllowMultiple := False)> _
    Public NotInheritable Class CustomAttribute
        Inherits ValidationAttribute
    ....
    End Class
    
  5. Substituir o IsValid método e adicione lógica para realizar a validação. Retornartrue Se for bem-sucedida, a validação personalizada ou false em caso de falha. O valor a ser validado é passado para o método sistema autônomo o único parâmetro.

    O exemplo a seguir mostra o método substituído.

    public override bool IsValid(object value)
    {
      bool result = true;
      // Add validation logic here.
      return result;
    }
    
    Public Overrides Function IsValid( _
        ByVal value As Object) As Boolean
          ' Add validation logic here.
      Return result
    End Function
    
  6. Opcionalmente, substituir o FormatErrorMessage método para executar a mensagem de erro personalizada de formatação.

    O exemplo a seguir mostra como usar o nome do campo de dados com falha na validação para criar uma mensagem de erro personalizada.The ErrorMessageString valor é passado sistema autônomo um parâmetro quando o atributo personalizado é aplicado ao campo de dados.

    public override string FormatErrorMessage(string name)
    {
      return String.Format(CultureInfo.CurrentCulture, 
        ErrorMessageString, name);
    }
    
    Public Overrides Function FormatErrorMessage( _
        ByVal name As String) As String
          Return [String].Format(CultureInfo.CurrentCulture, _
            ErrorMessageString, name)
    End Function
    
  7. salvar e fechar o arquivo de atributo de classe.

Aplicar um atributo de validação personalizada

Para personalizar a validação para um campo de dados, você deve implementar uma classe parcial que estende o modelo de dados.Isso permite que você aplicar o atributo personalizado para o campo de dados.

Para criar uma classe parcial para validação

  1. In O gerenciador de soluções, clicar com o botão direito do mouse na posta App_Code pasta e, em seguida, clique em Adicionar novo item.

  2. Em Visual Studio installed templates, clique em Class.

    No Nome, digite o nome da tabela de banco de dados que deseja adicionar validação para.

    O nome da classe deve corresponder ao nome de classe de entidade que representa a tabela.Por exemplo, se desejar adicionar validação para a tabela clientes, deve nomear o arquivo cliente.cs em Visual C# ou cliente.vb em Visual Basice o nome da classe Customer.

  3. Adicionar o Partial palavra-chave em Visual Basic ou o partial palavra-chave em Visual C# a definição de classe para torná-lo em uma classe parcial.

  4. Se você estiver criando a classe em Visual C#, exclua o construtor padrão.

    O exemplo a seguir mostra a declaração de classe atualizada.

    public partial class Customer {
    
    }
    
    Partial Public Class Customer
    
    End Class
    
  5. Adicionar referências para o System.Web.DynamicData e System.ComponentModel.DataAnnotations espaços para nome usando o Imports palavra-chave em Visual Basic ou o using palavra-chave em Visual C#, conforme mostrado no exemplo a seguir:

    using System.Web.DynamicData;
    using System.ComponentModel.DataAnnotations;
    
    Imports System.Web.DynamicData
    Imports System.ComponentModel.DataAnnotations
    
  6. No mesmo arquivo, crie uma classe segundo que atuará sistema autônomo a classe de metadados associados.Você pode usar qualquer nome para a classe que é um nome de classe válido e que já não está sendo usado.

    O exemplo a seguir mostra uma declaração de classe de metadados.

    public class CustomerMetadata
    {
    
    }
    
    Public Class CustomerMetadata 
    
    End Class
    

    A classe de metadados associados fornece um objeto que você pode aplicar atributos de validação.

  7. Aplicar o MetadataTypeAttribute o atributo à definição de classe parcial. O atributo do parâmetro, use o nome da classe metadados associados que você criou na etapa anterior.

    O exemplo a seguir mostra a definição de classe parcial com atribuída adicionado.

    [MetadataType(typeof(CustomerMetadata))]
    public partial class Customer {
    
    }
    
    <MetadataType(GetType(CustomerMetadata))> _
    Partial Public Class Customer
    
    End Class
    

Agora você pode aplicar o atributo de validação personalizada a um campo de dados.

Para aplicar um atributo de validação personalizada a um campo de dados

  1. Na classe metadados, criar uma propriedade ou campo cujo nome corresponde ao campo de dados para validar.

  2. Aplicar o atributo de validação personalizada que você criou anteriormente para o campo de dados que você deseja validar.

    O exemplo a seguir mostra como aplicar o atributo de validação personalizada para o campo de dados do telefone.

    public partial class CustomerMetadata
    {
      [CustomAttribute(parm1,
        ErrorMessage = "{0} field validation failed.")]
      public object Phone; 
    }
    
    Public Class CustomerMetadata 
      <PhoneMask(parm1, _
        ErrorMessage:="{0} field validation failed.")> _
      Public Phone As Object
    End Class
    
  3. Salve e feche o arquivo de classe.

Exemplo

O exemplo a seguir mostra como criar e aplicar um atributo personalizado chamado PhoneMaskAttribute para o campo de dados do telefone da tabela cliente no banco de dados AdventureWorksLT. O exemplo usa uma classe LINQ para SQL para o modelo de dados.

O atributo instrui dados dinâmicos para validar o campo de dados de telefone com uma máscara que representa um formato de número de telefone específico.Se o número de telefone digitado pelo usuário não coincidir com a máscara, o código de atributo emitirá um erro personalizado.

Imports Microsoft.VisualBasic
Imports System
Imports System.Globalization
Imports System.ComponentModel.DataAnnotations

<AttributeUsage(AttributeTargets.[Property] Or AttributeTargets.Field, AllowMultiple:=False)> _
Public NotInheritable Class PhoneMaskAttribute
    Inherits ValidationAttribute

    ' Internal field to hold the mask value.
    ReadOnly _mask As String
    Public ReadOnly Property Mask() As String
        Get
            Return _mask
        End Get
    End Property

    Public Sub New(ByVal mask As String)
        _mask = mask
    End Sub

    Public Overrides Function IsValid( _
    ByVal value As Object) As Boolean
        Dim phoneNumber As String = DirectCast(value, String)
        Dim result As Boolean = True
        If Me.Mask <> Nothing Then
            result = MatchesMask(Me.Mask, phoneNumber)
        End If
        Return result
    End Function

    ' Checks if the entered phone number matches the mask.
    Public Shared Function MatchesMask(ByVal mask As String, _
        ByVal phoneNumber As String) As Boolean
        If mask.Length <> phoneNumber.Trim().Length Then
            ' Length mismatch.
            Return False
        End If
        Dim i As Integer = 0
        While i < mask.Length
            If mask(i) = "d"c _
             AndAlso Char.IsDigit(phoneNumber(i)) = False Then
                ' Digit expected at this position.      
                Return False
            End If
            If mask(i) = "-"c AndAlso phoneNumber(i) <> "-"c Then
                ' Spacing character expected at this position.
                Return False
            End If
            System.Math.Max(System.Threading.Interlocked.Increment(i), i - 1)
        End While
        Return True
    End Function

    Public Overrides Function FormatErrorMessage( _
    ByVal name As String) As String
        Return [String].Format(CultureInfo.CurrentCulture, _
          ErrorMessageString, name, Me.Mask)
    End Function


End Class

using System;
using System.Globalization;
using System.ComponentModel.DataAnnotations;


[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
sealed public class PhoneMaskAttribute : ValidationAttribute
{
    // Internal field to hold the mask value.
    readonly string _mask;

    public string Mask
    {
        get { return _mask; }
    }

    public PhoneMaskAttribute(string mask)
    {
        _mask = mask;
    }


    public override bool IsValid(object value)
    {
        var phoneNumber = (String)value;
        bool result = true;
        if (this.Mask != null)
        {
            result = MatchesMask(this.Mask, phoneNumber);
        }
        return result;
    }

    // Checks if the entered phone number matches the mask.
    internal bool MatchesMask(string mask, string phoneNumber)
    {
        if (mask.Length != phoneNumber.Trim().Length)
        {
            // Length mismatch.
            return false;
        }
        for (int i = 0; i < mask.Length; i++)
        {
            if (mask[i] == 'd' && char.IsDigit(phoneNumber[i]) == false)
            {
                // Digit expected at this position.
                return false;
            }
            if (mask[i] == '-' && phoneNumber[i] != '-')
            {
                // Spacing character expected at this position.
                return false;
            }
        }
        return true;
    }

    public override string FormatErrorMessage(string name)
    {
        return String.Format(CultureInfo.CurrentCulture,
          ErrorMessageString, name, this.Mask);
    }

}
Imports Microsoft.VisualBasic
Imports System.Web.DynamicData
Imports System.ComponentModel.DataAnnotations

<MetadataType(GetType(CustomerMetadata))> _
Partial Public Class Customer

End Class

Public Class CustomerMetadata
    <PhoneMask("999-999-9999", _
    ErrorMessage:="{0} field value does not match the mask {1}.")> _
  Public Phone As Object

End Class
using System.Web.DynamicData;
using System.ComponentModel.DataAnnotations;

[MetadataType(typeof(CustomerMetadata))]
public partial class Customer
{

}

public class CustomerMetadata
{
    [PhoneMask("999-999-9999",
        ErrorMessage = "{0} value does not match the mask {1}.")]
    public object Phone; 
}
<%@ Page Language="VB" 
AutoEventWireup="true" CodeFile="CustomAttributeValidation.aspx.vb" 
Inherits="CustomAttributeValidation" %>


<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" >
    <title></title>
    <link href="~/Site.css" rel="stylesheet" type="text/css" />
</head>
<body>
     <h2>Example: <%=Title%></h2>

     <!-- Enable dynamic behavior. The GridView must be 
     registered with the manager. See code-behind file. -->
    <asp:DynamicDataManager ID="DynamicDataManager1" 
        AutoLoadForeignKeys="true" />


    <form id="form1" >

        <!-- Capture validation exceptions -->
        <asp:DynamicValidator ID="ValidatorID" ControlToValidate="GridView1" 
             /> 

        <asp:GridView ID="GridView1" 
             
            DataSourceID="GridDataSource" 
            AutoGenerateColumns="false"  
            AutoGenerateEditButton="true"
            AllowPaging="true"
            PageSize="10"
            AllowSorting="true">
            <Columns>
                <asp:DynamicField DataField="FirstName" />
                <asp:DynamicField DataField="LastName" />
                <asp:DynamicField DataField="Phone" />
            </Columns>
       </asp:GridView>
    </form>

    <!-- Connect to the database -->
    <asp:LinqDataSource ID="GridDataSource"   
        TableName="Customers" EnableUpdate="true"
        ContextTypeName="AdventureWorksLTDataContext">
    </asp:LinqDataSource>
</body>
</html>
<%@ Page Language="C#" 
AutoEventWireup="true" CodeFile="CustomAttributeValidation.aspx.cs" 
Inherits="CustomAttributeValidation" %>


<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" >
    <title></title>
    <link href="~/Site.css" rel="stylesheet" type="text/css" />
</head>
<body>
     <h2>Example: <%=Title%></h2>

     <!-- Enable dynamic behavior. The GridView must be 
     registered with the manager. See code-behind file. -->
    <asp:DynamicDataManager ID="DynamicDataManager1" 
        AutoLoadForeignKeys="true" />


    <form id="form1" >

        <!-- Capture validation exceptions -->
        <asp:DynamicValidator ID="ValidatorID" ControlToValidate="GridView1" 
             /> 

        <asp:GridView ID="GridView1" 
             
            DataSourceID="GridDataSource" 
            AutoGenerateColumns="false"  
            AutoGenerateEditButton="true"
            AllowPaging="true"
            PageSize="10"
            AllowSorting="true">
            <Columns>
                <asp:DynamicField DataField="FirstName" />
                <asp:DynamicField DataField="LastName" />
                <asp:DynamicField DataField="Phone" />
            </Columns>
       </asp:GridView>
    </form>

    <!-- Connect to the database -->
    <asp:LinqDataSource ID="GridDataSource"   
        TableName="Customers" EnableUpdate="true"
        ContextTypeName="AdventureWorksLTDataContext">
    </asp:LinqDataSource>
</body>
</html>
Imports System
Imports System.Collections
Imports System.Configuration
Imports System.Web.DynamicData

Partial Public Class CustomAttributeValidation
    Inherits System.Web.UI.Page
    Protected _table As MetaTable

    Protected Sub Page_Init(ByVal sender As Object, ByVal e As EventArgs)
        ' Register control with the data manager.
        DynamicDataManager1.RegisterControl(GridView1)
    End Sub

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
        ' Get the table entity.
        _table = GridDataSource.GetTable()

        ' Assign title dynamically.
        Title = String.Concat( _
        "Customize <i>Phone</i> Data Field Validation", _
        "Using a Custom Attribute")
    End Sub
End Class
using System;
using System.Collections;
using System.Configuration;
using System.Web.DynamicData;

public partial class CustomAttributeValidation : System.Web.UI.Page
{
    protected MetaTable _table;

    protected void Page_Init(object sender, EventArgs e)
    {
        // Register control with the data manager.
        DynamicDataManager1.RegisterControl(GridView1);
    }

    protected void Page_Load(object sender, EventArgs e)
    {
        // Get the table entity.
        _table = GridDataSource.GetTable();

        // Assign title dynamically.
        Title = string.Concat("Customize <i>Phone</i> Data Field Validation",
            "Using a Custom Attribute");

    }
}

Compilando o código

Para compilar o código de exemplo, você precisa do seguinte:

  • Microsoft Visual Studio 2008 serviço empacotar 1 ou Visual Web Developer 2008 Express Edition serviço empacotar 1.

  • O banco de dados de exemplo AdventureWorksLT.Para obter informações sobre como baixar e instalar o banco de dados de exemplo do SQL servidor, consulte Exemplos de produtos do Microsoft SQL servidor: Banco de dados no site da CodePlex.Certifique-se de instalar a versão correta do banco de dados de exemplo para a versão do SQL servidor que você está executando (Microsoft SQL Server 2005 ou Microsoft SQL Server 2008).

  • Um orientados por dados site dinâmico.Isso permite que você criar um contexto de dados para o banco de dados e criar a classe que contém o campo de dados para personalizar e os métodos para substituir.Para obter mais informações, consulte Walkthrough: Creating a New Dynamic Data Web Site using Scaffolding.

Consulte também

Conceitos

Visão geral do ASP.NET dinâmico dados campo modelos

Visão geral de modelo Dados Dinâmicos ASP.NET

Visão geral de dados dinâmicos do ASP.NET

Referência

ValidationAttribute

DynamicValidator

Parcial classes e métodos (Guia de programação C#)

Date

History

Motivo

Julho de 2008

Tópico adicional.

Alteração de recurso do SP1.