Archives / 2007 / September
  • New Wrox Silverlight 1.0 Book

    Interested in learning more about developing Silverlight 1.0 applications?  There's a lot of great info on the Website, but Wrox is also releasing a new book titled Silverlight 1.0 that will be out in October. 

    I haven't had a chance to read it yet, but knowing Ambrose and Devin my bet is that it's very good.  I'll add more info once I receive my copy.  It looks like everything is in color which should be really nice.


  • JavaScript Beautifier Tool

    I was working on a new article on Silverlight tonight and needed to "beautify" the Silverlight.js code so that I could read through it more easily.  I came across a nice JavaScript beautifier tool that did a great job converting the unformatted file into an easy to read format.  I'm sure there are several of these tools out there on the Web, but this was the first one that popped up while searching and it worked quite well in case anyone needs that type of functionality.



  • Managing ASP.NET Development, Staging and Production Connection Strings (without pulling your hair out)

    If you work with a large number of applications then you know what a pain it can be to manage multiple web.config files and multiple connection strings for development, staging/test, and production databases.  Because developers typically have development, staging, and production connection strings to manage (depending upon the environment they are working in), many different strategies have been created to handle switching from development to staging/test to production. One way to manage this task is to have multiple web.config files and simply name them differently. For example, while in development the staging web.config file may be named web.stage.config. When code has been tested in development and needs to be deployed to staging/test, the staging web.config file can be renamed to "web.config" and then moved over to the staging Web Server(s). While this works well it involves an unnecessary step that should be more automated to avoid human error and involves keeping data in-sync between two or more web.config files.

    VS.NET build events are another popular way to handle this problem.  Scott Guthrie posted about this topic and links to a post that provides great details if you'd like to go this route. 

    When large numbers of developers are involved in creating different applications that have separate web.config files for each application that may hit the same databases, a management issue comes into play. If the database connection strings change at all (for instance moving from passing username/password credentials to integrated security or database name changes due to upgrades) then all web.config files with the appropriate connection strings in them must be updated. If you manage a large number of applications (an Intranet environment for example) then you now have to open many web.config files to modify the connection strings and hope that your search and replace routine catches everything.  A more centralized way to store connection strings needs to be available in this case so that you can go to one place to make changes and be done with it!

    The example code that follows demonstrates how to avoid renaming web.config files when applications are moved between environments while also providing a centralized storage location for database connection strings as well as other server information such as proxy servers and mail servers. The code relies upon XML serialization to load data from an XML file named ServerConfig.config into an object-model, detect the environment automatically based upon data in the ServerConfig.config file, and return the appropriate connection string for the environment (development, staging, production, etc.). It also allows primary and secondary connection strings to be accessed in cases where a secondary production database server is available to use when the primary is too busy or down. An example of the Server.Config file used in the downloadable sample code is shown below.  Each server defines the environment it supports as well as the domains that can run on it.  The domains are used to dynamically lookup the proper environment (dev, staging, prod, etc.) at runtime.

    <?xml version="1.0" encoding="utf-8" ?>
        <Server Name="DevelopmentServerName" Type="Web" Environment="Development" UserName="" Password="" Domain="" IP="">
        <Server Name="StagingServerName" Type="Web" Environment="Staging" UserName="" Password="" Domain="" IP="">
        <Server Name="ProductionServerName" Type="Web" Environment="Production" UserName="" Password="" Domain="" IP="">
        <Server Name="ProxyServerName" Type="Proxy" Environment="Production" UserName="" Password="" Domain="" IP="">
        <Server Name="MailServerName" Type="Mail" Environment="Production" UserName="" Password="" Domain="" IP="">
        <ConnectionString Database="Northwind">
          <Primary>server=prodServerName;Integrated Security=SSPI;database=Northwind</Primary>
          <Secondary>server=secondaryProdServerName;Integrated Security=SSPI;database=Northwind</Secondary>
          <Staging>server=stagingServerName;Integrated Security=SSPI;database=Northwind</Staging>
          <Development>server=devServerName;Integrated Security=SSPI;database=Northwind</Development>
        <ConnectionString Database="Pubs">
          <Primary>server=prodServerName;Integrated Security=SSPI;database=Pubs</Primary>
          <Secondary>server=secondaryProdServerName;Integrated Security=SSPI;database=Pubs</Secondary>
          <Staging>server=stagingServerName;Integrated Security=SSPI;database=Pubs</Staging>
          <Development>server=devServerName;Integrated Security=SSPI;database=Pubs</Development>

    Once the ServerConfig.config file is created you can reference it in web.config (or better yet, in a higher level config file that is global to the server) by adding the following:

        <!-- Suggest placing this in a more global location rather than in multiple web.config files -->
            <add key="ServerConfigPath" value="~/ServerConfig.config"/>

    The "ServerConfigPath" key is a fixed name in this case since the object model looks specifically for that key.  Where you put the ServerConfig.config file is up to you of course, but putting it in a place that multiple Web applications can access is recommended. 

    A sample of accessing the Northwind database connection string from a data layer class is shown below.  A class named ServerConfigManager does all the work of looking up the proper connection string to use based upon the domain that the application is currently running within.  If no matching domain is found, it defaults to the development environment (that behavior can certainly be changed) and returns the development connection string.

    using System;
    using System.Data;
    using System.Data.SqlClient;
    using System.Web;
    using Wahlin.Configuration;
    namespace ServerConfig.Data {
        public class Northwind {
            public static SqlDataReader GetCustomers() {
    ConnectionString cs = ServerConfigManager.GetConnectionString("Northwind");
    //Use sproc if possible and avoid SELECT * of course.....just a demo!
    string sql = "SELECT * FROM Customers"; try { //Hit primary database SqlConnection conn = new SqlConnection(cs.Primary); SqlCommand cmd = new SqlCommand(sql,conn); conn.Open(); return cmd.ExecuteReader(CommandBehavior.CloseConnection); } catch (Exception exp) { //Log error try { //Hit secondary database if needed SqlConnection conn2 = new SqlConnection(cs.Secondary); SqlCommand cmd = new SqlCommand(sql,conn2); conn2.Open(); return cmd.ExecuteReader(CommandBehavior.CloseConnection); } catch { //Log error } } return null; } } }

    This code works in development, staging and production since the appropriate connection string to load is dynamically discovered. No code changes or file changes need to be made when the code is moved to production. All of the ServerConfig.config functionality is accessible via an object named ServerConfigManager (as shown above) which has several static methods such as GetConnectionString(string database), GetServerEnvironment(), GetServer() and GetServerConfig(). While the code does not currently encrypt/decrypt the connection strings, that functionality could certainly be added. 

    I've used this type of connection string management strategy in a large scale environment very successfully over the past few years but there are always ways to make things better so if you use the code and enhance it please let me know.  All of the code can be downloaded here along with a simple demo Website.


  • Using ADO.NET in an N-Layer Application Architecture

    I'm teaching a C# programming course this week at Interface Technical Training and promised that I'd post some demo code that demonstrates how to segregate code into multiple layers (presentation, business, and data) while using ADO.NET.  The code can be downloaded here.

    Awhile back I put together a video that walks through the fundamentals of creating N-Layer/N-Tier applications.  The video can be viewed here.



  • My Latest ASP.NET AJAX Articles

    Over the past few months I've been writing articles for the .NET Insight insight newsletter covering various ASP.NET AJAX concepts.  The articles are designed to be focused and concise and get straight to the topic without a lot of fluff.  Everything written to this point is listed below:

    Once Web Service topics are wrapped up the next articles will go into membership and provider services and then switch gears and start talking more about Silverlight.  If you have a specific aspect of ASP.NET AJAX you'd like covered let me know.


  • Slides and Code for my Silverlight and ASP.NET AJAX Integration Talk


    I had the opportunity to talk on Silverlight and ASP.NET AJAX integration yesterday at Desert Code Camp which was a lot of fun.  For those that attended (or those that are interested) you can find the slides and code at the links that follow:

  • Thanks to Lorin Thwaits (code camp director) for organizing yet another great event!



  • Speaking on Silverlight and ASP.NET AJAX Integration at Desert Code Camp

    I'll be giving a talk on September 15th at Desert Code Camp in Phoenix, AZ that discusses how Silverlight 1.0 can be integrated with ASP.NET AJAX and Web Services to enhance how data is displayed to end users.  Desert code camp is a free event and there are a lot of great sessions planned.  You can sign-up here to attend the session (space is limited at this point).  Here are a few more details about the session.

    Integrating Silverlight with ASP.NET AJAX and Web Services

    This session will discuss the fundamentals of building Silverlight 1.0 applications and show how it can be used to display data from different data sources including's Web Service. ASP.NET AJAX integration techniques will be shown along with animation features.

     In addition to my session, several co-workers and good friends from Interface Technical Training will also be presenting.  Here's a list of their sessions:

    More information about the event can be found at



  • ASP.NET AJAX Script Library Patch for iPhone 1.01 Software Update

    Matt Gibbs recently posted about an update to the ASP.NET AJAX Script library that fixes functionality broken when trying to run ASP.NET AJAX-enabled pages in the iPhone's Safari browser when the 1.01 software update has been applied to a phone.  He posts a step-by-step guide to using the scripts and explains what was changed in case you're interested.


  • C# 3.0 Features: Object Initializers

    C# 3.0 is just around the corner so I thought I'd start writing about a few of the features that it exposes and provide quick and concise examples of how they can be used.  Many of the new features rely on the compiler to generate code that you would have had to write in the past. This can result in significantly less code compared to C# 2.0 syntax in many cases.  Here's a list of some of the key features available in C# 3.0:

    • Object Initializers
    • Anonymous Types
    • Automatic Properties
    • Extension Methods
    • Lambda Expressions
    • LINQ
    • Collection Initializers

    In this post I'll discuss the fundamentals of object initializers in C# 3.0.  To get started, let's look at the standard way of initializing an object with data in C# 2.0 using constructors.  The following example creates a Person object and passes three values to its constructor.

    Person p = new Person("John", "Doe", "602-123-1234");

    As mentioned, C# 3.0 now supports the concept of "object initializers" which means you can easily assign data to specific properties in a type with having to create an explicit constructor (you can of course still create constructors as well). The standard C# { and } brackets are used to create object initializers.  Here's an example of using an object initializer to assign property data to a Person type.  It's nice because doing the same thing without using a constructor in C# 2.0 would have resulted in around 5 lines of code which is too many for something simple like property value assignments.

    Person p = new Person() {FirstName="John",LastName="Doe",Phone="602-123-1234",City="Phoenix"};

    If the Person type defines a sub object as a property you can even use object initializers to create the sub object. Here's an example of defining an Address object:

    Person p = new Person()
        FirstName = "John",
        LastName = "Doe",
        Address = new Address()
            Street = "1234 St.",
            City = "Phoenix"

    If you've used JavaScript Object Notation (normally referred to as JSON) in AJAX or other client-side applications, you'll recognize this style of syntax.  It's simple, compact, and easy to use.  Although I formatted the example above onto multiple lines to maximize readability, it could certainly be compacted quite a bit if desired. 

    In the next post I do on C# 3.0 features I'll cover anonymous types and explain how they answer a question I'm often asked in .NET language classes I teach:  "Why do I have to define a type name twice when creating an object?".


comments powered by Disqus