November 2004 - Posts

DataSourceControl - take 2

In a previous blog I posted about my disappointment with the objectDataSource control. I was wrong. I was looking at using this control based on some simple examples that I came across.

This control is in deed pretty cool, and it allows some pretty slick auto generation of stuff between my BO's and DetailViews, GridViews, etc. The trick was creating a simple little BOAgent around each respective BO that abstracted the select,update, insert, delete calls to the BO (and it's child hierarchy should one exist). I'll try to blog more about this latter. But the ObjectDataSourceControl looks a lot more like what I had hoped!

DataSourceControl, DataSourceView

The new Asp.Net 2.0 DataSournceControls, their underlying DataSourceView's and the new visual controls that bind to these like the FormView, GridView, etc. are really cool. I really think these things are going to help cut down a lot of the mundane aspects of form building, by providing mechanisms that will do a lot of this work in a simple declarative fashion. In my mind they will allow a lot of Asp.Net developers to implicitly follow a good mvc'ish pattern without even realizing it. Overall, I really like these controls and what they are going to give us in productivity and in terms of good autogenerated layering of responsibility between model, view and controller.

However, I was really disappointed to dig into the beta1 “out of the box” objectDataSource. I really thought this was going to allow me to extend a true Business Object as an available dataSource. Instead, what I found was simply another pass through to a DataSet. In my mind, the objectDataSource simply provides a little extra ability to abstract the fact that your DataSet is coming and going through some other object. What if I don't want to use a DataSet? So, out of the box we have 2 dataSourceControls that hook right to DB tables and views (Access and SQL), and we have 2 dataSourcesControls that hook to DataSets (the dataSetDataSource and in my mind the objectDataSource). I for one would like to see a DataSourceControl that is designed to link directly to a BusinessObject (that has standard property accessors and Save,Delete,Fetch methods, etc.

I think this weekend I'll be looking at extending the DataSourceControl and DataSourceView into my own custom BusinessObjectDataSource and BusinessObjectDataView. Don't plan on completing this over the weekend, but just evaluate what is required to do so, and test the waters a little. Ultimately, what I'm after is similar behavior to the way the existing controls work. Drop a new BODataSource control on a form, point it to a custom BO, then drop a FormView on a form and give it's DataSourceID property the ID of the BODataSource, and presto, magic, reflection, have a Form drawn on my page that has default ItemTemplates and EditTemplates based on the give BusinessObject's properties...Keeping my fingers crossed.

My.User.IsInRole thread versus httpcontext

I'm noticing a strange behavior with the My.User.IsInRole. I have a 2005 solution with an asp.net web project and a vb.net class library project. The class library contains business objects, and does not reference system.web. The web app obviously does. When I call My.User.IsInRole(”SomeRole”) directly from code written in the web project I correctly get a True for the given User/Role. My web project references the class library and calls upon BO's to do some work. Inside a BO, I also use My.User.IsInRole(”SomeRole”) to check authorization on something before proceeding. When I call My.User.IsInRole from the class library, I get false.

Immediately, the one difference that comes to mind is context. The web app is the overall app domain, and because it is a web app, My.User.IsInRole must be relying on HttpContext.Current.User, while the class library does not reference system.web. I would assume that behind the scenes, My.User must be relying on Threading.Thread.CurrentPrincipal. So with this thought in mind I added a reference to system.web to the class library and set a breakpoint at the line where I was calling My.User.IsInRole. I then entered the immediate window and typed ?Threading.Thread.CurrentPrincipal.IsInRole(”SomeRole”) and got back false. I then entered ?Httpconext.Current.User.IsInRole(”SomeRole”), and sure enough I got back True??? Both returned the same User, so it's not just a matter of the active thread not getting the user set from the httpcontext. So, both returned the same User, but for some reason the User's Roles were not getting set on the User account on the thread...very odd.

To temporarily work around this, I added a line to the global.asax during the AcquireRequestState to set the Threading.Thread.CurrentPrincipal = HttpContext.Current.User. This appears to have temporarily done the trick.

I'll need to research this one a little more, but looks like there might be something odd going on. I did a quick newsgroup search, but didn't see anything similiar. Has anybody else out there seen anything similiar to this with Whidbey beta? As a note, I'm using the default Access Membership Security DB created by Visual Studio.