Wrap your ASP.Net session state into a more meaningful object.

Posted on December 8, 2009 
Filed Under .Net Code, CSharp, Web Development | Leave a Comment

I’ve tried to eliminate as much session state as possible as I know that it can cause some issues, especially in a server farm environment. However, there are quite a few times that I just need to have it, and I really doubt this small application is going to be hosted in a farm environment. This application is connected to a WCF service, and I really needed to eliminate round trips without using caching since some of this data is somewhat time sensitive, but it still needs to be available across a few page views. Instead of hitting the WCF service numerous times, I save the data in session state.

The way most people seem to have done session state (at least in just random searches on the internet and in sample code), you see this:

  HttpContext.Current.Session["SomeData"] = myData;

There is nothing wrong with this. It works. Is it maintainable? Sort. Is it a potential problem? YES! What happens if you do this somewhere:

  myData = HttpContext.Current.Session["SomData"];

Obviously you are going to get a null object back and possibly an error depending on other factors. You will probably find the problem during your automated tests (you do have automated tests right?) or at minimum find it during your own testing. The problem is, sometimes things like this will slip past if they are in infrequently used parts of a system that no one bothers to check for 3 or 4 versions that pass.

So in searching around I found various posts on how to wrap your session state into a more manageable object so that typos don’t creep up and bite you on the backside. Some of the examples went way over what I needed to do and some were way too simple to make sense for me.

So here is what I did (if I happened to have stolen your code, sorry, but it happens in software).

First I created my Current Session class to store everything and I made it static since Session itself is a static object.

  public static class CurrentSession
  {
    private static HttpSessionState LiveSession
    {
      get { return HttpContext.Current.Session; }
    }
  }

This simple gives me a class that has access to the current session through a private variable called LiveSession.

Inside this class, I created another class for the CurrentUser since I needed to track the current logged in user (this user has data from the web service, so I’m not using asp.net authentication methods).

    public static class CurrentUser
    {
      public static bool IsLoggedIn
      {
        get 
        { 
          bool? logIn = GetUserItem(UserData.LoginState);
          if (!logIn.HasValue) logIn = false;
          return (logIn.Value);
        }
        set { SetUserItem(UserData.LoginState, value); }
      }

      public static FamilyData CurrentFamily
      {
        get { return (GetUserItem(UserData.Family)); }
        set { SetUserItem(UserData.FamilyInfo, value); }
      }

      private static T GetUserItem(UserData key)
      {
        T data = (T)LiveSession[Enum.GetName(typeof(UserData), key)];
        return (data);
      }

      private static void SetUserItem(UserData key, T data)
      {
        if (data == null)
          LiveSession.Remove(Enum.GetName(typeof(UserData), key));
        else
          LiveSession[Enum.GetName(typeof(UserData), key)] = data;
      }

      public enum UserData
      {
        Family,
        LoginState
      }
    }

Now, some explanation and why I did it the way I did. I could have just made my public variable have the getter and setter access the Session object directly. My typo chances would have been minimized by the fact that it’s only in two spots that I need to type it, but there is still a chance. So I created myself an enum that I can use to specify which sets of data I am saving or retrieving. I use the enum’s string value as the session object name, so all I have to do is make sure my enums never use the same name. In my RLC (Real Life Code) I use much longer enums, like CalendarFilterMonth or CalendarFilterDay, for example. In the above example, I use LoggedInUserFamily in place of just Family. While it may be long, intellisense always gets it right for me with just a few keystrokes.

The GetUserItem and SetUserItem simple save and retrieve from the LiveSession object. I use Type generics to tell the functions what type I am saving and retrieving for ease of use. My type casting never has to be done now. I tell it what I want and that’s what I will get in return.

The best part about this, is to add more, all I need to do is copy and paste a property and change a few of the options, maybe add an enum, and now I’m done. I don’t have to worry about typo’s and I can organize my session object however I want.

