Oct 14, 2013, 12:15 PM
[2.3] ModelField supports its own Model. Custom Data Binding example.
Hello,
The v2.3 release brings many new features. Here I shed light on one of them, a new possibility to customize serialization of complex data when binding it to a Store.
Anyone knows a Store => Model => ModelField sequence.
With the v2.3 release, it can be expanded to Store => Model => ModelField => Model.
It actually means that a ModelField supports its own Model.
Let's consider an example.
Imagine a Customer entity. It has some primitive type field like int ID, string Name, etc. and some complex type field like Address.
It is possible to do by using Json.NET JsonIgnore attribute:
A possible solution could be defining a Model for a ModelField.
Example
Real world case
The v2.3 release brings many new features. Here I shed light on one of them, a new possibility to customize serialization of complex data when binding it to a Store.
Anyone knows a Store => Model => ModelField sequence.
With the v2.3 release, it can be expanded to Store => Model => ModelField => Model.
It actually means that a ModelField supports its own Model.
Let's consider an example.
Imagine a Customer entity. It has some primitive type field like int ID, string Name, etc. and some complex type field like Address.
public class Customer
{
public int ID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public Address Address { get; set; }
}
The Address class's definition is:public class Address
{
public string City { get; set; }
public string Street { get; set; }
public string SomeAdditionalInfo { get; set; }
}
We would like to bind a set of customers to a Store. However, during data binding on server side, we would like to exclude the SomeAdditionalInfo property from serialization. It is possible to do by using Json.NET JsonIgnore attribute:
[JsonIgnore]
public string SomeAdditionalInfo { get; set; } // we would like to exclude that property from binding
<ext:ModelField Name="Address" Type="Object" />
However, marking the SomeAdditionalInfo property with JsonIgnore you might be kind of stuck with the requirement to serialize an Address with the SomeAdditionalInfo property.A possible solution could be defining a Model for a ModelField.
<ext:ModelField Name="Address">
<Model>
<ext:Model runat="server">
<Fields>
<ext:ModelField Name="City" />
<ext:ModelField Name="Street" />
</Fields>
</ext:Model>
</Model>
</ext:ModelField>
Here is a full example.Example
<%@ Page Language="C#" %>
<%@ Import Namespace="System.Collections.Generic" %>
<%@ Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>
<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
List<Customer> list = new List<Customer>(5);
for (int i = 1; i <= 5; i++)
{
Customer customer = new Customer
{
ID = i,
FirstName = ("FirstName" + i),
LastName = ("LastName" + i)
};
Address address = new Address
{
Street = ("Street" + i),
City = ("City" + i),
SomeAdditionalInfo = "SomeAdditionalInfo" // it comes from a database, for example
};
customer.Address = address;
list.Add(customer);
}
this.Store1.DataSource = list;
}
public class Customer
{
public int ID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public Address Address { get; set; }
}
public class Address
{
public string City { get; set; }
public string Street { get; set; }
public string SomeAdditionalInfo { get; set; } // we would like to exclude that property from binding
}
</script>
<!DOCTYPE html>
<html>
<head runat="server">
<title>Custom Data Binding - Ext.NET Examples</title>
</head>
<body>
<form runat="server">
<ext:ResourceManager runat="server" />
<ext:GridPanel
runat="server"
Title="Customers"
Width="630"
Height="300">
<Store>
<ext:Store ID="Store1" runat="server">
<Model>
<ext:Model runat="server">
<Fields>
<ext:ModelField Name="ID" Type="Int" />
<ext:ModelField Name="FirstName" />
<ext:ModelField Name="LastName" />
<ext:ModelField Name="Address">
<Model>
<ext:Model runat="server">
<Fields>
<ext:ModelField Name="City" />
<ext:ModelField Name="Street" />
</Fields>
</ext:Model>
</Model>
</ext:ModelField>
</Fields>
</ext:Model>
</Model>
</ext:Store>
</Store>
<ColumnModel runat="server">
<Columns>
<ext:Column runat="server" Text="ID" DataIndex="ID" />
<ext:Column runat="server" Text="FirstName" DataIndex="FirstName" />
<ext:Column runat="server" Text="LastName" DataIndex="LastName" />
<ext:Column runat="server" Text="City" DataIndex="Address">
<Renderer Handler="return value.City;" />
</ext:Column>
<ext:Column runat="server" Text="Street" DataIndex="Address">
<Renderer Handler="return value.Street;" />
</ext:Column>
</Columns>
</ColumnModel>
</ext:GridPanel>
</form>
</body>
</html>
The example has been added to the SVN trunk:trunk\Ext.Net.Examples\Examples\GridPanel\Miscellaneous\Custom_Data_Binding\Default.aspx
Some important notes about the feature:- A ModelField's Model is used on server only: with the data applied to a Store's DataSource or with the ModelSerializer class.
- A ModelField's Model is not used on client at all. Nothing is rendered to client. It means that client side features of ModelFields of a ModelField's Model, like Convert, Mapping, etc. don't make sense.
- But a ModelField's ServerMapping does work being used during serialization on server.
Real world case
Recently on the forums, we got a support question where a member was getting "Out of memory" exception binding the data to the Store using Entity Framework. It turned out that a recursion during serialization occurs there. And a ModelField's Model could be a possible solution.