My First Real ASP.NET Site

I’m fortunate enough to be one of the first developers at my current employer to create a site using ASP.NET.  Currently, almost all our internet and intranet applications are built with classic ASP.  Yeah, I know.  Early adopters we ain’t.  As cool as it is that I’m getting to blaze this trail, it also means that there’s little guidance to be had, and no internal examples to look at.  Even the guys I usually go to for advice at work (Kerry Jenkins and David Mohundro) haven’t used ASP.NET that much.

Right now, I’m still struggling to come up with an architecture that I think will be clean, but will also be understandable by people that come along behind me.  I know this problem has been solved a bazillion times before, but I’ve found it a bit hard to find some examples that are close enough to real-world complexity.  I took a look at Code Camp Server, but it uses NHibernate, which I don’t think is an option for us.  Using open-source software to build applications is viewed with more than a little apprehension by management.  Their reasoning is that if something goes wrong with the software, no one has a responsibility to offer us support.  I think that hinders us in a lot of ways, but that’s a topic for another post. 😉

So, lacking any good examples, I came up with something myself.  To illustrate, I’ll use an example scenario:  creating a new user account.  I’m going to simplify it and just talk about the architecturally relevant parts.  (I’m sure nobody cares what my CSS looks like.) 

The solution has four main projects:

  • Web (Controls and aspx’s)
  • BusinessLogicLayer (so there’s as little code in the aspx.vb’s as possible)
  • DataAccessLayer (DB2 Database stuff)
  • ObjectModel (DTOs and stuff)

So, say I have a Register.aspx that looks like this:


  
       
        Please choose a user name and password:

        User Name:
       

        Password:
       

        Confirm Password:
       
       
                    onclick=”submitButton_Click” />
       
   

Standard stuff.  One thing that gave me a bit of trouble was how to get error messages back to the UI.  I toyed with the idea of having something named Context that would contain both the object the UI needed, plus messages about any errors that happened while performing the request.  I eventually rejected that in favor of having my pages implement an interface like this:

    public interface IView
    {
        string ErrorMessage { set; }
    }

So my business logic services can take an IView in their constructors, then set the ErrorMessage property when it encounters an error.  So I end up with something like this:

public partial class _Default : System.Web.UI.Page, IView
    {
        WebUserService _userSvc;

        protected void Page_Load(object sender, EventArgs e)
        {
            _userSvc = new WebUserService(this);
        }

        protected void submitButton_Click(object sender, EventArgs e)
        {
            WebUser user = _userSvc.CreateNewWebUser(userNameTextBox.Text, passwordTextBox.Text);

            if (user != null)
            {
                FormsAuthentication.SetAuthCookie(user.UserName, false);
                Response.Redirect(“Home.aspx”);
            }
        }

        #region IView Members

        public string ErrorMessage
        {
            set
            {
                serverValidator.ErrorMessage = value;
                serverValidator.IsValid = false;
            }
        }

        #endregion

}

public class WebUserService
    {
        private IView _view;

        public WebUserService(IView view)
        {
            _view = view;
        }

        public WebUser CreateNewWebUser(string userName, string password)
        {
            WebUserRepository rep = new WebUserRepository();
            WebUser user = null;

            if (rep.GetWebUserByUserName(userName) == null)
            {
                user = rep.CreateNewWebUser(userName, password);
            }
            else
            {
                _view.ErrorMessage = “That username is not available.  Please choose a different one.”;
            }

            return user;
        }
    }

public class WebUser
    {
        public string UserName { get; set; }
    }

Another thing I had a bit of trouble with was deciding where to check for things like duplicates in the database.  I thought that if I did most of that in the data access layer, I’d have the same problem communicating error messages back to the business logic layer that I did to the UI.  So, I decided to try to make the data access layer methods as granular as possible so I could do all that kind of validation in the business logic layer.  It’s more chatty than I’d like, but I think it will work for me, since we really don’t have any logic in the database.  (We don’t use stored procs or anything, because higher-ups don’t want any logic in the DB). 

I think this setup ought to work for most cases, but I don’t really have enough experience to know if I’m on the right track here.  If someone with more ASP.NET experience than me has any suggestions, I’m wide open.  I’ll post more of my experiences as I go along.

7 thoughts on “My First Real ASP.NET Site

  1. Sam Erwin

    I know what you mean about the DB stuff. I think some of the stuff I’ve worked on is one of the few systems to use ASTs (most other systems handle their own summarization) and if one of my current projects looks similar enough by the time it’s done, it’ll likely be the second project in the whole company to make use of triggers.

    Reply
  2. Brian Sullivan

    @Gary,

    Actually, no. I’ve been using VB at work, because that’s what most people at DTC are using. I’d prefer to use C#, since I cut my teeth on C++ and that syntax just “feels” better. Plus the IntelliSense and syntax highlighting in C# in VS 2005 is better. I usually use C# in any projects I do on my own, and so it shows up in my blog code samples. :-)

    Reply
  3. Gary White

    Cool, I was curious. Our area expressed the desire to go the C# route. Back in the dark ages when I attended college I did quite a bit of C/C+ and even some C++. Yes, colleges existed back then. I promise. 😉

    Reply
  4. Michael Paladino

    I’ve been meaning to sit down and think through this more, but haven’t gotten the time, so I’ll just throw out a couple of ideas. Disclaimer: I usually don’t have the time to think about architecture on the projects I work on, so I’m far from qualified to comment on this.

    First of all, I like the overall concept of what you’ve proposed. I would suggest changing the ErrorMessage string to a list of strings to handle multiple error messages such as “UserName must be at least 5 characters.” and “Password must be at least 5 characters.” I would then probably have a helper function or maybe even a function in a BasePage class or something like that take that list and format the message for display with appropriate HTML markup, etc.

    Reply
  5. Brian Sullivan

    @Michael Yeah, I’ve been thinking about making that error message a list. The only thing is that I’m using a CustomValidator control right now to display the server-side errors in a ValidationSummary along with the client-side(ish) errors. If I have multiple server-side errors, do I just dynamically add validator controls to the page? I don’t know if I like that, but I’m not sure if there’s another way to do it and still get the messages to show up in the ValidationSummary.

    Reply
  6. Michael Paladino

    I’m not crazy about this solution either, but I found a couple of folks who wrote their own ValidationSummary controls to add a .AddMessage() method. It then allows you to add an error message without first having to generate the validator control because they do that for you behind the scenes. Seems kinda clunky, but might be worth taking a look:

    http://www.codeproject.com/KB/validation/validationsummary.aspx
    http://forums.asp.net/p/1245903/2296241.aspx

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *