Feed Subscribe
Exception has been thrown by the target of an invocation.


Binding object graphs to the ASP.NET GridView control

by ondrejsv 1. September 2009 15:31

One of the drawbacks of the standard ASP.NET GridView control is that you can’t use the “dot” convention to bind object graphs when using the BoundField columns. This article explains how to do it with a new inherited column.

Suppose you have a typical object graph from the AdventureWorks model consisting of objects of the Order, OrderDetail, Product, ProductCategory, and ProductSubcategory classes as shown on the figure below. It’s not important how you get the graph, be it as a result of a LINQ-to-SQL or LINQ-to-Entities query or you have created it manually from a direct SQL query through ADO.NET. Our task is to create a simple grid of all items on a given order (represented by a collection of OrderDetail objects). The user is interested in the name of the product placed on the order, it’s category and subcategory and quantity ordered and unit price it was sold for. Note that the product name, category and subcategory are attributes of the Product object while quantity and unit price are attributes of the OrderDetail object itself. In the object world the standard way of getting information from “subordinate” objects is by traversing via object references (while in the relational world we would be issuing a JOIN statement).

image

If we were binding a single OrderDetail object to a FormView control, for example, we could use a perfectly valid Eval statements:


<%# Eval("Product.Name") %>
<%# Eval("Product.Subcategory.Name ") %>
<%# Eval("Product.Subcategory.Category.Name ") %>

However, a first try to use a BoundField column within a regular ASP.NET GridView control:


<asp:BoundField HeaderText="Product" DataField="Product.Name" />

results in the HttpException "field or property with the name 'Product.Name' was not found on the selected data source."

The problem is that a BoundField column looks up only for properties of the object it’s bound to and does not analyze the DataField string if it contains a navigation path to the property.

The solution is simple: in the attached sample project you find the NavigationBoundField class which inherits from the standard BoundField class and overrides the key method GetValue.

The code uses TypeDescriptors to retrieve object properties (via GetProperties method) and PropertyDescriptors to get value of a property (GetValue method).

Disclaimer: This article and its enclosed sample just demonstrates a single technical aspect. It by no means shows how to create a properly designed multi-layered application or how to write a properly designed code in a complex application.

kick it on DotNetKicks.com vote it on WebDevVote.com

Tags:

Comments (3) -

9/1/2009 5:33:35 PM #

DotNetKicks.com

Binding object graphs to the ASP.NET GridView control You&#39;ve been kicked (a good thing) - Trackback from DotNetKicks.com

DotNetKicks.com |

9/1/2009 5:37:48 PM #

WebDevVote.com

Binding object graphs to the ASP.NET GridView control You are voted (great) - Trackback from WebDevVote.com

WebDevVote.com |

9/16/2009 12:45:04 PM #

Peter Merkač

Dear Ondrej,

This is exactly what the friends from ASP.NET controls forgot to implement. I cannot believe how hard can it sometimes be to use fields from different objects on a single Form or Details view although this is the BASIC functionality in REAL world. In my experience the processes or designs are very often connected from a group of cooperating objects, which you ofcourse want to display on a single form. Therefore i have the guts to say that their controls DO NOT model the real-world scenarios, which a good software should.

Good job.
Peter Merkač, Stroka produkt d.o.o.

Peter Merkač Slovenia |

Pingbacks and trackbacks (2)+

Comments are closed