Tales from the Evil Empire

Bertrand Le Roy's blog

News


Bertrand Le Roy


Add to Technorati Favorites Tales from the Evil Empire - Blogged

Blogs I read

My other stuff

Archives

Do data source controls belong on the page?

I get a lot of feedback on this subject (see this post if you have time for example). More and more developers are now finally getting the multi-layered application architecture concept, which is a great improvement over the situation we had even five years ago. So many of them, the first time the see data source controls on the page, go WTF is this doing in my UI layer? Even though the ObjectDataSource is here to make them feel better about it.
Well, first of all, in ASP.NET, the Page is not the UI layer exactly. It contains the UI (the Template View, that is, the CodeFront), but it also contains some form of controller or rather Page Controller (see Martin Fowler's Patterns of Enterprise Application Architecture). So it's actually more an application surface than a simple UI surface.
But it is also wrong to see the CodeFront as the UI and the CodeBehind (or CodeBeside) as the controller. You should see it more as the declarative part and the procedural part of the same object.
So what did we have in v1? To bind a control to data, you had to do it from the procedural part of the page. If you were doing it quick and dirty, you were instantiating a Connection, a Command or DataAdapter, and filling a DataSet or DataReader with it. Then, you would attach this DataSet or DataReader as the data source of your controls and call databind. If you were doing multi-layered development, you were instantiating objects and binding them to the controls in pretty much the same way. It should be noted at this point that if you wanted to prototype a quick-and-dirty page and then migrate this to a multi-layered page later, you had to rewrite a large part of this boilerplate code. The designer made all this a little more confusing by displaying some of the procedurally defined components on the designer surface despite the fact that they were nowhere to be seen in the CodeFront markup.
As framework developers, every time we see code that's copied all over any application with little variations, we have to ask ourselves if we couldn't make it declarative.
And that's what data source controls are: a declarative way to bind controls to data. Is anyone shocked by the presence of jsp:useBean tags in a JSP page? Well, you shouldn't be any more shocked by the presence of a data source control in an ASP.NET page. On the other hand, what's wrong is procedural code in the declarative part, and you should avoid this as much as possible (it is IMHO a great design flaw in JSP to define procedural markup).
By going from the procedural part to the declarative part, the data-binding code did not change layers, it just migrated to a different part of the same object.
The end result is improved productivity as you don't have to rewrite all this boilerplate code. You will also quickly notice that the migration from quick-and-dirty SqlDataSource to an ObjectDataSource is really easy as there is no source-specific code. All the visual controls see is a data source, they don't have to know where the data came from. All you have to really change is the data source itself.
But the data source controls have additional advantages. My favorite are parameters. You can add parameters to any data source. These parameters will allow you to declaratively filter the source's data according to a query string parameter, a form field, a control value or an arbitrary object value. Having a DropDownList filter the contents of a DataGrid has never been so easy: you can have such a page without writing a single line of code.
I'm currently writing a web site with Whidbey, and my goal is to have zero code in the web site project itself. It features declaratively interchangeable data stores and a fully skinnable UI. Having zero code in the web site is not a contrived exercise, it's actually promoting good design and the good news is that it's amazingly easy to do in ASP.NET v2.
So I'll say it loud and clear: ASP.NET 2.0 promotes good design.

Comments

Jerry Pisk said:

No it doesn't. The rule is "no business logic belongs to the view (an ASPX page in ASP.NET)", not "no code belongs to the view". There can be code in the view, but not business logic code (or anything else business logic). Database connections are business logic, not views, and as such they do not belong to the view, even if you wrap them so you don't actually have to put any code there.

But you're right in one point - ASP.NET is not layered. An ASPX page is all three layers in one, it's the controller, the business logic and the view. No separation there at all, no matter how much you and Microsoft keep repeating that there is.
# July 12, 2004 4:23 PM

masqued vengor said:

Hey Bertrand, move on blogs.dng ;-)
# July 12, 2004 5:40 PM

Bertrand Le Roy said:

Jerry, you just don't get it.
Data sources are NOT business logic.
No matter how you write your applications, your presentation layer will always have to communicate with the other layers. Data sources are just a declarative way of communicating with other layers.
Yes, there can be code in the view, but there should not be code in a declarative surface such as the CodeFront. But you're right in pointing out that it's not a matter of code or no code.
Data sources are NOT database connections, they are a way for the presentation layer to communicate with other layers.
The Page Controller is not business logic either. The only code you should have in there is the code that orchestrates the UI elements and the code that establishes the communication with the other layers.
My whole point is the the communication code has always been in the page (it has to be, there has to be a way for the data to get into the Template View), it just moved from procedural to declarative.

ASP.NET does NOT contain the business layer unless you want it to be there, and we all know this is not good architecture.
But many many people are doing multilayered architecture with ASP.NET and your statement is just a troll.
As many people, you're thinking in J2EE terms. It is not because ASP.NET adopts a different angle that it's wrong. And surprise, JSF adopts almost the same architecture. Why would that be??
# July 12, 2004 5:55 PM

SomeNewKid said:

From my extended mail conversation with you, Bertrand, I took away two concepts that I feel underscore ASP.NET's strength and beauty.

The first is the concept of the Page as an application surface, not a UI surface. It is a powerful concept, and I had already added it as an epilogue to Paschal's archive of our conversation:
http://weblogs.asp.net/pleloup/archive/2004/06/18/159085.aspx

The second is the concept of CodeFront and CodeBehind representing two sides of the same coin ... declarative and procedural programming respectively. The more logic we can represent declaratively, the more powerful and graceful ASP.NET becomes.

Now to see the Page as an application surface, one that does not invalidate n-tier development, requires that developers view their app from a different perspective.

Current literature always shows an application from a "side on" view. Here, we see a data store at the bottom, above that a data layer, above that a business layer, and above that the UI layer. Business and UI processes may represent additional layers.

To best understand the ASP.NET Page, we must swing our view from "side on" to "above". Having done so, we can understand the Page as a topographic map of the entire application. That "pool" of data on our map may be a shallow pool (perhaps drawing directly from an XML file), or it may be a deep pool (with data having risen from a different physical tier, through a data layer and business layer). This analogy illustrates the power of the SqlDataSource and ObjectDataSource respectively. Looking from "above" the application, they may look similar, but their depth is completely different.

Before I took this new "from above" perspective, I found Whidbey troubling. Now, having taken this new perspective, I find Whidbey beautiful. It may be a strange superlative to apply to a development environment, but I truly find ASP.NET's declarative model to be a thing of beauty. Powerful, graceful, beautiful.
# July 12, 2004 6:46 PM

Bertrand Le Roy said:

Thank you so much for this comment, Alister, I really appreciate. So, when are you getting a blog?
# July 12, 2004 6:50 PM

Kevin Dente said:

The data source stuff is very cool, and I'm looking forward to being able to take advantage of it. But why do data source controls appear on the visual portion of the page when they don't generate any visual representation? It sems like the component tray was originally intended to hold non-visual design elements, but ASP.NET never really took advantage of it the way WinForms did.
# July 12, 2004 11:30 PM

Bertrand Le Roy said:

Kevin: I personally am uneasy with the way non-visual elements like DataAdapters used to appear in this component tray whereas it's not part of the markup (ie, the declarative part of the page). Why DataAdapters and not any public property of the page, then? Of course, the answer is that only Components appear there, but for most users, it is not clear what a Component is, so it seems quite arbitrary.
Now, data source controls are part of the markup, so they appear on the design surface like any other control. If you see the design surface as the visual representation of the markup, there is no reason why it should behave any differently than other controls.
Another reason is that it is perfectly possible for example to put a data source control in a DataList template to do hierarchical binding. Of course, doing that with a SqlDataSource would most of the time give catastrophic performance, but doing it with an object data source could make perfect sense. Don't get me wrong, there are better ways to do that, but it is still a reasonable scenario and one that we're allowing. Well, in this case, the data source couldn't be in the component tray because its data container is important in this context, it's not directly under Page, and it is repeated.
ASP.NET is closer in its spirit to Avalon than to Windows Forms anyway (which is not a surprise when you know the people behind Avalon...)
# July 13, 2004 2:45 AM

