By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
444,137 Members | 2,282 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 444,137 IT Pros & Developers. It's quick & easy.

Bind an Array of Custom Objects

P: n/a
Jed
I have a web service method that returns an array of custom objects marked
serializeable with fully described public properties.

When I bind the results to a DataGrid I can access the properties in the
ItemDataBound event of the codebehind but I can't access them declaratively
in the HTML code?

Here is the code to call the method.
net.mysite.www.WSInterface proxy;
proxy = new net.mysite.www.WSInterface();
ProjectList[] pl = proxy.getProjects("%",false,true);
this.DataGrid1.DataSource = pl;
this.DataGrid1.DataBind();

Here is the code to access the property in the Item databound event.
lbl.Text = ((ProjectList)dg.DataItem).ClientName;

Here is the code that won't work on the HTML side:
Option 1:
<asp:BoundColumn HeaderText="Client Contact"
DataField="ClientContact"></asp:BoundColumn>

Option 2:
<asp:TemplateColumn HeaderText="Contact">
<ItemTemplate><%# DataBinder.Eval(Container.DataItem,
"ClientContact")%></ItemTemplate>
</asp:TemplateColumn>

Here is the error:
DataBinder.Eval: 'net.mysite.www.ProjectList' does not contain a property
with the name ClientContact.

Why can I access the property in the ItemDataBound event but not on the
declarative side?

The Page obviously know what kind of Object the data item is, otherwise the
error could not report it.

Any ideas? Thanks!
Nov 18 '05 #1
Share this Question
Share on Google+
7 Replies


P: n/a
Jed, dumb question: in your one that works, you use "ClientName", but in the
ones that don't you use "ClientContact". Is that right?

Bill

"Jed" wrote:
I have a web service method that returns an array of custom objects marked
serializeable with fully described public properties.

When I bind the results to a DataGrid I can access the properties in the
ItemDataBound event of the codebehind but I can't access them declaratively
in the HTML code?

Here is the code to call the method.
net.mysite.www.WSInterface proxy;
proxy = new net.mysite.www.WSInterface();
ProjectList[] pl = proxy.getProjects("%",false,true);
this.DataGrid1.DataSource = pl;
this.DataGrid1.DataBind();

Here is the code to access the property in the Item databound event.
lbl.Text = ((ProjectList)dg.DataItem).ClientName;

Here is the code that won't work on the HTML side:
Option 1:
<asp:BoundColumn HeaderText="Client Contact"
DataField="ClientContact"></asp:BoundColumn>

Option 2:
<asp:TemplateColumn HeaderText="Contact">
<ItemTemplate><%# DataBinder.Eval(Container.DataItem,
"ClientContact")%></ItemTemplate>
</asp:TemplateColumn>

Here is the error:
DataBinder.Eval: 'net.mysite.www.ProjectList' does not contain a property
with the name ClientContact.

Why can I access the property in the ItemDataBound event but not on the
declarative side?

The Page obviously know what kind of Object the data item is, otherwise the
error could not report it.

Any ideas? Thanks!

Nov 18 '05 #2

P: n/a
Jed
Unfortunately, no.

It is a good catch though. I noticed that after I posted. Both ClientName
and ClientContact are legitimate string properties of the object. I get the
same behaviour with both.

Thanks!

"Bill Borg" wrote:
Jed, dumb question: in your one that works, you use "ClientName", but in the
ones that don't you use "ClientContact". Is that right?

Bill

Nov 18 '05 #3

P: n/a
Hello Jed,

Because objects serialized from web services do not contain public properties,
they contain public fields. Fields are not able to be used for declarative
data binding.

The reason it works in your code-behind, is because you are referencing a
field, which is valid in code.

--
Matt Berther
http://www.mattberther.com
I have a web service method that returns an array of custom objects
marked serializeable with fully described public properties.

When I bind the results to a DataGrid I can access the properties in
the ItemDataBound event of the codebehind but I can't access them
declaratively in the HTML code?

