В этой статье мы ознакомимся с возможностью аннотирования модели данных с помощью мета-модели, с целью изменения её отображения. Это та самая описательная информация объектной модели данных, о которой мы говорили ранее, которая позволяет отобразить объектную модель в html формате.
Должен заметить, что механизм, описанный ниже, используется не только в DynamicData, но также в новом средстве быстрой разработки MVC2 — шаблонных помощников (Templated helpers). Это хелперы DisplayFor(), LabelFor(), EditorFor().
DynamicData и MVC2 позволяют гибко настраивать мета-модель с помощью аннотирования полей специальными атрибутами, например, менять отображаемые названия полей, менять тип соответствующих html-контролов, задавать правила валидации. Однако аннотируются не сами свойства в модели, а свойства специального класса-болванки (MetadataType), которые имеют те же имена, что и свойства модели. Их декорируют (аннотируют) атрибутами, которые определены в пространствах имён System.ComponentModel и System.ComponentModel.DataAnnotations. Так происходит потому, что во-первых, классы модели обычно генерируются автоматически, поэтому последующее их редактирование нецелесообразно, а во-вторых, правильно отделять описание представления и правила валидации модели от неё самой.
К примеру, LINQ to SQL сгенерировал класс Product для нашей Northwind базы данных (см. предыдущий пост). Этот класс соответствует таблице Products. Найти его можно в файле Northwind.designer.cs.
[Table(Name="dbo.Products")]
public partial class Product : INotifyPropertyChanging, INotifyPropertyChanged
{
/// ... private fields
/// ... Extensibility Method Definitions
public Product() {// constructor code}
[Column(Storage="_ProductID", AutoSync=AutoSync.OnInsert, DbType="Int NOT NULL IDENTITY", IsPrimaryKey=true, IsDbGenerated=true)]
public int ProductID
{
get
{
return this._ProductID;
}
set
{
if ((this._ProductID != value))
{
this.OnProductIDChanging(value);
this.SendPropertyChanging();
this._ProductID = value;
this.SendPropertyChanged("ProductID");
this.OnProductIDChanged();
}
}
}
[Column(Storage="_ProductName", DbType="NVarChar(40) NOT NULL", CanBeNull=false)]
public string ProductName
{
// ...
}
[Column(Storage="_SupplierID", DbType="Int")]
public System.Nullable<int> SupplierID
{
// ...
}
[Column(Storage="_CategoryID", DbType="Int")]
public System.Nullable<int> CategoryID
{
// ...
}
// ... etc.
}
Обратите внимание, что этот класс partial, значит его можно расширить собственными методами и свойствами. Для того, чтобы аннотировать его мета-данными, необходимо декорировать определение этого класса атрибутом MetadataTypeAttribute. Создаём отдельную папку для мета-данных, в ней файл Product.cs и пишем следующее:
[ScaffoldTable(true)]// Можно назначить как тут, так и в ProductMetaModel
[MetadataType(typeof(ProductMetaModel))]
public partial class Product {}
[TableName("Товары")]
public class ProductMetaModel
{
[DisplayName("ID товара")]
public object ProductID { get; set; }
[DisplayName("Название")]
public object ProductName { get; set; }
[DisplayName("Поставщик")]
public object SupplierID { get; set; }
[DisplayName("Категория")]
public object CategoryID { get; set; }
[DisplayName("Количество в упаковке")]
public object QuantityPerUnit { get; set; }
[DisplayName("Цена за упаковку")]
public object UnitPrice { get; set; }
[DisplayName("Упаковок на складе")]
public object UnitsInStock { get; set; }
[DisplayName("Упаковок заказано")]
[ScaffoldColumn(false)]
public object UnitsOnOrder { get; set; }
[ScaffoldColumn(false)]
public object ReorderLevel { get; set; }
[ScaffoldColumn(false)]
public object Discontinued { get; set; }
[ScaffoldColumn(false)]
public object Order_Details{ get; set; }
[ScaffoldColumn(false)]
public object Category{ get; set; }
[ScaffoldColumn(false)]
public object Supplier{ get; set; }
}
Теперь при генерации представления, будут выводиться значения только тех полей, для которых атрибут ScaffoldColumn имеет значения true (по умолчанию), подписи к полям будут соответсвовать строкам, заданым в атрибутах DisplayName, а название таблицы — TableName.
Опробуем это с помощью механизма Templated helpers. Создадим в методе Index HomeController объект Product:
var product = new DynamicDataMvcScaffolding.Models.Product()
{
CategoryID = 1,
ProductName = "Картошка",
ProductID = 123,
SupplierID = 2,
QuantityPerUnit = "50 кило",
UnitPrice = 234,
UnitsInStock = 1000,
UnitsOnOrder = 111
};
ViewData["product"] = product;
В соответсвующем представлении:
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"> <div> <%= Html.DisplayFor(product => ViewData["product"]) %> </div> </asp:Content>
Результат:
No comments:
Post a Comment