My First Baby Steps in ASP.net

Not being an ASP guy from the get-go I needed some time to finish our first project here at A. D. Williams Engineering. ASP is way different (or way back as I think of it) from Winforms. But with the help of AJAX and the AJAX toolkit it’s getting there.

And having used it for a bit now I can see the beauty of the whole thing. I always liked the way you can present readable information with HTML. It generates really nice text flow that is so hard to recreate with Winforms. But getting some user input is a whole different story…

Technical Overview

For starters I wanted to point out some architectural decisions I made (and maybe will regret in the future). I generally broke the application into two projects, one containing all business objects and one containing the web site itself.

The Library

  • Uses SQL Server 2005 as database
  • Uses LINQ to SQL for Data Access
  • Uses the CSLA framework (http://www.lhotka.net/cslanet) as business object layer

The Web Site

  • Uses ASP.net 3.5
  • Uses ASP.net AJAX
  • Uses ASP.net AJAX Control Toolkit

Technical Details

The Business Layer

I used the CSLA network and LINQ-To-SQL for my business objects and data access. Sticking to Rocky Lhotka’s framework I did not split up the business objects and the data layer but included the data access into the business object.

There are several advantages when using the CSLA framework. For one thing you keep all the actions for an object in one place (data access, validation, authorization, data transformations …) and the object has a lot of properties and events that lets you interact with the UI.

And there is actually the problem. I love using the framework on Winforms because it allows you to really base UI actions and reactions on the behavior of the object. It almost will replace the need for a controller in a MVC kind of application. But if you try to translate this idea over to the ASP.net world you will run into some troubles.

For one, ASP.net should be stateless. You can circumvent this with the help of SessionState and ViewState and that is actually what I did with this project. I created a session state variable that holds the current business object and I reuse that in every page and user control. But this doesn’t make me happy and actually requires quite a bit of code in the page behind class.

The other problem is that if you are using CSLA with LINQ-To-SQL your objects get quite heavy. There’s a lot of data transformation going on in the background even if the resulting code is nice and short. And by its nature CSLA objects cannot be inherited and always need a factory method to instantiate which makes it difficult to user them in service scenarios. But to show you how easy it is to create a read-only list for a drop-down, here’s some code:

Protected Overrides Sub DataPortal_Fetch(ByVal criteria As Object)
    Me.RaiseListChangedEvents = False
    IsReadOnly = False
    'add empty entry
    Me.Add(New NameValuePair("", ""))
    Using ctx = ContextManager(Of VISIONDataContext).GetManager(Database.VISION)
        Dim data = From tbl In ctx.DataContext.EMs _
            Where tbl.Status = New Nullable(Of Char)(CChar("A")) _
            Order By tbl.LastName, tbl.FirstName _
            Select New NameValuePair( _
                tbl.Employee, _
                String.Format("{0}, {1}", tbl.LastName, tbl.FirstName)) 
        Me.AddRange(data)
    End Using
    IsReadOnly = True
    Me.RaiseListChangedEvents = True
End Sub

And due to the framework’s maturity it is very easy to keep track of changes (in the whole object graph not just in your current object) and send them back to the database. Using LINQ-To-SQL makes it even easier:

Using ctx = ContextManager(Of DataContext).GetManager("mydb")
    'get data from db
    ctx.DataContext.ObjectTrackingEnabled = True
    Dim data = ( _
        From p In ctx.DataContext.Projects _
        Where p.ProjectKey = Me.ProjectKey _
        Select p).SingleOrDefault
    'apply changes from instance
    Csla.Data.DataMapper.Map(Me, data, True)
    'modify child data
    DataPortal.UpdateChild(ReadProperty(Of Phases)(PhasesProperty), Me)
    DataPortal.UpdateChild(ReadProperty(Of Budgets)(BudgetsProperty), Me)
    DataPortal.UpdateChild(ReadProperty(Of Expenses)(ExpensesProperty), Me)
    'send back to DB
    ctx.DataContext.SubmitChanges() 
End Using

As stated before, I love the framework and it takes away a lot of work and headache in the winforms world. But I’m not sure if I will change the business layer into a service layer for my next project. I will make the stateless approach so much easier.

The Data Access Layer

The DAL is part of the business object and I used LINQ to SQL for it. There are some reasons for it:

  • By Using Drag&Drop with existing tables it’s so easy to set up
  • You can now program typesafe against the database tables (including intellisense)
  • You can easily create a list of (type) inside the statement and then just use it in your code (see code example above)
  • … and you are able to try something new

Nevertheless there are some issues with LINQ to SQL that has dampened my experience with it.

  • It does not support left joins! Most of you will say now that is easy to overcome and you can just create a view on a database and access it. But since I access a database from a software vendor to extract some data I am not allowed to change its schema so it turns out to be a BIG problem
  • I think it will be superseded by the new ObjectEntities Framework from Microsoft. It seems to me that LINQ to SQL was something like a prototype of how to do things with LINQ and a database and because ObjectEntities will do all of LINQ to SQL and more, Microsoft will ultimately abandon it – they have done it before!
  • Writing complex LINQ statements isn’t that easy and I’m still missing some good examples in VB.net as always.

The Web Site

We tried to create a pretty straight forward website that would keep the user mainly on a details page with a lot of in page editing and searching capabilities. The idea behind this is that we replace an existing excel document that allowed users to create some sorts of budgets and we wanted to keep this kind of user experience.

For this reason we used the new AJAX and AJAX control toolkit to create as much interactivity as possible.

As a Winform programmer I liked how easy to use the toolkit was. I didn’t have to care about java script, session states and postbacks too much. These guys did a pretty good job!

But I am not happy with the general design experience in Visual Studio 2008 as a whole. If you split up your pages into many small components (user controls) as we did and use master pages and all that stuff Visual Studio just cannot keep track of that. I actually had to resort to typing html instead of using the designer and summon all my knowledge of HTML 4.0 from 8 years ago. But I found out that all of you asp.net programmers pretty much crawl inside the HTML source anyway. Quite an experience for a pampered forms guy!

Due to my inexperience with ASP.net and its stateless nature I found myself doing a lot of code inside the page behind class. That’s not good. It’s like doing Microsoft Access forms all over again. And I found out that if you have a user control that includes some AJAX and you try to place this control more than once on a page it does have issues!

Building the better Mousetrap

This first projects gave me a lot of insight into web programming. But as always with your first project you promise yourself to do things better the next time around. So here’s my list of “things need to be done”

UI

I had a close look at ASP.net MVC (preview 2) when I started the project and immediately fell in love with the idea. I had to decide against using it because it seemed still in its early beta phase and a lot of things weren’t working as expected, AJAX or databinding for instance.

But as ASP.net MVC will be released soon and databinding isn’t as good as I thought first I will give it a try and build me next app with that framework. You should have a look at the “MVC Storefront” series which has some great ideas on how to do stuff (http://www.codeplex.com/mvcsamples/SourceControl/ListDownloadableCommits.aspx). Using a MVC model keeps your code so much nicer and the testdriven development is a good way to go. But it will kind of destroy our idea of keeping the user on one page and he will be forced to navigate through a number of pages to get to the desired result.

Business Layer

Due to the statelessness of asp.net (and Silverlight for that matter) having a full blown business object in the background is kind of overkill. I will use some of the ideas in the “MVC Storefront” app and use services and DTOs (simple Data Transfer Objects).

I already thought of creating real web services that will encapsulate the data access and write a kind of a front end for the web site that will allow the site to call the services async, do filtering and validating and so on.

So I will end up with at least 3 layers (services, front end library, web site) and I’m not sure if that’s overkill too…

Data Access

If I use web services in the background that will respond with simple DTOs to request from my page I will probably keep on using LINQ to SQL for now because it is so simple to return a list of DTOs from a LINQ select like this:

Public Function GetEmployees(ByVal request As LookupRequest) _
    As LookupResponse(Of String) Implements ILookupService.GetEmployees
    Dim retval As New LookupResponse(Of String)
    Using context As VISIONDataContext = New VISIONDataContext
        Dim data = From tbl In context.EMs _
            Where tbl.Status = New Nullable(Of Char)(CChar("A")) _
            Order By tbl.LastName, tbl.FirstName _
            Select New KeyValuePair(Of String) _
                (tbl.Employee, String.Format("{0}, {1}", tbl.LastName, tbl.FirstName))
       retval.Items = data.ToArray
    End Using
    Return retval
End Function

But I guess I will replace LINQ to SQL with ObjectEntities as soon as they are stable enough to use.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted by: steepvalley
Posted on: 7/9/2008 at 11:21 AM
Categories: Projects | VB.net | ASP.net
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed

Related posts

Add comment


 

  Country flag

[b][/b] - [i][/i] - [u][/u]- [quote][/quote]



Live preview

Friday, November 21, 2008 1:15 AM