Here is the code to call the method.
net.mysite.www.WSInterface proxy;
proxy = new net.mysite.www.WSInterface();
ProjectList[] pl = proxy.getProjects("%",false,true);
this.DataGrid1.DataSource = pl;
this.DataGrid1.DataBind();
Here is the code to access the property in the Item databound event.
lbl.Text = ((ProjectList)dg.DataItem).ClientName;

Here is the code that won't work on the HTML side:
Option 1:
<asp:BoundColumn HeaderText="Client Contact"
DataField="ClientContact"></asp:BoundColumn>
Option 2:
<asp:TemplateColumn HeaderText="Contact">
<ItemTemplate><%# DataBinder.Eval(Container.DataItem,
"ClientContact")%></ItemTemplate>
</asp:TemplateColumn>
Here is the error:
DataBinder.Eval: 'net.mysite.www.ProjectList' does not contain a
property
with the name ClientContact.
Why can I access the property in the ItemDataBound event but not on
the declarative side?

The Page obviously know what kind of Object the data item is,
otherwise the error could not report it.

Any ideas? Thanks!

Nov 18 '05 #4

P: n/a
Jed
Thanks, Matt,

Huh. I will look into that. I didn't know that there was even a "Field"
concept for class objects, nor do I even now understand how the Framework
maps my Property to this virtual "Field" value/construct.

Is there a best practices on how to overcome this (i.e.,custom
deserializer)? or is just impossible when working with web services?

Thanks again,
Jeff

"Matt Berther" wrote:
Hello Jed,

Because objects serialized from web services do not contain public properties,
they contain public fields. Fields are not able to be used for declarative
data binding.

The reason it works in your code-behind, is because you are referencing a
field, which is valid in code.

--
Matt Berther
http://www.mattberther.com

Nov 18 '05 #5

P: n/a
Hello Jed,

The differences between fields and properties are:

class Foo
{
public string Foo; // this is a field

private string bar;
public string Bar // this is a property
{
get { return bar; }
set { bar = value; }
}
}

According to this article [1] allowing databinding to fields is not something
thats going to change...

[1]http://www.nikhilk.net/Entry.aspx?id=42

Now, from what I've seen of ASP.NET 2.0, the class generated from the WSDL
has get/set properties instead of fields, so this might be good news for you.

Other than that, I imagine you could probably avoid using the web reference
and craft your communication layer yourself and get around this...

--
Matt Berther
http://www.mattberther.com
Thanks, Matt,

Huh. I will look into that. I didn't know that there was even a
"Field" concept for class objects, nor do I even now understand how
the Framework maps my Property to this virtual "Field"
value/construct.

Is there a best practices on how to overcome this (i.e.,custom
deserializer)? or is just impossible when working with web services?

Thanks again,
Jeff
"Matt Berther" wrote:
Hello Jed,

Because objects serialized from web services do not contain public
properties, they contain public fields. Fields are not able to be
used for declarative data binding.

The reason it works in your code-behind, is because you are
referencing a field, which is valid in code.

--
Matt Berther
http://www.mattberther.com

Nov 18 '05 #6

P: n/a
Hi,

I was searching the internet to find out how to bind the selected
columns of an array of custom objects to the datagrid and i found this
post on google groups. I want you to please have a look at my sample
code and let me know if i am on the right track or not. I am new to
..net and would like to have some guidance from u guys. here is what
iam trying to do:

1) get an array of objects from the web service method(for ex: lets
say there are 4 fields/properties for each object)
2) i want to bind only 2 fields/properties to the datagrid.
3) i have written an event handler that assigns the value of the
property to the literal control inside a datagrid's item template
column.
4) attached the event handler to the datagrid by using the
OnItemDataBound event of the datagrid
here is the code that i have:

event handler for the OnItemDataBound event :

public void Item_Bound(object sender, DataGridItemEventArgs e)
{
if(e.Item.ItemType == ListItemType.Item || e.Item.ItemType ==
ListItemType.AlternatingItem)
{
Literal l = (Literal)e.Item.FindControl("lit");
if(l.Text == String.Empty)
{
l.Text = ((FormsOrderingWS.Order)
e.Item.DataItem).OrderDate.ToString();
}
}
}

