I have run into an issue trying to use the edit form template on a radgrid bound to an objectdatasource connected to a entity framework data model that uses complex types. It works fine when you edit an existing record but gives an error when adding a new record. Below is the code for a simple demo that I set up using a list of objects. In the below example if I edit a record it all works fine but if I add a record it throws an error "DataBinding: 'Telerik.Web.UI.GridInsertionObject' does not contain a property with the name 'person'.". Any ideas of a work around?
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<telerik:RadScriptManager ID="RadScriptManager1" runat="server">
<Scripts>
<asp:ScriptReference Assembly="Telerik.Web.UI" Name="Telerik.Web.UI.Common.Core.js" />
<asp:ScriptReference Assembly="Telerik.Web.UI" Name="Telerik.Web.UI.Common.jQuery.js" />
<asp:ScriptReference Assembly="Telerik.Web.UI" Name="Telerik.Web.UI.Common.jQueryInclude.js" />
</Scripts>
</telerik:RadScriptManager>
<telerik:RadAjaxManager ID="RadAjaxManager1" runat="server">
</telerik:RadAjaxManager>
<div>
<telerik:RadGrid ID="grdData" runat="server"
AllowSorting="True" GridLines="Vertical" AllowPaging="True" PageSize="50"
AutoGenerateColumns="False" Width="800px" DataSourceID="odsData"
OnDeleteCommand="grdData_DeleteCommand" OnInsertCommand="grdData_InsertCommand" OnUpdateCommand="grdData_UpdateCommand" >
<MasterTableView GridLines="Vertical" CommandItemDisplay="Top" DataKeyNames="id" EditMode="PopUp">
<Columns>
<telerik:GridEditCommandColumn ButtonType="ImageButton" ItemStyle-Width="25" />
<telerik:GridBoundColumn HeaderText="First Name" DataField="person.name" SortExpression="name" UniqueName="name" />
<telerik:GridBoundColumn HeaderText="Email" DataField="person.email" SortExpression="email" UniqueName="email" />
<telerik:GridCheckBoxColumn HeaderText="Sales Rep" DataField="salesRep" SortExpression="salesRep" UniqueName="salesRep" />
<telerik:GridButtonColumn ConfirmText="Are you sure you want to delete this item?" ConfirmDialogType="RadWindow"
ConfirmTitle="Delete" ButtonType="ImageButton" CommandName="Delete" ItemStyle-Width="25" />
</Columns>
<EditFormSettings EditFormType="Template" >
<PopUpSettings Width="400px" Modal="true" />
<FormTemplate>
<div style="padding: 10px; text-align: left;">
<div><asp:Label ID="Label1" runat="server" Text="Name: " /></div>
<div>
<asp:TextBox ID="fldFirstName" runat="server" Text='<%# Bind("person.name") %>' Width="300" MaxLength="50" TabIndex="1" />
</div>
<div>
<asp:RequiredFieldValidator ID="valNameRequired" runat="server" ErrorMessage="Name Required" ControlToValidate="fldFirstName" />
</div>
<div><asp:Label ID="Label4" runat="server" Text="Email: " /></div>
<div>
<asp:TextBox ID="fldEMail" runat="server" Text='<%# Bind("person.email") %>' Width="300" MaxLength="50" TabIndex="3" />
</div>
<div>
<asp:RequiredFieldValidator ID="valEmailRequired" runat="server" ErrorMessage="Email Required" ControlToValidate="fldEmail" Display="dynamic" />
<asp:RegularExpressionValidator ID="valEmail" runat="server" ControlToValidate="fldEmail" ErrorMessage="Enter a valid Email" ValidationExpression="\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*" />
</div>
<div><asp:Label ID="Label6" runat="server" Text="Sales Rep: " /><asp:CheckBox ID="cbxSalesRep" runat="server" Checked='<%# Bind("salesRep") %>' /></div>
<div>
<asp:Button ID="btnSave" Text="Save" runat="server" CommandName='<%# (Container is GridEditFormInsertItem) ? "PerformInsert" : "Update" %>' Width="100" TabIndex="10" />
<asp:Button ID="btnCancel" Text="Cancel" runat="server" CausesValidation="False" CommandName="Cancel" Width="100" TabIndex="11" />
</div>
</div>
</FormTemplate>
</EditFormSettings>
</MasterTableView>
</telerik:RadGrid>
</div>
<telerik:RadWindowManager ID="RadWindowManager" runat="server" />
<asp:ObjectDataSource ID="odsData" runat="server" TypeName="UserData" SelectMethod="getUsers" DataObjectTypeName="UserData+User" />
</form>
</body>
</html>
using System;
using System.Collections.Generic;
using System.Collections;
using System.IO;
using System.Xml.Serialization;
using System.Text;
using Telerik.Web.UI;
public partial class Default : System.Web.UI.Page
{
public UserData userData = new UserData();
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
}
}
protected void grdData_InsertCommand(object sender, Telerik.Web.UI.GridCommandEventArgs e)
{
var editableItem = ((GridEditableItem)e.Item);
Hashtable values = new Hashtable();
editableItem.ExtractValues(values);
UserData.User user = new UserData.User();
user.person.name = (string)values["person.name"];
user.person.email = (string)values["person.email"];
user.salesRep = bool.Parse(values["salesRep"].ToString());
userData.updateUser(user);
}
protected void grdData_UpdateCommand(object sender, Telerik.Web.UI.GridCommandEventArgs e)
{
var editableItem = ((GridEditableItem)e.Item);
var id = (int)editableItem.GetDataKeyValue("id");
UserData.User user = userData.getUserById(id);
Hashtable values = new Hashtable();
editableItem.ExtractValues(values);
user.person.name = (string)values["person.name"];
user.person.email = (string)values["person.email"];
user.salesRep = bool.Parse(values["salesRep"].ToString());
userData.updateUser(user);
}
protected void grdData_DeleteCommand(object sender, Telerik.Web.UI.GridCommandEventArgs e)
{
var editableItem = ((GridEditableItem)e.Item);
var id = (int)editableItem.GetDataKeyValue("id");
userData.deleteUser(id);
}
}
public class UserData
{
List<User> userData;
public UserData()
{
if (File.Exists("c:\\temp\\testdata.xml"))
userData = XSerial.Load<List<User>>("c:\\temp\\testdata.xml");
else
{
userData = new List<User>();
userData.Add(new User(1, new Person("Fred Flintstone", "fredflintstone@gmail.com"), false));
userData.Add(new User(2, new Person("Barney Rubble", "brubble@gmail.com"), false));
userData.Add(new User(3, new Person("Mr. Slate", "mslate@slatequarry.com"), false));
saveData();
}
}
public void saveData()
{
XSerial.Save<List<User>>("c:\\temp\\testdata.xml", userData);
}
public List<User> getUsers()
{
return userData;
}
public User getUserById(int id)
{
int i = 0;
while(i < userData.Count && userData[i].id != id)
i++;
return userData[i];
}
public void insertUser(User user)
{
int nextId = 1;
int i = 0;
while (i < userData.Count && userData[i].id != user.id)
{
if (userData[i].id > nextId)
nextId = userData[i].id + 1;
i++;
}
user.id = nextId;
userData.Add(user);
XSerial.Save<List<User>>("c:\\temp\\testdata.xml", userData);
}
public void updateUser(User user)
{
int i = 0;
while (i < userData.Count && userData[i].id != user.id)
i++;
userData[i] = user;
XSerial.Save<List<User>>("c:\\temp\\testdata.xml", userData);
}
public void deleteUser(int id)
{
int i = 0;
while (i < userData.Count && userData[i].id != id)
i++;
userData.RemoveAt(i);
XSerial.Save<List<User>>("c:\\temp\\testdata.xml", userData);
}
public class Person
{
private string _name;
private string _email;
public string name
{
get { return _name; }
set { _name = value; }
}
public string email
{
get { return _email; }
set { _email = value; }
}
public Person()
{
_name = "";
_email = "";
}
public Person(string name, string email)
{
_name = name;
_email = email;
}
}
public class User
{
private int _id;
private Person _person;
private bool _salesRep;
public int id
{
get { return _id; }
set { _id = value; }
}
public Person person
{
get { return _person; }
set { _person = value; }
}
public bool salesRep
{
get { return _salesRep; }
set { _salesRep = value; }
}
public User()
{
_id = 0;
_person = new Person();
_salesRep = false;
}
public User(int id, Person person, bool salesRep)
{
_id = id;
_person = person;
_salesRep = salesRep;
}
}
}
/// <summary>
/// Serializer class. Load and Save classes from/to XML files.
/// </summary>
public class XSerial
{
/// <summary>
/// Load a class from a serialized XML file.
/// </summary>
/// <param name="filename">full path or path relative to the XML file</param>
/// <param name="t">type of the class that is being retrieved (Use typeof(ClassName))</param>
/// <returns>A populated version of the class, or null on failure</returns>
/// <exception cref="Exception">Can throw several exceptions for IO and serialization loading</exception>
public static T Load<T>(string filename)
{
T ob = default(T);
using (Stream s = File.Open(filename, FileMode.Open))
{
StreamReader sr = new StreamReader(s);
ob = DeserializeObject<T>(sr.ReadToEnd());
s.Close();
}
return ob;
}
/// <summary>
/// Save an instance of a class to an XML file
/// </summary>
/// <param name="filename">Full or relative path to the file</param>
/// <param name="cls">Class to serialize and save.</param>
/// <param name="t">Type of the class (use: typeof(ClassName)</param>
/// <returns>True on success, False on failure</returns>
public static void Save<T>(string filename, T cls)
{
using (Stream s = File.Open(filename, FileMode.Create))
{
using (StreamWriter sw = new StreamWriter(s))
{
sw.Write( SerializeObject<T>(cls) );
sw.Close();
s.Close();
return;
}
}
}
/// <summary>
/// Serialize the object into an XML format
/// </summary>
/// <typeparam name="T">Type of object to serialize</typeparam>
/// <param name="pObject">the object to serialize</param>
/// <returns>a string representing the XML version of the object</returns>
public static String SerializeObject<T>(T pObject)
{
MemoryStream memoryStream = new MemoryStream();
UTF8Encoding encoding = new UTF8Encoding();
XmlSerializer xs = new XmlSerializer(typeof(T));
System.Xml.XmlTextWriter xmlTextWriter = new System.Xml.XmlTextWriter(memoryStream, Encoding.UTF8);
xs.Serialize(xmlTextWriter, (object) pObject);
memoryStream = (MemoryStream)xmlTextWriter.BaseStream;
return encoding.GetString(memoryStream.ToArray());
}
/// <summary>
/// Deserialize the object back into the object from an XML string
/// </summary>
/// <typeparam name="T">Type of the object to restore</typeparam>
/// <param name="pXmlizedString">The string that represents the object in XML</param>
/// <returns>A new instance of the restored object</returns>
public static T DeserializeObject<T>(String pXmlizedString)
{
UTF8Encoding encoding = new UTF8Encoding();
XmlSerializer xs = new XmlSerializer(typeof(T));
MemoryStream memoryStream = new MemoryStream(encoding.GetBytes(pXmlizedString));
System.Xml.XmlTextWriter xmlTextWriter = new System.Xml.XmlTextWriter(memoryStream, Encoding.UTF8);
return (T)xs.Deserialize(memoryStream);
}
}
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<telerik:RadScriptManager ID="RadScriptManager1" runat="server">
<Scripts>
<asp:ScriptReference Assembly="Telerik.Web.UI" Name="Telerik.Web.UI.Common.Core.js" />
<asp:ScriptReference Assembly="Telerik.Web.UI" Name="Telerik.Web.UI.Common.jQuery.js" />
<asp:ScriptReference Assembly="Telerik.Web.UI" Name="Telerik.Web.UI.Common.jQueryInclude.js" />
</Scripts>
</telerik:RadScriptManager>
<telerik:RadAjaxManager ID="RadAjaxManager1" runat="server">
</telerik:RadAjaxManager>
<div>
<telerik:RadGrid ID="grdData" runat="server"
AllowSorting="True" GridLines="Vertical" AllowPaging="True" PageSize="50"
AutoGenerateColumns="False" Width="800px" DataSourceID="odsData"
OnDeleteCommand="grdData_DeleteCommand" OnInsertCommand="grdData_InsertCommand" OnUpdateCommand="grdData_UpdateCommand" >
<MasterTableView GridLines="Vertical" CommandItemDisplay="Top" DataKeyNames="id" EditMode="PopUp">
<Columns>
<telerik:GridEditCommandColumn ButtonType="ImageButton" ItemStyle-Width="25" />
<telerik:GridBoundColumn HeaderText="First Name" DataField="person.name" SortExpression="name" UniqueName="name" />
<telerik:GridBoundColumn HeaderText="Email" DataField="person.email" SortExpression="email" UniqueName="email" />
<telerik:GridCheckBoxColumn HeaderText="Sales Rep" DataField="salesRep" SortExpression="salesRep" UniqueName="salesRep" />
<telerik:GridButtonColumn ConfirmText="Are you sure you want to delete this item?" ConfirmDialogType="RadWindow"
ConfirmTitle="Delete" ButtonType="ImageButton" CommandName="Delete" ItemStyle-Width="25" />
</Columns>
<EditFormSettings EditFormType="Template" >
<PopUpSettings Width="400px" Modal="true" />
<FormTemplate>
<div style="padding: 10px; text-align: left;">
<div><asp:Label ID="Label1" runat="server" Text="Name: " /></div>
<div>
<asp:TextBox ID="fldFirstName" runat="server" Text='<%# Bind("person.name") %>' Width="300" MaxLength="50" TabIndex="1" />
</div>
<div>
<asp:RequiredFieldValidator ID="valNameRequired" runat="server" ErrorMessage="Name Required" ControlToValidate="fldFirstName" />
</div>
<div><asp:Label ID="Label4" runat="server" Text="Email: " /></div>
<div>
<asp:TextBox ID="fldEMail" runat="server" Text='<%# Bind("person.email") %>' Width="300" MaxLength="50" TabIndex="3" />
</div>
<div>
<asp:RequiredFieldValidator ID="valEmailRequired" runat="server" ErrorMessage="Email Required" ControlToValidate="fldEmail" Display="dynamic" />
<asp:RegularExpressionValidator ID="valEmail" runat="server" ControlToValidate="fldEmail" ErrorMessage="Enter a valid Email" ValidationExpression="\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*" />
</div>
<div><asp:Label ID="Label6" runat="server" Text="Sales Rep: " /><asp:CheckBox ID="cbxSalesRep" runat="server" Checked='<%# Bind("salesRep") %>' /></div>
<div>
<asp:Button ID="btnSave" Text="Save" runat="server" CommandName='<%# (Container is GridEditFormInsertItem) ? "PerformInsert" : "Update" %>' Width="100" TabIndex="10" />
<asp:Button ID="btnCancel" Text="Cancel" runat="server" CausesValidation="False" CommandName="Cancel" Width="100" TabIndex="11" />
</div>
</div>
</FormTemplate>
</EditFormSettings>
</MasterTableView>
</telerik:RadGrid>
</div>
<telerik:RadWindowManager ID="RadWindowManager" runat="server" />
<asp:ObjectDataSource ID="odsData" runat="server" TypeName="UserData" SelectMethod="getUsers" DataObjectTypeName="UserData+User" />
</form>
</body>
</html>
using System;
using System.Collections.Generic;
using System.Collections;
using System.IO;
using System.Xml.Serialization;
using System.Text;
using Telerik.Web.UI;
public partial class Default : System.Web.UI.Page
{
public UserData userData = new UserData();
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
}
}
protected void grdData_InsertCommand(object sender, Telerik.Web.UI.GridCommandEventArgs e)
{
var editableItem = ((GridEditableItem)e.Item);
Hashtable values = new Hashtable();
editableItem.ExtractValues(values);
UserData.User user = new UserData.User();
user.person.name = (string)values["person.name"];
user.person.email = (string)values["person.email"];
user.salesRep = bool.Parse(values["salesRep"].ToString());
userData.updateUser(user);
}
protected void grdData_UpdateCommand(object sender, Telerik.Web.UI.GridCommandEventArgs e)
{
var editableItem = ((GridEditableItem)e.Item);
var id = (int)editableItem.GetDataKeyValue("id");
UserData.User user = userData.getUserById(id);
Hashtable values = new Hashtable();
editableItem.ExtractValues(values);
user.person.name = (string)values["person.name"];
user.person.email = (string)values["person.email"];
user.salesRep = bool.Parse(values["salesRep"].ToString());
userData.updateUser(user);
}
protected void grdData_DeleteCommand(object sender, Telerik.Web.UI.GridCommandEventArgs e)
{
var editableItem = ((GridEditableItem)e.Item);
var id = (int)editableItem.GetDataKeyValue("id");
userData.deleteUser(id);
}
}
public class UserData
{
List<User> userData;
public UserData()
{
if (File.Exists("c:\\temp\\testdata.xml"))
userData = XSerial.Load<List<User>>("c:\\temp\\testdata.xml");
else
{
userData = new List<User>();
userData.Add(new User(1, new Person("Fred Flintstone", "fredflintstone@gmail.com"), false));
userData.Add(new User(2, new Person("Barney Rubble", "brubble@gmail.com"), false));
userData.Add(new User(3, new Person("Mr. Slate", "mslate@slatequarry.com"), false));
saveData();
}
}
public void saveData()
{
XSerial.Save<List<User>>("c:\\temp\\testdata.xml", userData);
}
public List<User> getUsers()
{
return userData;
}
public User getUserById(int id)
{
int i = 0;
while(i < userData.Count && userData[i].id != id)
i++;
return userData[i];
}
public void insertUser(User user)
{
int nextId = 1;
int i = 0;
while (i < userData.Count && userData[i].id != user.id)
{
if (userData[i].id > nextId)
nextId = userData[i].id + 1;
i++;
}
user.id = nextId;
userData.Add(user);
XSerial.Save<List<User>>("c:\\temp\\testdata.xml", userData);
}
public void updateUser(User user)
{
int i = 0;
while (i < userData.Count && userData[i].id != user.id)
i++;
userData[i] = user;
XSerial.Save<List<User>>("c:\\temp\\testdata.xml", userData);
}
public void deleteUser(int id)
{
int i = 0;
while (i < userData.Count && userData[i].id != id)
i++;
userData.RemoveAt(i);
XSerial.Save<List<User>>("c:\\temp\\testdata.xml", userData);
}
public class Person
{
private string _name;
private string _email;
public string name
{
get { return _name; }
set { _name = value; }
}
public string email
{
get { return _email; }
set { _email = value; }
}
public Person()
{
_name = "";
_email = "";
}
public Person(string name, string email)
{
_name = name;
_email = email;
}
}
public class User
{
private int _id;
private Person _person;
private bool _salesRep;
public int id
{
get { return _id; }
set { _id = value; }
}
public Person person
{
get { return _person; }
set { _person = value; }
}
public bool salesRep
{
get { return _salesRep; }
set { _salesRep = value; }
}
public User()
{
_id = 0;
_person = new Person();
_salesRep = false;
}
public User(int id, Person person, bool salesRep)
{
_id = id;
_person = person;
_salesRep = salesRep;
}
}
}
/// <summary>
/// Serializer class. Load and Save classes from/to XML files.
/// </summary>
public class XSerial
{
/// <summary>
/// Load a class from a serialized XML file.
/// </summary>
/// <param name="filename">full path or path relative to the XML file</param>
/// <param name="t">type of the class that is being retrieved (Use typeof(ClassName))</param>
/// <returns>A populated version of the class, or null on failure</returns>
/// <exception cref="Exception">Can throw several exceptions for IO and serialization loading</exception>
public static T Load<T>(string filename)
{
T ob = default(T);
using (Stream s = File.Open(filename, FileMode.Open))
{
StreamReader sr = new StreamReader(s);
ob = DeserializeObject<T>(sr.ReadToEnd());
s.Close();
}
return ob;
}
/// <summary>
/// Save an instance of a class to an XML file
/// </summary>
/// <param name="filename">Full or relative path to the file</param>
/// <param name="cls">Class to serialize and save.</param>
/// <param name="t">Type of the class (use: typeof(ClassName)</param>
/// <returns>True on success, False on failure</returns>
public static void Save<T>(string filename, T cls)
{
using (Stream s = File.Open(filename, FileMode.Create))
{
using (StreamWriter sw = new StreamWriter(s))
{
sw.Write( SerializeObject<T>(cls) );
sw.Close();
s.Close();
return;
}
}
}
/// <summary>
/// Serialize the object into an XML format
/// </summary>
/// <typeparam name="T">Type of object to serialize</typeparam>
/// <param name="pObject">the object to serialize</param>
/// <returns>a string representing the XML version of the object</returns>
public static String SerializeObject<T>(T pObject)
{
MemoryStream memoryStream = new MemoryStream();
UTF8Encoding encoding = new UTF8Encoding();
XmlSerializer xs = new XmlSerializer(typeof(T));
System.Xml.XmlTextWriter xmlTextWriter = new System.Xml.XmlTextWriter(memoryStream, Encoding.UTF8);
xs.Serialize(xmlTextWriter, (object) pObject);
memoryStream = (MemoryStream)xmlTextWriter.BaseStream;
return encoding.GetString(memoryStream.ToArray());
}
/// <summary>
/// Deserialize the object back into the object from an XML string
/// </summary>
/// <typeparam name="T">Type of the object to restore</typeparam>
/// <param name="pXmlizedString">The string that represents the object in XML</param>
/// <returns>A new instance of the restored object</returns>
public static T DeserializeObject<T>(String pXmlizedString)
{
UTF8Encoding encoding = new UTF8Encoding();
XmlSerializer xs = new XmlSerializer(typeof(T));
MemoryStream memoryStream = new MemoryStream(encoding.GetBytes(pXmlizedString));
System.Xml.XmlTextWriter xmlTextWriter = new System.Xml.XmlTextWriter(memoryStream, Encoding.UTF8);
return (T)xs.Deserialize(memoryStream);
}
}