To use it, I just do this anywhere in my application:

  if (!CurrentSession.CurrentUser.IsLoggedIn)
     RedirectToLogin();
  else
     if (CurrentSession.CurrentUser.CurrentFamily.NeedsProfileUpdate)
        RedirectToUpdate();

Since NeedsProfileUpdate is part of my FamilyData class, I can access that directly!

WCF in an ASP.Net Application

Posted on May 22, 2009 
Filed Under Uncategorized | Leave a Comment

I posted a question on Stackoverflow.com today because I am experiancing some issues in production with a web application that is using WCF. To make a long story short, see this post.

My solution was actually quite simple and easy for me to implement. I can’t post actual code here since it’s a production project and I didn’t have time to write up a proof of concept. This is the short of it, however:

My ServiceClient object was already wrapped up in a another class where the client was created and disposed off properly. Each function call also had a prefunction and postfunction call. For example:

public string GetData()
{
   Open();
   string ret = GetData();
   Close();
   return ret;
}

Open and Close do not actually open and close the service client. Some of my functions require back to back calls so I didn’t want to be closing and opening connections repeatedly. I put these functions in, however, so that I could insert code before and after data calls, just in case I needed it. They were both empty until today. I have about 50 function calls in this WCF service, so it was a good thing I put those function calls in ahead of time!

I added 2 member variables to my class. A busy bool variable and a last used datetime. In the open function I now set busy to true and in the close I reset it back to false and also update the last used time. I then created some member properties to get how long it’s been idle (since last used time), if it’s busy, and what the communication state is (in cause of fault, but I also have fault checking inserted into Open, but let’s not go there right now).

I then created a connection pool class that simply holds a generic list of these client classes. Initially on application start, this list is blank. I created a function to get the next free client. This simply goes through this generic list and checks the communication state (has to be opened) and if it’s busy. If it’s open and not busy, I just return that client, otherwise I create a new one, add it to the pool and then return it. I also added some functions to get the state of each client and idle time, etc. For cleanup purposes, I just added a timer that executes every minute and checks to see if the idle time is over 5 minutes. If it is, it disposes that client and removes it from the pool.

My application always calls one single function to get the data client, so inserting the ability to get it from the pool was trivial. I just changed that function to get the pool object out of the Application state and then called the get next free client function and returned that.

All in all, this took less than 20 minutes to build and test. I installed it on the client’s production server since it was just crawling and a crash would be better than it’s current state anyway. I’m happy to report that things are moving quite well now. I would even venture to say that it’s running faster now than it did when I had web services set up instead of WCF.

If anyone sees a problem with this set up, or has a better way to do it, or just wants to tell me I’m dumb, go for it. I’m completely new to WCF and I will always take helpful advice.

First usage of WCF and specified fields.

Posted on April 27, 2009 
Filed Under .Net Code, WCF, Web Development | 3 Comments

I hadn’t done much in the past with WCF. We had built our web service with the classes .Net 2.0 form of web services and it worked well. Then one day I realized that we had no built in security other than SSL. Since we had added a lot more things to it that could do some damage if a hacker found the service address, I decided to add some basic security. Needless to say, it’s not as easy as it looks with straight web services.

After doing some searching, I found a few examples of using WCF and implementing custom username authentication, which is exactly what I wanted to do.

Getting WCF set up and running was quite easy. Porting over our web service code just meant creating my ServiceContract and DataContracts and then recompiling. I also had to set my SQL to Linq datacontext serialization mode to Unidirectional. After coding up my custom username authentication and testing it, things were going along quite smoothly.

Everything I had experienced with Linq to SQL serialization still applied to WCF. Relationships had to have the parent set to internal access instead of public. I did also find that the relationships seemed to need a One-To-Many in order to work right. If it was a Many-To-One or a Many-To-Many, it wasn’t being sent from the WCF service to the client. Since I was in a hurry, I left that issue on the back burner and worked around it. If I five more into it, I will post about it here.

