CodeBetter.Com
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @CodeBetter

Brendan Tompkins [MVP]

Blog First. Ask Questions Later.

November 2003 - Posts

  • Assertions in ASP.NET

    So, in a roundabout way via The Benefits of Assigning a Non-default Value to Enums on D-Ral's blog, I've stumbled around looking at a bunch of stuff on Assertions. I came upon an old article that had some cool stuff in it about how to use assertions from ASP.NET, which is where I need them most.  I've found Handling Assertions in ASP .NET Web Apps  it's old, but it has some good stuff .

    -Brendan

  • Enumerated Types as Bitflags

    There's been a lot of blogging going on about the values of Enums.   One of my favorite articles on the subject has always been Extolling the Virtues of Enumerated Types that appeared in 2001 in msdn magazine.   But before I can say, “And that's about all I have to say about that“ Forrest Gump Style, I've got to mention using enums with Bitwise operations.  This is something that I use often to express a value that is a composite of other possible values. 

    For Example, I use this is with my ContainerWatch application here at the Virginia International Terminals.  I need  store which Container event a user wants to receive email notifications for.   They can elect to receive all, none or any combination of the following events, which are represented in the following enum:

    [Flags]
    public
    enum
    WatchListEventEnum
    {
      None = 0x00,               //  Binary 000000
      Arrive = 0x01,             //  Binary 000001
      Ready = 0x04,              //  Binary 000100
      Depart = 0x02,             //  Binary 000010
      FumigationComplete = 0x08, //  Binary 001000
      TermTermOut = 0x10,        //  Binary 010000
      TermTermIn = 0x20          //  Binary 100000
    }

    Now I want to store this information in a SQL Server table, and I do have them also stored in a SQL Tables as integers, but I don't want to deal with join tables to see which events users are watching for which shipping container.  So, I instead store one int value, which is a bitwise OR of all of the events they've chosen.  I can use the following logic to determine if a given event is represented in a given int value. 

    public static bool IsWatchListEvent(int bitmask, WatchListEventEnum evt)
    {
       return Convert.ToBoolean(bitmask & (int)evt);
    }

    And if I want to get the int value to store in the database, I can use this function:

    public static int GetEventBitmask(bool isArrive, bool isReady, bool isDepart, bool isFumigationComplete, bool isTermTerm)
    {
      int retVal = (isArrive) ? (int) WatchListEventEnum.Arrive : 0;
      retVal |= (isReady) ? (int) WatchListEventEnum.Ready : 0;
      retVal |= (isDepart) ? (int) WatchListEventEnum.Depart : 0;
      retVal |= (isFumigationComplete) ? (int) WatchListEventEnum.FumigationComplete : 0;
      retVal |= (isTermTerm) ? (int) WatchListEventEnum.TermTermIn + (int) WatchListEventEnum.TermTermOut : 0;
      return retVal;
    }

    I can even use the bitwise & operator from SQL like so:

    ((WL_NEW_CTR_EVTS.WL_CONTAINER_EVENT_TYPE_ID & vw_ACTIVE_WATCH_CONTAINERS.WL_CONTAINER_EVENT_TYPE_BITMASK) > 0)

    Now, a database purist may not advocate this approach,  but it works great for me in certain situations.  Okay. That's about all I have to say...

    -Brendan

  • Three Simple ways to get the most out of your Enums

    Yes. Of course. You've heard it again and again.  Enums are great.  Use them and your code will be more maintainable and you'll get less run-time errors.  Everybody says so.  See Paul's blog post here More on using Enums and designing for performance  But to really get the most from enums in C#, you've gotta have a handle on coverting to and from strings and ints to your enumerated object. I explained this to a co-worker recently, and thought I'd share it here.  Pretty simple stuff, but good to have in your bag o' tricks. 

    public enum DayOfWeek {
      Sunday = 0,
      Monday = 1,
      Tuesday = 2,
      Wednesday = 3,
      Thursday = 4,
      Friday = 5,
      Saturday = 6
    }

    1) Going from int to DayOfWeek

    DayOfWeek day = (DayOfWeek)1;  // DayOfWeek.Monday

    2) Going from DayOfWeek to int

    int i = (int) DayOfWeek.Monday; // Equivalent to 1

    3) Going from a String to DayOfWeek

    DayOfWeek day = (DayOfWeek) Enum.Parse( typeof(DayOfWeek), “Monday“ ); // DayOfWeek.Monday

    -Brendan

  • Windows Service Administration with ASP.NET - Part 2 - Remoting to the Marshalled Object

    Yesterday, I posted Windows Service Administration with ASP.NET - Part 1 - Marshalling Status Information to show how to Marshal an object from a Windows Service to for monitoring from an ASP.NET control.  Here's how to remote to it and use it from an ASCX control.

    Step 1:  Add a method to Activate the remotable object, and return the inner class. I've implemented this in a Business-tier class, but you can put this code directly in your .ascx control if you wish.

    public WatchListStatus GetCurrentStatus()
    {
      try
      {
      
      // Call GetObject to Activate our Remotable object
         WatchListStatusRemotable wlsr = (WatchListStatusRemotable) Activator.GetObject(
             
    typeof(WatchListStatusRemotable), "tcp://[SERVER]:8001/GateStatus");

         // Return the inner class that contains the monitoring info
         
    return
    wlsr.ServiceStatus;
      }
      catch
    (System.Exception ex)
      {
          System.Diagnostics.Trace.WriteLine(ex);
          System.Diagnostics.Trace.WriteLine(ex.InnerException);
         
    return null
    ;
       }
    }

    Step 2: ... Is so simple, I'm not sure I even need to explain it.  Just call your Get method, and do whatever you want with your remote object. 

    WatchListStatus status = GetCurrentStatus();

    foreach(WatchListStatusItem item in status.StatusHistory)
    {
      // ... Do some cool stuff with your remote object here and amaze your friends.
    }

    Part 3 - Controlling your Service. 

    -Brendan

    Music Tip - Explore a good Record Label, Like Candle Records

  • Windows Service Administration with ASP.NET - Part 1 - Marshalling Status Information

    This is the first of a three-part blog post on how to monitor and control a .NET Windows Service from an ASP.NET page.  The general approach I've taken involves using remoting to marshal a singleton object over a tcp channel.  If you're not familiar with Singleton objects, remoting, serialization and marshalling, you may want to go figure out that stuff first, then come back here to the specifics.  I'm not an expert on these in general, so I'm not going to even try to do them justice with explanations here.  This approach does work well for me, I'm using it to monitor a service that checks for status changes on shipping containers. It looks like this:

    Step 1: Add a reference to System.Runtime.Remoting to your Service project.  You also want to use the following namespaces in your .cs code:

    using System.Runtime.Remoting;
    using System.Runtime.Remoting.Channels;
    using System.Runtime.Remoting.Channels.Http;
    using System.Runtime.Remoting.Channels.Tcp;

    Step 2: Create a Serializable object that will be marshalled over the tcp channel. What I've done here create an object that contains the service information I want to monitor.  This class keeps information about how long the service has been running, how often it executes its checks, and an array of items that have info about each status check. It looks like this, sorta (I've simplified the code for this example).

    [Serializable]
    public class WatchListStatus
    {
      
    public
    TimeSpan ExecutionInterval;
      
    public
    WatchListStatusItem [ ] StatusItems;
      
    public
    DateTime ServiceStarted;
    }

    [Serializable]
    public class
    WatchListStatusItem
    {
      
    public int
    NumberEvents;
       public
    DateTime CheckDateTime;
      
    public
    TimeSpan ExecutionTime;
      
    public
    WatchListCheckResult Result;
    }

    [Serializable]
    public enum WatchListCheckResult
    {
      
    Successful,
      
    FailedTimeOut,
      
    FailedError
    }

    Step 3: Create a wrapper class that inherits from MarshalByRefObject.  This will be the remotable object. I've been calling these wrapper classes [wrapped-classname]Remotable for consistency. You can control the time-to-live for your object, by overriding the InitializeLifetimeService().  To make your object live for the life of the service process, return null here.

    public class WatchListStatusRemotable : MarshalByRefObject
    {
      
    public
    WatchListStatus ServiceStatus;
       
      
    // Sets the time to live for this object. When this expires, the object will have to
       // be re-marshalled
      
    public override
    Object InitializeLifetimeService()
       {
        
    return null
    ;
       }
    }

    Step 4: Add a private instance member object to your service class.  This is where the singleton model stuff becomes important.  You only want to have one instance of this object per service.

    private
    WatchListStatusRemotable m_Status;

    Step 5: On - Startup of the service, marshal the object like so:

    // Register the TCP Channel on port 8001
    ChannelServices.RegisterChannel(new
    TcpChannel(8001));

    // Register the type

    RemotingConfiguration.RegisterWellKnownServiceType (
            typeof
    (WatchListStatusRemotable), 
            "WatchListStatus", 
            WellKnownObjectMode.Singleton);

    // Now, Marshal it  this will make it available to other processes via the TCP remoting channel
    try 
    {
         RemotingServices.Marshal(m_Status, "WatchListStatus");
         System.Diagnostics.Trace.WriteLine("Watch List Status Marshalled");

    catch
    (System.Exception ex)
    {
         System.Diagnostics.Trace.WriteLine(ex.Message);
         System.Diagnostics.Trace.WriteLine(ex.InnerException);
    }

    That's it!  You can modify the object as the service does it's thing and other processes that remote to this object will have access to this information.  All you have to do is consume it with a call to Activator.GetObject from your ASP.NET code. In part two, I'll go into the details of how I did this in my app and how to control the service.

    -Brendan

    Music tip: Have I mentioned British Sea Power?

  • Adding System.Array Items

    OBSOLETE CONTENT
    The author of this post has determined that this content is obsolete. Use at your own risk! Blog posts are a point-in-time snapshot of the blogger's thinking and should not be assumed to represent this blogger's current opinions. This post was left up for historical purposes.

    So, I see this type of pattern in a bunch of different places in my code where I use arrays of objects contained in other objects.  Often, I want to use a System.Array object, like string [] instead of an ArrayList or other collection for the simplicity, ease of serialization, etc. But, I find myself re-writing code that looks like this do perform the simple task of adding an item on the end of the array:

    [Serializable]
    public class
    WatchListStatus
    {
        private WatchListStatusItem [] m_statusItems;

        public void AddStatusItem(WatchListStatusItem item)
        {
           
    // Get the length
           
    int intLength = (this.m_statusItems == null) ? 0 : this
    .m_statusItems.Length;
            WatchListStatusItem [] tmpStatus = WatchListStatusItem[intLength + 1];

           
    // Copy items if needed
           
    if(intLength > 0) Array.Copy(this
    .m_statusItems, tmpStatus, intLength);

           
    // Add to the end of the array
           
    tmpStatus[intLength] = item;

           
    // set the private instance 
           
    this
    .m_statusItems = tmpStatus;
        }
    }

    So, here's my question for everyone... Is there a better way?  I know I could do something generalized with reflection, but I'm not sure that the payoff would be that great.  I guess I'm searching for a static method of the System.Array class that could append an object, but I'm not aware of one.

    Music tip - Wanna know who's coming to town? Check out Pollstar

  • IIS 6 on Win 2003 Image Caching Problem

    Well, IIS 6 pulled a Crystal today.  We've had this problem where content won't come out of the cache when a file is updated.  Now, usually IIS does it's thing reliably, but this time it wouldn't let go of cached files.  We could over-write the file, delete it, rename it, anything, and IIS just served up the old version.  I used FileMon from SysInternals and confirmed that no IO was happening when the files were requested. 

    So, we checked everything we could think of.  ASP Caching got turned off.  Meta-tags were set to automatically disable local caching.  Re-starting the site would fix the problem, but as soon as the new file was served, it was cached, and never refreshed.

    Then, customers started complaining that the files were old.  Truckers to be precise.  They rely on IIS to show them pictures of the terminal gates so that they can put down their coffee and drive into the terminal when the gates are empty.  Now, the last thing you want is a bunch of angry truckers on your hands. Something had to be done.

    I say pulled a Crystal, because when I found a fix, it was random, obscure, un-documented and involved changing a registry setting, just like most Crystal fixes. Here was our fix:

    It had to do with the new Kernel-Mode caching in IIS. I added the reg value, UriEnableCache and set it to 0. I found the keys that control caching on a support page from MS (http://support.microsoft.com/?id=820129).

    -Brendan

    Music Tip: Gotta Love the Pogues

  • Ex-Girlfriend Discovers Blog

  • Remote Development with Visual Studio 2003

    So, our .NET framework here is catching on, and there are some people in other departments who want to use our VIT namespace for new application development.  This is great for us, despite the extra time and effort it's going to take to get them up to speed.  But, it poses a big problem.  See, we've been granted special  permission by the network Ogre here to run IIS on our local machines.  Gasp!  Can you believe it?  We're really living on the edge.  Anyhow.  The Ogre is really going to get upset and start breaking things if he is asked to give this permission to a developer in another department.  Which leads me scratching my head about this very simple issue:

    How does one do development remotely with VS 2003?  I haven't done any remote development in years, and I'm glad I don't have to do it, but I was wondering if anyone can give me some pointers about best practices for doing this?

    Music tip of the day - Re-Discover Brian Ferry

  • Network Slowness Update

    For anyone who has been following The Story of the Two Dotnet Gnomes and the Network Services Ogre,  the Ogre on Friday fixed the problem.  It WAS the network after all.  Go figure.

    Music tip of the day The Pernice Brothers

  • Factory Class Best Practices?

    Does anyone have any suggestions about where to locate factory classes?  I've got a bunch of static factory classes that I use to create other classes.  I've put a lot of these into my common tier, in our Common.Util namespace.   I just ran across a class that I can't put into my common tier, since it references a business tier object.  So I've put it into my Business.UserAuthentication.Util namespace.  But, now I'm thinking that a VIT.Business.Factories namespace may be best.  Or should I locate these in a  Util namespace for each assembly?

    Music tip: Check out The Thrills

  • Crystal Reports Poll Results

    100% of those responding to the poll (11 people) said they'd like to kick Crystal Reports in the knee.

More Posts

Our Sponsors

Free Tech Publications