HTML code for datagrid:

<asp:DataGrid OnItemDataBound="Item_Bound"......>
<asp:Columns>
<asp:TemplateColumn HeaderText="Order Date">
<ItemTemplate>
<asp:Literal ID="lit" Runat="server"></asp:Literal>
</ItemTemplate>
</asp:TemplateColumn>
</asp:Columns>
</asp:DataGrid>
please suggest changes if iam wrong. Thank you
Nov 18 '05 #7

P: n/a
Jed
I don't see anything wrong with your approach.

In the end, I created a method to convert my object array to a DataSet so
that I could bind to the DataSet in the code, and also declaratively access
the property information from the HTML.

The sample is binding to a DropDown, which is the same as binding to a Grid
except that you have to specify, in the code, which fields represent the
Value and Text for each item. If you were using a DataGrid you could simple
use a BoundColumn to display the property values.

Here is the code I use:
/// <summary>
/// A method to convert an array of objects returned from a web service into
/// a DataSet so that they can be bound declaratively in the HTML. This is
to work
/// around the fact that the default Visual Studio WebServices references
/// deserialize object properties as fields instead of true get/set
properties.
/// </summary>
/// <param name="objectArray">The array of objects.</param>
/// <returns>A DataSet with a table named after the objectType.</returns>
public static DataSet ConvertObjectArrayToDataSet(object objectArray)
{
StringWriter writer = new StringWriter();
XmlSerializer serializer = new XmlSerializer(objectArray.GetType());
serializer.Serialize(writer, objectArray);
DataSet ds = new DataSet();
StringReader reader = new StringReader(writer.ToString());
ds.ReadXml(reader);
return ds;
}

// Here is an example of calling the static method and binding the
// resultant Dataset to a DropDown. The nice thing about this is
// that you can sort it before binding.
DataSet binder = Helpers.ConvertObjectArrayToDataSet(objs);
binder.Tables[0].DefaultView.Sort = "ClientName";
dropDown.DataSource = binder.Tables[0].DefaultView;
dropDown.DataValueField = "ID";
dropDown.DataTextField = "ClientName";
dropDown.DataBind();

"fd537" wrote:
Hi,

I was searching the internet to find out how to bind the selected
columns of an array of custom objects to the datagrid and i found this
post on google groups. I want you to please have a look at my sample
code and let me know if i am on the right track or not. I am new to
..net and would like to have some guidance from u guys. here is what
iam trying to do:

1) get an array of objects from the web service method(for ex: lets
say there are 4 fields/properties for each object)
2) i want to bind only 2 fields/properties to the datagrid.
3) i have written an event handler that assigns the value of the
property to the literal control inside a datagrid's item template
column.
4) attached the event handler to the datagrid by using the
OnItemDataBound event of the datagrid
here is the code that i have:

event handler for the OnItemDataBound event :

public void Item_Bound(object sender, DataGridItemEventArgs e)
{
if(e.Item.ItemType == ListItemType.Item || e.Item.ItemType ==
ListItemType.AlternatingItem)
{
Literal l = (Literal)e.Item.FindControl("lit");
if(l.Text == String.Empty)
{
l.Text = ((FormsOrderingWS.Order)
e.Item.DataItem).OrderDate.ToString();
}
}
}

HTML code for datagrid:

<asp:DataGrid OnItemDataBound="Item_Bound"......>
<asp:Columns>
<asp:TemplateColumn HeaderText="Order Date">
<ItemTemplate>
<asp:Literal ID="lit" Runat="server"></asp:Literal>
</ItemTemplate>
</asp:TemplateColumn>
</asp:Columns>
</asp:DataGrid>
please suggest changes if iam wrong. Thank you

Nov 19 '05 #8

This discussion thread is closed

Replies have been disabled for this discussion.