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.
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:

  1. A ModelField's Model is used on server only: with the data applied to a Store's DataSource or with the ModelSerializer class.
  2. 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.
  3. 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.