Настройка метаданных ASP.NET Dynamic Data

132

Система динамических данных ASP.NET поддерживает определение классов метаданных. Эти настройки применяются к модели данных и позволяют осуществлять детализированное управление.

Создание класса метаданных

Система динамических данных ASP.NET для метаданных полагается на частичные классы. Мы создаем частичный класс для типа модели данных, который требуется настроить, и отдельный класс, который будет использоваться для метаданных, после чего эти два класса ассоциируются друг с другом посредством аннотации. Проще всего рассмотреть пример.

Щелкните правой кнопкой мыши на папке App_Code в окне Solution Explorer, выберите в контекстном меню пункт Add New Item (Добавить новый элемент) и укажите шаблон Class (Класс) в списке шаблонов. Имя, назначаемое классу, не имеет особого значения - мы выбрали Metadata.cs. Щелкните на кнопке Add (Добавить), чтобы создать новый файл. Откройте файл для редактирования и удалите все его содержимое, заменив его следующим кодом:

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

[MetadataType(typeof(Order_DetailMetadata))]
public partial class Order_Detail
{
}

public class Order_DetailMetadata
{
}

Операторы using ссылаются на пространства имен, содержащие атрибуты, которые будут использоваться в следующих разделах. Интерес представляет класс Order_Detail. Это - частичный класс, который расширяет класс Order_Detail, сгенерированный в модели данных. Обратите внимание, что применяется форма единственного числа - мы обращаемся к типу данных, а не к таблице.

Атрибут MetadataType применяется к частичному классу для указания того, что необходимо предоставить метаданные для этого типа данных. Аргументом этого атрибута является тип класса, который будет использоваться. В этом же файле мы создали еще один класс - Order_DetailMetadata. Это все, что требуется для создания класса метаданных. В одном файле класса можно определять множество отношений между метаданными. Например, если необходимо объявить метаданные для таблицы Products, можно создать следующий частичный класс Product:

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

[MetadataType(typeof(Order_DetailMetadata))]
public partial class Order_Detail
{
}

public class Order_DetailMetadata
{
}

[MetadataType(typeof(ProductMetadata))]
public partial class Product
{
}

public class ProductMetadata
{
}

Изменение отображаемых имен

После создания классы метаданных можно применять для настройки своего приложения динамических данных. Начать целесообразно с изменения отображаемого имени таблицы Order_Details - то, что база данных не допускает использования пробелов в именах таблиц, еще не означает, что пользователи обязаны мириться с символами подчеркивания в именах.

Настройки с помощью метаданных осуществляются за счет применения атрибутов к классу, которому назначено имя в атрибуте MetadataType - в данном случае типу Order_DetailMetadata для таблицы Order_Details. Для изменения отображаемого имени таблицы должен использоваться атрибут DisplayName:

[DisplayName("Детали заказа")]
public class Order_DetailMetadata
{
}

В этом коде в качестве отображаемого имени указано "Детали заказа" (без символа подчеркивания). Выберите пункт Start Without Debugging в меню Debug. Стартовая страница приложения будет иметь вид, показанный на рисунке ниже:

Измененное отображаемое имя таблицы

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

Можно изменять также имена столбцов в таблице. Для этого в свой класс метаданных необходимо добавить свойства с теми же самыми именами, что и у столбцов, которые должны быть изменены. В следующем примере задействованы столбцы UnitsInStock и UnitPrice из таблицы Products:

public class ProductMetadata
{

    [DisplayName("В наличии")]
    public object UnitsInStock { get; set; }

    [DisplayName("Цена")]
    public object UnitPrice { get; set; }
}

О типе свойств можно не беспокоиться - мы использовали тип object. Важно, чтобы имя свойства совпадало с именем столбца таблицы. Как только свойства определены в классе метаданных, можно применить атрибут DisplayName, как это было сделано для имени таблицы.

Сохраните изменения в файле Metadata.cs и выберите пункт Start Without Debugging в меню Debug. Щелкните на ссылке таблицы Products на стартовой странице, и обратите внимание на изменения в именах столбцов:

Изменение отображаемых имен столбцов

Стоит повторить еще раз: эти изменения оказывают влияние при каждом применении имен столбцов. Щелкнув на ссылке Details для одной из записей, можно убедиться, что новые заголовки "В наличии" и "Цена" используются и там.

Изменение видимости

Атрибуты можно использовать для управления видимостью столбцов и таблиц в шаблонах. Чтобы скрыть столбец, необходимо применить атрибут ScaffoldColumn с аргументом false, как показано в следующем примере:

public class ProductMetadata
{

    [DisplayName("В наличии")]
    public object UnitsInStock { get; set; }

    [DisplayName("Цена")]
    public object UnitPrice { get; set; }

    [ScaffoldColumn(false)]
    public object SupplierID { get; set; }
}

Мы определили свойство для столбца SupplierID и применили атрибут ScaffoldColumn. Если теперь запустить приложение динамических данных и выбрать таблицу Products, выяснится, что столбец SupplierID исчез.

С помощью атрибута ScaffoldTable то же самое можно выполнить для таблиц. Следующий код определяет класс метаданных для таблицы Customers и использует атрибут, чтобы скрыть всю таблицу:

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

[ScaffoldTable(false)]
public class CustomerMetadata
{
}

Если взглянуть на домашнюю страницу приложения, можно видеть, что в ней отсутствует ссылка таблицы Customers. Эффект применения этого атрибута отличается от пропуска таблицы с помощью маршрутов. Несмотря на отсутствие ссылки таблицы, система динамических данных ASP.NET все равно использует таблицу для установки отношений внешнего ключа. Откройте представление таблицы Orders и вы увидите, что по-прежнему можно выполнять фильтрацию по Customer.

Настройка форматирования полей

Если взглянуть на записи в таблице Orders, выяснится, что метки времени во всех столбцах OrderDate, RequiredDate и ShippedDate установлены в 00:00:00. Это связано с тем, что форматирование временных меток по умолчанию включает и дату, и время, как показано на рисунке ниже:

Неформатированные временные метки в таблице Orders

Форматирование можно изменить с помощью строки DisplayFormat, которая позволяет передавать стандартную строку формата .NET, используемого при отображении поля.

В следующем коде показано, как это применить к трем полям даты в таблице Orders:

[MetadataType(typeof(OrderMetadata))]
public partial class Order
{
}

public class OrderMetadata
{
    [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}")]
    public object OrderDate { get; set; }

    [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}")]
    public object RequiredDate { get; set; }

    [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}")]
    public object ShippedDate { get; set; }
}

Выбранная строка формата отображает дату в компактной форме и полностью опускает значение времени. Если сохранить эти изменения в файле кода Metadata.cs и выбрать пункт Start Without Debugging в меню Debug, можно убедиться, что отображение изменилось:

Форматированные поля даты

Использование специального шаблона поля

В статье "Настройка с помощью шаблонов" было показано, как изменить внешний вид всех полей заданного типа. Используя метаданные, можно изменять внешний вид определенного столбца данных. Вначале понадобится создать новый шаблон поля. Скопируйте файл Text.ascx в папку FieldTemplates и переименуйте копию в REDText.ascx. Замените его содержимое следующим кодом - простой меткой, отображающей белый текст на красном фоне:

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="REDText.ascx.cs" Inherits="DynamicData_FieldTemplates_REDText" %>

<asp:Label ID="Label1" runat="server" Text="<%# FieldValueString %>" 
    ForeColor="White" BackColor="Red" />

Теперь с помощью атрибута UIHint можно сообщить системе динамических данных ASP.NET о необходимости использования нашего специального шаблона поля для отображения столбца. В следующем коде посредством атрибута к столбцу ShipName применяется шаблон REDText:

public class OrderMetadata
{
    // ...

    [UIHint("REDText")]
    public object ShipName { get; set; }
}

Теперь при запуске приложения и просмотре таблицы Orders поля ShipName отображаются с использованием нашего шаблона, как показано на рисунке ниже:

Применение специального шаблона поля
Пройди тесты
Лучший чат для C# программистов