Практическое руководство. Настройка проверки полей данных в модели данных с использованием настраиваемых атрибутов

Visual Studio 2010

Обновлен: Июль 2008

Платформа динамических данных ASP.NET позволяет настраивать и расширять проверку полей данных на уровне данных. В этом разделе описываются следующие этапы добавления проверки полей данных в модели данных.

  • Создание настраиваемого атрибута проверки. Этот атрибут позволяет создавать собственные метаданные, которые будут использоваться в модели данных для выполнения проверки.

  • Применение настраиваемого атрибута проверки. После создания настраиваемого атрибута его нужно применить к полям данных, которые требуется проверять.

Запустите пример этой функции в Интернете.

Настраиваемый атрибут проверки позволяет создавать метаданные, которые можно использовать в модели данных для проверки полей данных. Настраиваемый атрибут необходимо создавать как производный класс из базового класса ValidationAttribute.

Чтобы создать настраиваемый атрибут проверки

  1. В Обозревателе решений щелкните правой кнопкой мыши папку App_Code и выберите команду Добавить новый элемент.

  2. В области Добавить новый элемент выберите Класс.

    В поле Имя введите имя класса настраиваемого атрибута проверки. Можно использовать любое незанятое имя. Например, можно ввести имя CustomAttribute.vb в Visual C# или CustomAttribute.vb в Visual Basic, чтобы создать класс настраиваемого атрибута с именем CustomAttribute.

  3. Добавьте ссылки на пространства имен System, System.Web.Globalization и System.ComponentModel.DataAnnotations , используя ключевое слово Imports в Visual Basic или ключевое слово using в Visual C#, как показано в следующем примере.

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

    Imports System
    Imports System.Globalization
    Imports System.ComponentModel.DataAnnotations
    
  4. Внесите в определение класса следующие изменения:

    • Запретите наследование класса. Добавьте ключевое слово NotInheritable в Visual Basic или ключевое слово sealed в Visual C#.

    • Сделайте класс производным от базового типа ValidationAttribute.

    • Примените к определению класса атрибут AttributeUsageAttribute, чтобы указать, как должен использоваться создаваемый настраиваемый атрибут проверки.

    В следующем примере показано определение класса. Параметры атрибута AttributeUsageAttribute заданы так, чтобы настраиваемый атрибут проверки можно было применять к свойствам или полям только один раз.

    [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. Переопределите IsValid метод и добавьте логику для выполнения проверки. Метод должен возвращать true, если настраиваемая проверка успешно пройдена, и false, если проверка не пройдена. Подлежащее проверке значение передается методу в качестве единственного параметра.

    В следующем примере показан переопределенный метод.

    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. При необходимости переопределите метод FormatErrorMessage для создания собственного форматирования сообщений об ошибке.

    В следующем примере показано, как использовать имя поля данных, не прошедшего проверку, для построения сообщения об ошибке. Значение ErrorMessageString передается в качестве параметра, когда настраиваемый атрибут применяется к полю данных.

    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. Закройте и сохраните файл класса атрибута.

Чтобы настроить проверку для поля данных, необходимо реализовать разделяемый класс, который будет расширять модель данных. Это даст возможность применить настраиваемый атрибут к полю данных.

Чтобы создать разделяемый класс для проверки

  1. В Обозревателе решений щелкните правой кнопкой мыши папку App_Code и выберите команду Добавить новый элемент.

  2. В группе Установленные шаблоны Visual Studio выберите шаблон Класс.

    В поле Имя введите имя таблицы базы данных, для которой требуется создать проверку.

    Имя класса должно совпадать с именем класса сущностей, представляющего таблицу. Например, для создания проверки для таблицы Customer необходимо назвать файл Customer.cs в Visual C# или Customer.vb в Visual Basic и назвать класс Customer.

  3. Добавьте ключевое слово Partial в Visual Basic или ключевое слово partial в Visual C# в определение созданного класса, чтобы сделать его разделяемым классом. 

  4. При создании класса в Visual C# удалите конструктор по умолчанию.

    В следующем примере показано обновленное объявление класса.

    public partial class Customer {
        
    }
    

    Partial Public Class Customer
        
    End Class
    
  5. Добавьте ссылки на пространства имен System.Web.DynamicData и System.ComponentModel.DataAnnotations, используя ключевое слово Imports в Visual Basic или ключевое слово using в Visual C#, как показано в следующем примере.

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

    Imports System.Web.DynamicData
    Imports System.ComponentModel.DataAnnotations
    
  6. В этом же файле создайте второй класс, который будет выступать в качестве связанного класса метаданных. Этому классу можно дать любое допустимое незанятое имя.

    В следующем примере показано объявление класса метаданных.

    public class CustomerMetadata
    {
      
    }
    

    Public Class CustomerMetadata 
      
    End Class
    

    Связанный класс метаданных обеспечивает объект, к которому можно применить атрибуты проверки.

  7. Примените к определению разделяемого класса атрибут MetadataTypeAttribute. В качестве параметра атрибута укажите имя связанного класса метаданных, созданного на предыдущем шаге.

    В следующем примере показано определение разделяемого класса с добавленным атрибутом.

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

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

Теперь можно применить настраиваемый атрибут к полю данных.

Чтобы применить настраиваемый атрибут к полю данных

  1. В классе метаданных создайте свойство или поле с именем, соответствующим подлежащему проверке полю данных.

  2. Примените ранее созданный настраиваемый атрибут проверки к полю данных, которое требуется проверять.

    В следующем примере показано применение настраиваемого атрибута проверки к полю данных Phone.

    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. Сохраните изменения и закройте файл класса.

В следующем примере показано создание и применение настраиваемого атрибута с именем PhoneMaskAttribute к полю данных Phone таблицы Customer в базе данных AdventureWorksLT. В качестве модели данных в этом примере используется класс LINQ to SQL.

Атрибут дает платформе динамических данных указание проверить поле данных Phone на соответствие маске, представляющей определенный формат номера телефона. Если введенный пользователем телефон не соответствует маске, код атрибута выдает настроенную ошибку.

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

}


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="C#" 
AutoEventWireup="true" CodeFile="CustomAttributeValidation.aspx.cs" 
Inherits="CustomAttributeValidation" %>


<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
    <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" runat="server"
        AutoLoadForeignKeys="true" />


    <form id="form1" runat="server">

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

        <asp:GridView ID="GridView1" 
            runat="server" 
            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" runat="server"  
        TableName="Customers" EnableUpdate="true"
        ContextTypeName="AdventureWorksLTDataContext">
    </asp:LinqDataSource>
</body>
</html>


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

    }
}


Для компиляции кода примера потребуются следующие компоненты.

  • Microsoft Visual Studio 2008 с пакетом обновления 1 или Visual Web Developer 2008, экспресс-выпуск с пакетом обновления 1. 

  • Учебная база данных AdventureWorksLT. Сведения о загрузке и установке учебной базы данных SQL Server см. в разделе Microsoft SQL Server Product Samples: Database на узле CodePlex. Важно установить правильную версию базы данных, соответствующую используемой версии SQL Server (Microsoft SQL Server 2005 или Microsoft SQL Server 2008).

  • Управляемый данными динамический веб-узел. Позволяет создать контекст данных для базы данных и создать класс, содержащий настраиваемое поле данных и переопределяемые методы. Дополнительные сведения см. в разделе Walkthrough: Creating a New Dynamic Data Web Site using Scaffolding.

Дата

Журнал

Причина

Июль 2008

Раздел добавлен.

Изменение функции SP1.

Показ: