Jul 27 2007

My development environment is better than yours

Category: Intellectual PursuitsJoeGeeky @ 18:31

Without realizing it, I have been part of a war.  Like most wars, this one has many battle-fronts and is often overflowing with testosterone.  This is the war of development client baselines.  Every developer I have ever known has the tools they like best starting with the Operating System right down to which debugger or obfuscator they prefer. There are generally two schools of thought…

Load what you want… as long as the code gets written it will all work out in the end.

We all know where this ends up… In a word… Chaos!  For years I watched developers argue over the choice of VI, EMACS, and/or Notepad and it was a little ridiculous and certainly a waste of time.
While this approach may work in college it just isn’t realistic in most professional development environments today.

  • Corporations are trying to protect intellectual property and secure networks.   This often leads to standardized operating systems, security protocols, Malware protection, Timecard applications, etc…
  • In a team environment you really need to be able to work and communicate in a fairly consistent manner, this often leads to common source control tools, IDE’s, etc…
  • This approach can often lead to a lot of rabbit trail debugging efforts because one of the developers used something to make their product work that did not exist under source control or in the larger development/test/production environment.
  • This approach often lacks good disaster recovery procedures and we all know that development systems can become unstable at the worst times.
    The other common school of thought generally goes something like this…

All developers shall only load the approved software list and shall not work outside approved baselines at any time.’ 

We all know what this means… In a word… Micro-management!  I don’t want to be too harsh, because in some cases this kind of restriction is necessary. I like to try and remember that Software Engineering is a creative process and I believe developers need a little room for exploration.

  • Depending on how it is handled this type of approach can become very inflexible and rigid. People can spend an inordinate amount of time trying to get approval to load really basic tools.  When I was a systems integrator I watched as a segment of our users spent a year and a half fighting to get WinZip installed on their systems.
  • This type of environment often has a good disaster recovery process and can generally be reconstructed more quickly.
  • There is generally good Configuration Management.
  • This approach often leads to developers that are not happy with their environment and lack a sense of trust and/or empowerment.
  • This can be a problem when working with sub-contractors or out-sourcing partners who may not be subject to these restrictions.

If you boil it down, here are the goals…

  • Have an environment that is secure.
  • Have a disaster recovery process.
  • Establish common tools and Configuration Management (CM) over the development baseline from one iteration to the next.
  • Have the flexibility to evolve the baseline over time.
  • Provide the developers some room to experiment.

For me the solution was virtualization.  Working in a sub-contracting environment I was able to establish the following rules.

  • The Host System
    • All development clients shall be Windows Platforms and have sufficient resources to support Microsoft Virtual PC 2004 or later and Microsoft Team Explorer 2005 or later.
    • All development clients shall include a Virus, Malware, and Software Firewall with exception added to connect to project assets.
    • All development clients shall be subject to periodic reviews to ensure monthly Critical patch from Microsoft are being loaded.
    • Developers can load any legal software they or their companies deem necessary.
  • The Virtual System
    • All development shall be conducted with-in CM controlled Virtual PC baselines which are versioned and maintained in a central location. 
    • Maintenance of virtual baselines will be managed by the CM team and shall be updated and published monthly.
    • Requests to change baselines will be reviewed every month.
    • New baselines can be established to meet emerging requirements and will be assessed as requested.

Essentially, these rules attempt to provide developers/contractors the flexibility they require while providing project managers the CM they require.  Virtualization has a lot of side benefits.

  • When a system inevitably crashes. The developers are able to reset their development environment by simply copying the requisite Virtual PC files.
  • You can easily jump between older and newer baselines to support older products or to work on newer efforts.
  • Developers can do any experimentation in Virtual baselines they create for themselves.
  • CM maintains virtual baselines based on the number of software licenses they have…  For example, since we are a TFS-shop we have architect baselines, tester baselines, developer baselines, etc

This has worked well for us and may help you as well.  Don’t underestimate the power of virtualization.

Tags:

Jul 26 2007

Debugging a Web Garden

Category: Rabbit TrailsJoeGeeky @ 13:24

Today I experienced one of those errors that can just drive you crazy. Ostensibly, the error was something that you would normally expect to see in code behind or at least represented in the classic white and yellow ASP.NET error page. In this case, our testers reported they were receiving fully-fledged “Windows Internet Explorer” dialog messages with every .NET developer’s favorite message “Object reference not set to an instance of an object.”. This was happening everywhere, and appeared to increase as the system load increased.

