Practical ASP.NET

Using the dataView and dataContext: What Doesn't Work (Yet)

Peter Vogel discusses what you can't do in marrying ASP.NET server-side controls with client-side data access.

I'm working through a project to recreate what I did in a series of columns that focused on using jQuery in ASP.NET (see Integrating jQuery, Web Services, AJAX and ASP.NET. This time, I'm using a WCF Data Service (though you could use any Web service) and the new dataView and dataContext client-side objects. In my last column (Accessing Server-Side Data from Client-Side Code in .NET 4, I used the dataView and dataContext to populate an ASP.NET DropDownList... sort of.

In my previous column I had used an ASP.NET DropDownList, setting the Text property of its ListItem to {{CompanyName}} and the Value property to {{CustomerID}} (the double braces are the syntax that binds client-side HTML to properties of the Customer objects retrieved by the dataContext). While the list looked good in the browser, the Value property of the DropDownList isn't being populated at the client.

Fortunately, I have at least four solutions to this problem. But first, I'll look at the problem.

Looking at the HTML
Here's the HTML that's generated from my ASP.NET server-side DropDownList by the time that the page reaches the browser:

  <select name="customerList" id="Select1" class="sys-template">
    <option value="{{CustomerID}}">{{CompanyName}}</option>
  </select>

As you can see, my DropDownList is generating an <option> tag with the CompanyID (with the binding braces) in the value attribute and the CompanyName (also with braces) in the InnerText of the option element.

The dataView, which is responsible for replacing the bound elements with actual data values (and repeating the <option> element for every object that's returned), finds the {{CompanyName}} in the tag's InnerText. That's why the DropDownList looks good in the browser.

The dataView does not, however, find the {{CustomerID}} in the value attribute. This means that if I were to retrieve the selected item from the drop down list, I'd find the CompanyName in the item's Text property (e.g. "Alfreds Futterkiste")... but I won't find the CustomerID (i.e. "ALFKI") in the selected item's value property.

The same problem occurs with the ASP.NET TextBox. To get databinding on the <input> tag that's generated by the TextBox control, I need to add a sys: prefix to the value attribute:

 <input type="text" sys:value="{{CompanyName}}"/> 

Adding the "sys:" prefix to the value attribute on the option tag would solve my problem with the drop down list. Unfortunately, there doesn't seem to be any way at the server to browbeat the ASP.NET controls into adding the sys: prefix.

Solutions
There are at least four solutions for my drop down list problem. The first is not to use an ASP.NET server-side control, but use instead a standard HTML <select> tag. If I do that, I can add the "sys:" prefix to the value attribute of the <option> element:

  <select name="customerList" id="Select1" class="sys-template">
	<option sys:value="{{CustomerID}}">{{CompanyName}}</option>
  </select>

The second solution is not to worry about the value attribute. I can use the CompanyName to retrieve customer data as easily as I can use the CustomerID (at least if I put the right index in place in my database).

Third solution: Don't use the dataContext and dataView at all. Instead, use the CascadingDropDownList extenders that have been part of the AJAX Toolkit since its inception.

Fourth solution: Don't use client-side code at all. In fact, it's not clear to me that there's a benefit in sending the page down to the browser and then immediately reaching back to the server to fill this listbox with all the CustomerIds. I'd be better off filling this DropDownList at the server using the EntityDataSource (or the DataSource of your choice). So that's what I did, as you'll see if you look in the download.

Prospects
Short term, it seems that if you want to use the dataView and dataContext objects, then you should expect to use more HTML elements and fewer ASP.NET controls. Long term, it seems reasonable to expect better integration between Microsoft's server and client solutions. The reason that Microsoft split the AJAX library off from ASP.NET was to encourage faster development in the client/AJAX arena. It shouldn't be surprising if the two sides of the solution aren't always in sync.

It's also worthwhile to remember that Microsoft is working with the jQuery team to build templating/databinding into the jQuery core. It's more likely that whatever technology comes out of that process will be the future of client-side ASP.NET. More specifically: The adoNetDataContext will continue to work, but the future will belong to a jQuery plug-in with equivalent functionality.

Next column: Retrieving data for a single customer. And, this time, I really will do it all from the client

.

About the Author

Peter Vogel is a system architect and principal in PH&V Information Services. PH&V provides full-stack consulting from UX design through object modeling to database design. Peter tweets about his VSM columns with the hashtag #vogelarticles. His blog posts on user experience design can be found at http://blog.learningtree.com/tag/ui/.

comments powered by Disqus

Featured

Subscribe on YouTube