TrackBack said:

See also http://techno-weenie.net/blog/code/95/net-20-datasource-controls
# July 13, 2004 1:53 PM

Kevin Dente said:

Bertrand: The way I see it, there's actually two separate issues here: 1) does the control persist as markup on the page, and 2) is the control displayed on the visual design surface, along with "visual" controls.

Personally, I think that the notion of a separate area where non-visual elements are displayed (even if they actually "live" as markup on the page) is a useful one. Putting them on the visual design surface strikes me as potentially confusing. Where should they go? Does it matter where they live on a page? Where do you shove them so they don't interfere with your visual layout (especially in a flow layout, where they occupy space in the flow and change the layout of the page)? Fortunately, I see that Whidbey has an option to hide non-Visual controls - but of course then it's not obvious that they exist at all, and if you unhide them, it reflows your page.

I do see your point about the data-source-in-a-template case, although it seems like there could be another solution. I'll have to think about that one... ;)

Side question - how does one flag a control as non-visual in Whidbey?

# July 13, 2004 4:27 PM

Bertrand Le Roy said:

Kevin: It doesn't matter where you put a data source on a page as long as you don't need it inside some container, so I'd put them at the end of the page so that they don't disturb the rest of the visual layout.
To make a control non-visual, just mark it with the [NonVisualControl] attribute...
# July 13, 2004 5:55 PM

Kevin Dente said:

Bertrand: Yes, I realize that. My point was that rendering the non-visual controls inline in the page forces the page designer to be aware of and accomodate those issues. Personally, I would rather just see the non-visual controls down in the tray. But that's just my opinion.

Thanks for the NonVisualControl pointer.
# July 13, 2004 6:30 PM

Laurent Kempé said:

I have to say that I second Kevin. Having the non visual controls in the flow is really annoying.
# July 22, 2004 6:40 PM

Bertrand Le Roy said:

This kind of choice is not made whimsically. It relies on usability studies, which means that while some may find it annoying, most people like it better this way.
As you have an easily discoverable designer option to make non-visual controls appear and disappear at will, I don't think there's much more we can do...
# July 22, 2004 6:44 PM

Eric said:

I have several business layer components I have created that I don't want in the flow design but would like to have in the tray where the SQL Connection object and others go. The only way I have been able to accomplish this is to inherit from System.ComponentModel.Component - BUT, being that I am not inheriting from System.Web.UI.WebControl all my state management, etc is gone. I need to inherit from System.Web.UI.WebControl but still have the control be put in the tray or not be visible. I tried "marking" the control with the [NonVisualControl] attribute but it just says "The type or namespace name 'NonVisualControl' could not be found (are you missing a using directive or an assembly reference?)
"

Any suggestions? In case anyone is wondering...the control manages the routing of documents for approval.

Here is the start of one of my control declarations:

[NonVisualControl, DefaultProperty("Department"), ToolboxData("<{0}:ApprovalFlow runat=server></{0}:ApprovalFlow>"),]

public class ApprovalFlow: System.Web.UI.WebControls.WebControl
# August 10, 2004 2:16 PM

Bertrand Le Roy said:

NonVisualControlAttribute is new in ASP.NET v2.
The tray is gone too in v2. In v1, the designer would mess a lot more with your code, and would represent on the design surface objects that are really declared in the codebehind (in the infamous "do not touch" sections).
In v2, the designer only changes what is in the declarative part of the page (that is the markup), leaving what's in the codebehind entirely your business.
So in v2, your code will still run, but I don't think you'll see your components on the design surface. Except if you make them non-visual controls and put them in the markup. They will still be in the design flow, but you can hide them using "hide non visual controls".
# August 10, 2004 2:33 PM

TrackBack said:

# December 7, 2004 8:44 PM