No matter how hard I tried, I could not recreate the problem on the development systems nor was I able to catch it with any debugger…  After some head-scratching I noticed the only difference between the two environments (e.g. Development and Testing) was the number processors and that reminded me I that Web Gardening had recently been enabled. While this is a great way to enhance performance, memory management, and scalability for your web applications it requires an out-of-process state manager to ensure session state is not lost between the different processor instances in the web garden. In this case, there was no state manager and once one was added all the problems went away.

<?xml version="1.0"?>
<configuration>
    <system.web>
        <!--This added to support web gardening and 
        out-of-process session management-->
        <sessionState mode="StateServer"
            stateConnectionString="tcpip=localhost:42424"
            cookieless="false"
            timeout="20"/>
 </system.web></configuration>

Conceptually, one instance started handling a given set of user requests and as the load increased, some of them started being handled by a new instance which did not have any of the state information that was being requested. With that solved, I was left with one lingering questions…  Why did they get a dialog box?  In every case, the error messages were thrown from within AJAX Async processes. I am just glad it’s over…

Tags:

Jul 23 2007

The forgotten config files

Category: Tips and TricksJoeGeeky @ 01:51

One of the really great capabilities brought to us by .NET is its configuration architecture.  More then ever before, it is really easy to establish and use application, assembly, and web configuration files.  Unfortunately, people often forget that .NET uses a Cascading configuration architecture.  This means there are many levels of configuration that are combined at runtime to define a resulting configuration for your .NET application.  Configurations are usually a combination of your applications configuration file (Ex. App.Config/Web.Config), a central machine-level configuration file (Ex. %WINDIR%\Microsoft.NET\Framework\v2.0.50727\CONFIG\Machine.Config), and an enterprise configuration file which may be distributed via Active Directory.  Understanding the relationships between the different configuration files is important since they all have the potential to affect your products behavior.  In some cases you receive the Union of configuration elements while in others you receive the Intersection of configuration elements.

Web Applications are affected by another configuration file (Ex. %WINDIR%\Microsoft.NET\Framework\v2.0.50727\CONFIG\Web.Config) that defines the default behavior of ASP.NET Applications.  This is a great example of a configuration file that affects your applications security and performance.  Consider the following example...

<?xml version="1.0" encoding="utf-8"?>
<!-- the root web configuration file -->
<configuration>
  <system.web>
   <httpModules>
    <add name="OutputCache" .../>
    <add name="Session" .../>
    <add name="WindowsAuthentication" .../>
    <add name="FormsAuthentication" .../>
    <add name="PassportAuthentication" .../>
    <add name="RoleManager" .../>
    <add name="UrlAuthorization" .../>
    <add name="FileAuthorization" .../>
    <add name="AnonymousIdentification" .../>
    <add name="Profile" .../>
    <add name="ErrorHandlerModule" .../>
    <add name="ServiceModel" .../>
   </httpModules>
  </system.web>
</configuration>

In the extract above you can see there are a number of modules that are running agaist your application(s) that you may not need.  Generally speaking, if you have components enabled then they increase your attack surface and hamper security.

  • If you are hosting an Internet solution using Forms authentication then you probably don't need the Passport or Integrated Security modules.  Conversely, if you are hosting an Intranet application using integrated security such as Active Directory then you probably don't need the Passport or Forms Authentication modules.
  • If you are not developing Web Parts or using any user profiling support then you can disable the Profile Module.
  • If you have developed custom modules to manage authentication cookies or hydrate user principle objects (Ex. HttpContext.Current.User) then you probably don't need the RoleManager module.  This is common when you are developing custom authentication/authorization providers and/or creating cross-domain or intra-domain SSO solutions.

If you review these files you will find there are a number of configuration elements that any applications don't need (Ex. Mobile application support, web parts files, handlers, etc...).  If you are concerned about application performance or security, make sure you take the time to review these files and make sure you have a good understanding of what is present.  Enjoy...

Note: There is an edge-case for configuration cascading.  In some solutions; like pluggable thick clients; A configuration can be constructed and passed to AppDomains and Processes created by your application at runtime. 

Tags:

Jul 22 2007

Endless appSettings vs. Custom Configuration Sections

Category: Tips and TricksJoeGeeky @ 20:57

At some point in your career you will come across an application config file or Web.Config with some ridiculous number of appSetting items. While easy to use, they have a number of specific shortfalls. Namely, appSettings are not hierarchal and as such, establishing relationships is left to naming conventions which will likely become unwieldy. appSetting also lack the ability to support any form of arrays unless you count comma delimited lists. Not to worry though... these limitations and others can easily be overcome using custom configuration sections. Here is a quick How to...

  • The first thing you need to do is create a class using standard properties to define your configuration structure.
  • Modify the class to inherit from System.Configuration.ConfigurationSection
  • Modify the class by decorating the properties with the ConfigurationProperty attribute
using System.Configuration;
public class MyConfigSection : ConfigurationSection
{
     private bool _enableautologon;
     
     private string _username;
     
     private string _password;
     
     public MyConfigSection() {
          base.Init();
     }
     
     [ConfigurationProperty("enabledAutoLogon")]
     public bool EnableAutoLogon {
          get {
               return this._enableautologon;
          }
          set {
               this._enableautologon = value;
          }
     }
     
     [ConfigurationProperty("username")]
     public string Username {
          get {
               return this._username;
          }
          set {
               this._username = value;
          }
     }
     
     [ConfigurationProperty("password")]
     public string Password {
          get {
               return this._password;
           
          set {
               this._password = value;
          }
     }
 }
  • Save and compile your project
  • In the target applications Configuration File (Ex. App.Config, Web.Config, etc...) add a configuration section to define your new config section
  • Add your config section details
<?xml version="1.0"?>
<configuration>
    <configSections>
        <section name="MyConfigSection" 
       type="MyConfigSection, 
            MyConfigSectionAssembly" />
    </configSections>
    <MyConfigSection 
      enabledAutoLogon="true" 
      username="user"
      password="pass01" />
</configuration>



Thats it! This is relatively easy and there are a lot of additional options available if you check MSDN.  Enjoy...

 

Tags:

Jul 22 2007

Don't forget to secure your web service configuration

Category: Tips and TricksJoeGeeky @ 14:43

By default .NET provides a wide range of protocols to call ASMX web services.  That can be a blessing if you want to allow your consumers to access your web services using a variety of mechanisms.  But keep in mind that every protocol you open up increases your attack surface.  Securing unneeded protocols is pretty easy, all you need to do is add a few lines to your configuration file.  The below example demonstrates how to explicitly add and remove web service protocol support.  This is the configuration I run in my development environment.  When I deploy, I generally remove Documentation and HttpPostLocalhost.

<?xml version="1.0"?>
<configuration>
    <system.web>
        <webServices>
            <protocols>
                <add name="Documentation"/>
                <add name="HttpSoap"/>
                <add name="HttpSoap12"/>
                <add name="HttpPostLocalhost"/>
                <remove name="HttpGet"/>
                <remove name="HttpPost"/>
                <remove name="Unknown"/>
            </protocols>
        </webServices>
    </system.web>
</configuration>

Tags:

Jul 18 2007

Easy XML Serialization for your business objects

Category: Tips and TricksJoeGeeky @ 18:40

No matter what your architecture is, you will likely run into situations when you need to serialize a business object to XML.  There are a lot of reasons to do this...