The one thing I had not counted on, was the fact that if you have any fields (properties) marked as being nullable, the Add Service wizard in Visual Studio 2008 will also add a boolean field called fieldSpecified. So if you have a nullable field for, say, PhoneNumber, you will have that and PhoneNumberSpecified. If you fill in the PhoneNumber field, but do not set PhoneNumberSpecified to true, the field will not be sent to the WCF service.

From my little bit of research, if that Specified field is set to false, the property will not be included in the XML document sent to the WCF service. If it is set to true, it will send it whether it’s null or not.

Since some of our classes have quite a few fields and we have quite a bit of code to set those fields, I did not want to go through and set every one of these stupid properties to true when I set a field. I’m actually quite surprised that we even need to do this.

In searching for an answer, I found the long way around of writing a program to parse your service.cs (or .vb) file and inserting this code:

  [System.Xml.Serialization.XmlElementAttribute(Order = 0)]
  public string PhoneNumber
  {
    get
    {
      return this.PhoneNumber;
    }
    set
    {
      this.PhoneNumber = value;
      PhoneNumberSpecified = true; // Line Added
    }
  }

So, we have to add one line to each property that has a corresponding Specified field. Now I know why people wrote a utility to do this. That file will get overwritten each time you update your service reference.

I wasn’t too pleased I had to do this so I tried to find a better way. I finally settled on using the PropertyChanged events and some reflection to go and fill that field in.

To make things simple, my Linq to SQL classes all have a base class called BaseBusiness where I do validation and hold some original values so we can use the disconnected nature of the web with Linq to SQL entities. Since I did this, I can only derive my classes on the client side from the same base class. So I created my BaseBusiness class and included my PropertyChange event in there like this:

  public partial class BaseBusiness
  {
    public void InternalPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
    {
      if (!e.PropertyName.Contains("Specified"))
      {
        string prop = String.Format("{0}Specified", e.PropertyName);
        PropertyInfo target = this.GetType().GetProperty(prop);
        if (target != null)
        {
          PropertyInfo src = this.GetType().GetProperty(e.PropertyName);
          bool currentValue = (bool)target.GetValue(sender, null);
          bool hasValue = (src.GetValue(sender, null) == null ? false : true);
          if (currentValue != hasValue)
            target.SetValue(sender, hasValue, null);
        }
      }
    }
  }

This is pretty straight forward so far. I check to see if the field is already set to what it should be so I don’t make any unneccesary calls. Note that I use sender as the object I am using the GetValue and SetValue on. This is because the event is in a base class and wouldn’t be the right object to use for reflection since the properties would be one level up (or down, depending of where you stand).

Now the only step left is to write it up in the data classes. Which is nothing more than this:

public partial class MyDataClass : BaseBusiness
{
  public MyDataClass()
  {
    this.PropertyChanged += InternalPropertyChanged;
  }

  ~MyDataClass()
  {
    this.PropertyChanged -= InternalPropertyChanged;
  }
}

Why excellent vendor support matters.

Posted on March 20, 2009 
Filed Under Web Development, Windows Development, Work | 1 Comment

We have been having some strange problems on production installs. Things like screens clearing when they shouldn’t, applications slowing down when they didn’t before, and people’s computers running slower and slower until they close our application. When I was finally informed of this, I knew it had to be memory leaks.

So I fired up the excellent MemProfiler, I started digging into the issues. Aside from some of the other stupidity I was doing, I found a problem with a vendor’s component. We use Developers Express controls for EVERYTHING and we love them, not just the controls, but the company. When I found this issue with XtraReports not being GC’d after a dispose, I immediately created a small sample for them and submitted a ticket.

Less than 2 days later, they already have it fixed and ready to rock in the latest version. Not only am I impressed, but I am put at ease knowing that if a problem comes up, they are there to not only fix it, but fix it quickly and get it out to people.

This also happened a few months ago when their ASPxThemeDeployer wouldn’t work on my x64 Vista machine. I peeked at their code and saw why. Reported it and the VERY NEXT DAY they had a solution to the problem and pushed out an update.

I don’t have to worry. I know I am taken care of.

Thanks guys!

← Previous PageNext Page →