  • Saving object data to the file system
  • Saving object XML documents/fragments to database fields
  • Performing on-the-fly XSLT transformations
  • Returning XML documents/fragments for parsing by JavaScript-driven processes
  • Aggregating object data into custom XML structures.
  • Etc, Etc, Etc...

There are a lot of ways to do this... I generally like to create a generic base class that my business object can inherit from.  If you play around with it you can add formating and other refinements.

Imports System.IO
Imports System.Xml
Imports System.Xml.Serialization
''' <summary>
''' Provides a serialization base business objects
''' </summary>
''' <typeparam name="TYPE">The type of the derived 
''' class</typeparam>
Public MustInherit Class MyGenericSerializableObject(Of TYPE)
    ''' <summary>
    ''' XMLSerializes a serializable object returning its 
    ''' string form
    ''' </summary>
    ''' <param name="source">Object to be serialized</param>
    ''' <returns>XML serialized form as a string</returns>
    Public Shared Function XMLSerialize(ByVal source As Object, _
        ByVal sourceType As System.Type) As String
        Dim serializer As New XmlSerializer(sourceType)
        Dim stringWriter As New StringWriter
        Dim xmlWriter As New XmlTextWriter(stringWriter)
        serializer.Serialize(xmlWriter, source)
        xmlWriter.Close()
        Return stringWriter.ToString
    End Function
    ''' <summary>
    ''' XMLSerializes a serializable object returning its 
    ''' string form.
    ''' </summary>
    ''' <returns>XML serialized form as a string</returns>
    Public Function XMLSerialize() As String
        Return XMLSerialize(Me, Me.GetType)
    End Function
    ''' <summary>
    ''' Deserializes an XML Serialized object
    ''' </summary>
    ''' <param name="serializedContent">Object to be 
    ''' deserialized</param>
    ''' <returns>Strongly type version of the xml 
    ''' fragment</returns>
    Public Shared Function XMLDeserialize( _
        ByVal serializedContent As String, _
        ByVal sourceType As System.Type) As Object
        Dim deSerializer As New XmlSerializer(sourceType)
        Dim stringReader As New StringReader(serializedContent)
        Dim returnValue As Object
        returnValue = deSerializer.Deserialize(stringReader)
        Return returnValue
    End Function
End Class

Tags: ,

Jul 18 2007

Adding Presence to your web applications

Have you ever wanted to add 'Who's online now' functionality?  This IM-style capability is a type of presence awareness and is being adopted by more and web communities.  Generally speaking this is pretty easy.  In most authentication systems; including those that come standard with ASP.NET; track some type of LastActivityDateTime.  If not, that ok too, because you can add your own DateTime field to your XML auth provider, SQL Accounts system, Active Directory Schema (this is a little harder), etc... 

Once that is in place all you need to do is update the value for users with named identities whenever they make a web request.  I generally tap into HttpContext.Current.User.Identity.Name with an HttpModule and if the user is authenticated, I grab their username and then update the date store.  Here is an abstract example...

Imports System.Web
''' <summary>
''' This module sets the online status and last 
''' activity date/time for logged on users
''' </summary>
Public NotInheritable Class PresenceUpdaterModule
    Implements IHttpModule
    ''' <summary>
    ''' Module Constructor
    ''' </summary>
    Public Sub Init(ByVal context As HttpApplication) _
        Implements IHttpModule.Init
        AddHandler context.PostAuthorizeRequest, _
        AddressOf Context_PostAuthorizeRequest
    End Sub
    ''' <summary>
    ''' Context handler for the PostAuthenticateRequest event
    ''' </summary>
    Private Sub Context_PostAuthorizeRequest( _
        ByVal source As Object, ByVal e As EventArgs)
        If source Is Nothing Then Exit Sub
        If HttpContext.Current.User Is Nothing OrElse _
            Not HttpContext.Current.User.Identity.IsAuthenticated Then
            'Do nothing
        Else
            UpdatePresenceStatus()
        End If
    End Sub
    ''' <summary>
    ''' This updates the users online status 
    ''' </summary>
    Private Sub UpdatePresenceStatus()
        'Add code to update the users LastActivityDateTime
    End Sub
    Public Sub Dispose() Implements IHttpModule.Dispose
        'Dispose resources as needed
    End Sub
End Class

With all of that done all you need to do is create some type of user control that encapsulates reading that value and applying graphics to represent different statuses.  For example...

  • If LastActivityDateTime <= 3 minutes the user is online
  • If LastActivityDateTime > 3 AND <= 5 minutes the user is away
  • If LastActivityDateTime > 5 minutes the user is offline

This is completely arbitrary and you can do what you want...  If you provide some form of a logoff function, you could also set an online/offline flag to track this state and automatically set the user to offline if there are no page requests within the ticket expiration period. 

With a little extra effort you could make your presence avatars link to messaging solutions and help facilitate user collaboration.

Not to overstate the obvious, but some critics may say that presence awareness in a stateless web environment is not really feasible.  For those critics, I would recommend you look at communities like MySpace.com who have become tremendously successful as a result of capabilities such as this.

Tags: ,