BusinessRx Community

Dedicated to the advancement of software, technology and the people who devote their lives to it.

Welcome to BusinessRx Community Sign in | Join | Help
in Search

BusinessRx Reading List

These blog entries are written by industry experts and leaders. We consider this content to be a good read for any software developer or web technologist.

July 2006 - Posts

  • What's Wrong With This Code?

    The developer who wrote the following code expects to see "Hello World!" printed twice. What will the developer see, and why? (Hint: "Hello, World!" will only appear once).

    using System;

    class Program
    {
        
    static void Main()
        {
            
    Console.WriteLine(Child.Message);
            
    new Child();
            
    Console.WriteLine(Child.Message);
        }
    }

    class Parent
    {
        
    static Parent()
        {
            _message =
    "Hello!";
        }

        
    static public string Message
        {
            
    get { return _message; }
        }

        
    static protected string _message;
    }

    class Child : Parent
    {
        
    static Child()
        {
            _message =
    "Hello, World!";
        }
    }

  • Package Pages, User Controls, and Master Pages for Reuse

    Graham Dyson has an interesting project named WAPUL:

    "WAPUL is a part of a project I've been developing for creating libraries of user controls, pages and master pages (although currently no support for a master page using another master page). Its aim is to avoid bodging or extra leg work when distributing (i.e. just one .dll file)."

    Sharing controls and pages is a feature many people are looking for. Graham has a clever solution using code, a post-build step, and the aspnet_merge tool.

  • Common Gotcha: Slow VS 2005 Web Site Build Performance Because of “Dueling Assembly References”

    Symptom:

    When building a VS 2005 Web Site Project you experience very slow build times – where compilation seems to mysteriously pause for 30+ seconds (or even minutes), before continuing each time you do a build or F5 of the project.

    This compilation performance slow-down might be the result of a problem I call “dueling assembly references”.  This can occur when you setup multiple “automatic refresh enabled” file-system assembly references within your web site project to multiple assemblies that in turn share common assembly dependencies whose version numbers are different.  The post below describes this in more detail and how to fix it.

    Some background on how file-assembly references work:

    Developers using VS 2005 Web Site Projects can add references to assemblies in multiple ways.  When you right-click on a project and choose the “Add Reference” menu option, it provides a dialog like the one below that allows you to reference .NET assemblies registered in the GAC, class libraries built as projects in the same VS solution, COM components, and file-path based assemblies that you pick using the “Browse” tab of the “Add References” dialog:

    When you add a file-system based assembly reference using the “Browse” dialog above, VS 2005 Web Sites will copy the assembly picked into the \bin directory of the project as well as (by default) add a .refresh file into the \bin directory that contains a relative path string that points back to the original assembly path location:

    When you build the solution, VS will automatically check those assemblies with .refresh files to see if a newer version of the assembly is available, and if so automatically re-copy the assembly and re-compile the solution using it.  This avoids you having to manually update the assembly yourself every time it changes (it also avoids you having to check-in the assembly under source control).  If you don’t want this “automatic refresh” capability, you can delete the .refresh file – in which case VS will not check the timestamp nor update the assembly for you.

    Because assemblies often have dependent assembly references, Visual Studio will also automatically copy dependent assemblies that a reference assembly requires into the \bin directory of the target web-site as well.  For example: if you setup a file-based reference to ClassLibrary1.dll, which in turn uses an assembly called SharedLibrary.dll that resides in the same directory, Visual Studio will make sure both assemblies are copied into the Web Site’s \bin directory (note: if it didn’t do this then the app would fail to run).

    Dueling Assembly Reference Problem

    The problem I refer to as a “dueling reference” occurs when you setup multiple file-based references to assemblies from a VS 2005 Web Site Project that are each updated dynamically (using .refresh files), and which in turn have dependencies on different versions of a common shared assembly library.  

    For example, assume your web-site has a reference to AssemblyA.dll and AssemblyB.dll – which in turn each reference AssemblyC.dll.  This will work without problems if the referenced AssemblyC.dll is the same version for both AssemblyA.dll and AssemblyB.dll.  But it will cause problems if the AssemblyC.dll being used is different between the two:

    In cases where AssemblyC.dll is different, VS ends up copying the AssemblyC.dll file twice for each build – since it continually thinks that the assembly has been updated (once for each reference).  This ends up requiring all references to be recalculated by the compiler, and a full re-build to occur within the IDE.  This will cause build performance to slow down dramatically, and will cause builds to appear to pause as VS does this reference recalculation and fix-up on every single build.

    How to Fix This Problem

    There are a couple of ways to fix this problem:

    1) The “most correct” way to fix this issue is to make sure your class library references are built against the same version of any dependent assemblies.   This is good to-do not just to fix the above build performance problem, but also because it decreases the likelihood of introducing hard to figure out bugs in your application (at runtime only one version of the shared assembly is going to be used –so if you don’t fix this at least one of your dependent assemblies will end up running against an assembly it wasn’t built/unit-tested with).

    2) The “easiest quick fix” way to resolve this issue is to modify one or more of your assembly file-based references to not be “automatic refresh enabled”.  You can do this by deleting the .refresh files within your \bin directory that produce that shared conflict.  This will avoid having VS auto-update the assemblies, and so will prevent the dueling update conflict altogether.   You might find it useful to quickly disable this behavior by deleting the .refresh files as a stop-gap, and then re-enable the auto-refresh behavior once you fix the shared assembly conflicts.

    Note that VS 2005 Web Application Projects don’t have this dueling reference issue (since they don’t use .refresh files for file-assembly references).  So you won’t have this build-performance problem with it (instead it will just pick one version of the shared assembly to use).   However, you still want to be careful about cases where you have two components built against two separate versions of a shared assembly – since this can still cause hard to understand behavioral bugs at runtime that end up bypassing your carefully written unit-tests (which were run against a different version of the shared assembly).

    Hope this helps,

    Scott

    Share this post: Email it! | bookmark it! | digg it! | reddit!
  • Atlas “How Do I?” Video Series Begins

    Earlier this spring we published a really popular series of short, focused, online ASP.NET videos that we called the “How Do I?” series.  The series walked through how to use Visual Web Developer to take advantage of the cool new ASP.NET 2.0 features like Master Pages, Membership, Role Management, Profiles, 3-tier Data Access, Themes, Web Parts, etc.

    If you haven’t watched these videos yet, I'd highly recommend setting aside an hour or two to review them all (each video is only 10-15 minutes long).  They are a really great way to quickly obtain a very good understanding of the new ASP.NET 2.0 features and how they all fit together.  You can watch each video online for free here.

    The series was so popular that we asked Joe Stagner to join the ASP.NET team fulltime to help us produce even more.  Our plan is to have him publish a brand new ASP.NET “How Do I?” video on the www.asp.net web-site each week going forward from now on.

    The first set of videos that Joe is building out will cover how to use Atlas to build Ajax applications with ASP.NET.   This week he published the first two videos on this:

    You can watch them both on the www.asp.net site from this page.  Make sure to check back each week to watch new videos as they get published.

    Hope this helps,

    Scott

    P.S. For other good Atlas Samples + Tutorials, please read my previous post on Atlas Tutorials + Samples here.

    P.P.S. AlanL from Vertigo has been posting some really nice tutorials on how to use some of the controls within the Atlas Control Toolkit.  I’d recommend checking out these two great posts to read: Atlas: Creating Better Looking Checkboxes with the ToggleButtonExtender and Atlas: Creating a Confirmation Using the ModalPopup Extender

     

    Share this post: Email it! | bookmark it! | digg it! | reddit!
  • Dependency Property Notes

    I've run into dependency properties in both Windows Presentation Foundation and Windows Workflow Foundation. In trying to understand what they do, I ran across Drew Marsh's excellent introduction - "Avalon: Understanding DependencyObject and DependencyProperty". Drew's article has a WPF slant and I've mostly been seeing dependency properties from the workflow side.

    In WF, dependency properties enable three features:

    • Attached properties
    • Activity binding
    • Meta properties

    The attached property story in WF is similar to the attached property story in WPF - a parent object can add additional state to the children it manages. A WPF grid will attach Row and Column properties to its children. The dynamically attached properties allow the grid to store layout state in each child. In WF, the Conditioned Activity Group can attach a When property to each child. The When property holds a condition for the CAG to evaluate before running a child activity.

    Activity binding gives a dependency property an ActivityBind object to evaluate when asked for its value. The ActivityBind can point to other fields, properties, or methods of activities inside a workflow. One activity could bind its input properties to a previous activity's outputs. Binding makes the data flow a part of the workflow model.

    The behavior of meta properties caught me off guard. There are two types of dependency properties in WF activities: meta properties and instance properties. We set meta properties at design time and cannot change their value at runtime (they can't use binding, either). I think meta properties exist to guarantee the integrity of an activity. At runtime, I can't change the InterfaceType of a CallExternalMethod activity and screw up the rest of the parameter bindings because InterfaceType is a meta-property.  

    Dependency properties are easier to understand once you see the use cases. You have to wonder if we'd be talking about dependency properties a all if the mainstream CLR languages were more dynamic.

  • Rules to Better Software Development

    I found this great guide to .NET best practices the other day from SSW discussing recommended coding standards.  It provides a categorized list of best practices to follow when doing software (and specifically .NET) development.  You can read the .NET best practices guide here.  Very useful stuff. 

    Hope this helps,

    Scott

    Share this post: Email it! | bookmark it! | digg it! | reddit!
  • Review of the Creative Zen Vision:M

    I'm the owner of a new 30GB Zen Vision:M. The Vision:M is a portable media center and plays both MP3s and videos. The unit currently retails between $269 and $299.

    The 320x240 2.5'' LCD display looks remarkably good, even with the brightness setting at 50%. The Vision:M is a bit thicker and heavier compared to its iCompetitor, but has more color (262k versus 65k), and supports more file formats (DivX, XviD, MPEG 1/2/4, and WMV all play). I'll take function over form. The rechargeable Li-Ion battery lasted over 10 hours on a mix of video and audio (mostly audio).

    I did not install the bundled software. Windows Media Player 10 recognized the device and synchronized content without any fuss. I've synched music, TV shows from a Media Center, and movies in WMV and DivX format. Of course, not everything you can record with Media Center will synch with an external device, thanks to the pinheads at the MPAA.

    The only problem I've had is with an MSDN web cast. It seems there is an extra stream in the web casts and the stream confuses WMP. Fortunately, Marauderz M2PMCEncoderZX converts the MSDN file, and adds some additional options for anyone who is unhappy with the default conversion settings WMP uses for portable media centers.

    The Vision:M synchronizes and charges through a USB connection, but requires a small dongle to adapt the USB connector to the unit itself. A full USB re-charging takes about 4 hours. The dongle includes connections for a charging with a DC adapter, and an A/V out. Creative made life more difficult (and more expensive) by not using a standard camcorder pinout for the 3.5mm AV jack. A little bit of splicing can work around this problem.

    A touch pad on the front scrolls through menus. It can take some time to become accustomed to the touchpad, but the sensitivity is adjustable. The Vision:M also includes a microphone and FM stereo receiver (but no line input). A PIM is included that will sych with Outlook, although I haven't tried this feature (it requires an install of the bundled software, which I've have not tried).

    Overall, thumbs up for the Creative Zen Vision:M.

  • FireFox Updates with no Warning in middle of Work

    I'm all for really trying to push updates needed for security on people by default, as long as there are options to disable that "feature", but it seems FireFox is a little overzealous.  Apparently the FireFox team just released v1.5.0.5, and so browser automatically found that update and installed it, which was the default setting.  What's the problem?  I had several pages open, and I was doing some real work in one (actively typing in an edit box), when with no warning all of my pages were simply closed and the install just started.  I cannot recall any application that doesn't give you a warning if you're currently woring in it before proceeding with an update, even when things are configured to be automatic with no user interaction.  Yes, I realize there is an option to ask me what I want to do instead of being automatic, but I think the difference should be that "ask me" does not do it automatically even when I'm not working, giving me complete control, while "automatic" should still give me a warning to save my work and close things if I am in the middle of things.  What do you think?
    Share this post: Email it! | bookmark it! | digg it! | reddit!
  • Narrative JavaScript

    I stumbled across Narrative JavaScript this weekend.

    NJS uses a compiler to generate asynchronous JavaScript from procedural JavaScript. You write simple code with local variables and blocking operations. NJS takes the simple code and spits out JavaScript with all the callbacks and asynchronous goo. It's like programming with continuations.

    I wonder if Nikhil could add something like this to ScriptSharp.

  • Pickup Lines In .NET

    Imagine if everyone in the world knew .NET programming. The world might be a bit strange, but at least these pickup lines might work.

    If I were a generic collection, I'd be strongly typed for you.

    You must be the latest version, because I've been checking you out.

    I have a small problem. I put an object in a Dictionary, but I lost the key! Can you come back to my place and help me look for it?

    A TypeConverter just returned my heart, and it's ready to assign to you.

    Let's turn off option strict and do some late night binding.

    So, what's your hash code?

  • It's Getting Crowded in the ThreadPool

    It seems everybody loves the thread pool. The default scheduler in Windows Workflow uses the thread pool, as does ASP.NET and the BeginInvoke method of every delegate. There is only one pool per process, which seems a bit limiting with such a big party inside.

    Joe Duffy says there is a lot of work going into improving the ThreadPool in future versions of the base class library, I wonder if future versions will allow for some partitioning of work. .

    A couple people have asked me about custom thread pools. I do see the need in some scenarios, but writing a custom thread pool is hard. I generally point people to custom thread pools that smart people have already built:

    Jon Skeet has a custom thread pool class on this page. The pool is configurable and allows you to separate your threads from the threads in the system pool.

    Mike Woodring has a custom thread pool available on this page. The thread pool is configurable, instrumented, and has a great many features.

  • Recipe: Implementing Role Based Security with ASP.NET using Windows Authentication and SQL Server

    Problem

    You are building an Intranet expense report application for your organization, and want to enable role-based authentication and authorization capabilities within it.  Specifically, you want to create logical roles called “approvers”, “auditors”, and “administrators” for the application, and grant/deny end-users access to functionality within the application based on whether they are in these roles.

    Because your application is an Intranet solution, you want to use Windows Authentication to login the users accessing the application (avoiding them having to manually login).  However, because the roles you want to define are specific to your application, you do not want to define or store them within your network’s Windows Active Directory.  Instead, you want to define and store these roles within a database.  You then want to map Windows user accounts stored within Active Directory to these roles, and grant/deny access within the application based on them.

    In addition to using roles to authorize access to individual pages within the application, you want to dynamically filter the links displayed within the site’s menu navigation based on whether users have permissions (or not) to those links.  And lastly, you want to build-in a custom role-management administration UI directly within the expense report application for “expense app administrators” to manage these roles and control who has access to the capabilities of the app:

     

    Solution 

    I've put together a detailed post that walks through step-by-step how to implement all of this.  You can read it here, and download the completed sample I walk through how to build here.

    Hope this helps,

    Scott

    Share this post: Email it! | bookmark it! | digg it! | reddit!
  • Recipe: Dynamic Site Layout and Style Personalization with ASP.NET

    Problem:

    You want to enable end-users visiting your web-site to dynamically customize the look and feel of it.  Specifically, you want to enable them to choose different content layouts for the site, as well as different style experiences (colors, fonts, etc). 

    When building this customization system, you want to make sure you avoid duplicating logic throughout the multiple pages.  Instead, you want to be able to author the dynamic personalization logic once and have all pages inherit it.

    Solution:

    ASP.NET 2.0 makes dynamically customizing the UI experience of a web-site easy.  Specifically, it provides a flexible mechanism for defining page layouts using a feature called “Master Pages”.  It also provides a flexible mechanism for defining a page’s style look and feel via a feature called “Themes”. 

    What is nice about both “Master Pages” and “Themes” is that they can be configured either statically (by specifying the Master Page or Theme to use within an ASP.NET Page’s <% Page %> directive), or dynamically at runtime by setting the Page’s MasterPageFile and Theme properties via code.  This later approach can be easily used to enable dynamic user personalization of UI on a web-site.  The below walkthrough demonstrates how to implement this.  You can also download a complete sample that shows how to-do this here.

    Step 1: Create a New Web-Site

    Begin by starting a new web-site in either Visual Studio or Visual Web Developer (which is free).  Create two master page files called “Site1.Master” and “Site2.Master” within it. 

    We will use these two master-pages to provide two alternative layout views for the site that end-users will be able to pick between.  For the purposes of this sample we’ll keep each master file simple (although obviously you could add much more layout and content to each).  Here is a trivial example of what you could have in “Site1.Master” to start with for the purposes of this sample:

    <%@ Master Language="VB" CodeFile="Site1.master.vb" Inherits="Site1" %>

     

    <html>

    <head runat="server">

        <title>Site1 Template</title>

    </head>

    <body>

        <form id="form1" runat="server">

        <div>

            <h1>Site1 Master Template</h1>

       

            <asp:contentplaceholder id="MainContent" runat="server">

            </asp:contentplaceholder>

        </div>

        </form>

    </body>

    </html>

    After creating the two master-pages, add two new ASP.NET pages to the project – and choose to have them built using a Master Page.  Call these two new pages “Default.aspx” and “Personalize.aspx”, and have them be based on the Site1.Master template above. 

    Step 2: Add Two Themes to the Site

    Right-click on the Solution Explorer within VS and choose the “Add ASP.NET Folder->Theme” context menu option.  This will create a folder called “App_Themes” immediately underneath your application root directory.  You should then create two sub-folders underneath the “App_Themes” folder called “Blue” and “Red”.  This will define two separate themes for the site.  Within each theme folder you can add CSS stylesheets, images, and .skin files to customize the site’s appearance however you want.

    For the purposes of this sample, we’ll add a “blue.css” stylesheet under the “Blue” folder and a “red.css” stylesheet under the “Red” folder.  For now we’ll keep their implementations trivial and just set the background color for pages in them:

    body

    {

        background-color:blue;

    }

    Once this is done, our site project layout should look like this:

    Now we are ready to enable end-users visiting our site to dynamically personalize which Master Page file is used (allowing them to control the layout of the site), as well as which Theme/Stylesheet is used (allowing them to control the style of the site).

    Step 3: Enable ASP.NET Personalization

    We could save our visitors’ layout and style preferences in a variety of different places (within an http cookie, within a custom database, in a directory on the file-system, etc).  For the purposes of this sample, I’m going to use the new ASP.NET 2.0 Profile Personalization feature.  This allows me to easily save/retrieve information about users accessing the site with minimal code.

    You can use the ASP.NET Profile Personalization feature in combination with any authentication mechanism (Windows Authentication, Forms Authentication, Passport, or any other authentication approach you want).  For this sample I’m just going to use Windows Authentication to login and identify the user.  If you aren’t familiar with how Windows authentication works, please read my previous Enabling Windows Authentication Recipe.

    Once I’ve configured the site to use Windows Authentication, I can enable the ASP.NET Profile system by adding a <profile> section within my web.config file that lists the properties I want to store about users.  For the purposes of this sample I’m going to store two string properties:

    <profile>

      <properties>

        <add name="ThemePreference" type="string" defaultValue="Blue"/>

        <add name="MasterFilePreference" type="string" defaultValue="~/Site1.master"/>

      </properties>

    </profile>

    If you have SQL Express installed on your machine, then you are done.  ASP.NET will automatically provision a new SQL Express database within your app_data folder at runtime that has the appropriate Profile tables configured to save your profile data above.  You don’t need to take any additional steps to configure this.

    If you don’t have SQL Express installed, and instead want to use a SQL Server to store the Profile data, you’ll need to create a database within SQL to store the ASP.NET Application Service tables, and update your web.config file to point at the database.  The good news is that this is easy to-do.  If you haven’t done this before, please read my previous Configuring ASP.NET 2.0 Application Services to use SQL Recipe that demonstrates how to do this.

    Step 4: Building the Personalize.aspx Page

    Now that we have enabled ASP.NET Profile Personalization, we can go to work building a Personalize.aspx page that we can use to enable end-users on the site to dynamically pick which Master Page and Theme they want to use.  To do this we’ll add two <asp:dropdownlist> controls to the page to enable users to select the appropriate choices:

    <asp:Content ID="Content1" ContentPlaceHolderID="MainContent" Runat="Server">

     

        <h2>

            Pick your master file:

            <asp:DropDownList ID="ddlMasterFilePreference" runat="server">

                <asp:ListItem Text="Site Choice One" Value="~/Site1.Master" />

                <asp:ListItem Text="Site Choice Two" Value="~/Site2.Master" />

            </asp:DropDownList>

        </h2>

     

        <h2>

            Pick your theme preference:

            <asp:DropDownList ID="ddlThemePreference" runat="server">

                <asp:ListItem Text="Blue" />

                <asp:ListItem Text="Red" />

            </asp:DropDownList>

        </h2>

     

        <div>

            <asp:Button ID="UpdateBtn" runat="server" Text="Update" />

        </div>

     

    </asp:Content>

    Within the code-behind of the Personalize.aspx page we’ll then write this code to save and restore the selection to the ASP.NET Profile system:

    Partial Class Personalize

        Inherits System.Web.UI.Page

     

        Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

     

            If (Page.IsPostBack = False) Then

     

                ddlMasterFilePreference.SelectedValue = Profile.MasterFilePreference

                ddlThemePreference.SelectedValue = Profile.ThemePreference

     

            End If

     

        End Sub

     

        Sub UpdateBtn_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles UpdateBtn.Click

     

            Profile.MasterFilePreference = ddlMasterFilePreference.SelectedValue

            Profile.ThemePreference = ddlThemePreference.SelectedValue

     

            Response.Redirect("default.aspx")

     

        End Sub

     

    End Class

    Notice that ASP.NET automatically adds a strongly-typed “Profile” object to our pages that we can use to easily get type-safe access to the Profile collection we defined within our web.config file previously.  It automatically handles saving/retrieving the user’s profile data from the configured profile database.

    When the Personalize.aspx page is visited, an end-user will now be able to pick which layout and style choice they want:

    When the end-user clicks “Update” their settings will be persisted in the ASP.NET Profile database automatically.  When they revisit the Personalize.aspx page later, their preferences will be retrieved and populated within the dropdownlists.

    Step 5: Building a Base Page Class to Personalize Page Content

    We want to avoid having to repeatedly add the same logic to set the Master Page and Theme on every page of the site.  We’ll instead create a base page class that encapsulates this functionality, and have each of the pages on our site inherit from it. 

    To-do this, we’ll create a new class called “MyBasePage” that will live within our app_code directory (if we are using the VS 2005 Web Site Project option):

    Imports System.Web.UI.Page

     

    Public Class MyBasePage

        Inherits System.Web.UI.Page

     

        Protected Overrides Sub OnPreInit(ByVal e As System.EventArgs)

     

            MyBase.OnPreInit(e)

     

            Dim MyProfile As System.Web.Profile.ProfileBase

            MyProfile = HttpContext.Current.Profile

     

            Me.MasterPageFile = MyProfile.GetPropertyValue("MasterFilePreference")

            Me.Theme = MyProfile.GetPropertyValue("ThemePreference")

     

        End Sub

     

    End Class

    The above class inherits the base ASP.NET Page Class (System.Web.UI.Page), and overrides the OnPreInit method (which is called when the “PreInit” event on a page executes).  Within this method we then set the page’s “MasterPageFile” and “Theme” properties with the values the user persisted within the ASP.NET Profile Store. 

    Note that when accessing the Profile data in the code above, I’m accessing it via the “GetPropertyValue()” helper method.  This code will work both within the web-site project, as well as any companion class-library projects I might want to use to store this base class in instead (enabling me to easily re-use it across multiple projects).

    Step 6: Using the Base Page Class within Pages

    Using the base page class we built above with pages is simple.  Just open the code-behind file of any of the pages within the site, and update its base class declaration from:

    Partial Class _Default

        Inherits System.Web.UI.Page

     

    End Class

    To instead be:

    Partial Class _Default

        Inherits MyBasePage

     

    End Class

    Now when the pages within our site run, the OnPreInit method within our base class will execute, and we’ll dynamically update the Page’s Master Page and Theme to reflect what the user has personalized.  For example:

    Or:

    This is all of the logic we need to enable dynamic layout and style personalization for the site.  We can now pass off the master page templates and CSS style-sheets to a designer to customize to make them as rich and attractive as we want.

    Summary

    The above walkthrough illustrates the basics of how you can enable rich site layout and style personalization.  It also demonstrates how you can encapsulate common page functionality within a base class that you can easily re-use across multiple pages in a site – a very useful approach that can be used far beyond just personalization.

    Click here to download a complete version of the sample that you can run and examine locally.

    Below are also some links/resources I recommend checking out to learn more about ASP.NET Master Pages, Themes, and Personalization:

    ASP.NET 2.0 Website Programming : Problem – Design – Solution: This is an outstanding book by Marco Bellinaso, and uses a great “real world example” approach to walkthrough how to best take advantage of ASP.NET 2.0 features (including Master Pages, Themes, Profiles and more).

    ASP.NET “How Do I” Videos: This is a great series of short 10-15 minute videos that you can watch online to learn ASP.NET concepts.  Included are several videos that show off Master Pages, Themes and Profiles.

    ASP.NET Master Page Articles: Two great articles by K. Scott Allen that talk about both the basics and the advanced scenarios involving ASP.NET 2.0 Master Pages.

    Free ASP.NET Design Template Downloads: Professionally designed site templates for ASP.NET that are XHTML compliant, and provide re-usable Master Pages and Themes that you can use in your own projects.

    Profiles in ASP.NET 2.0: A great article by K. Scott Allen about the new ASP.NET 2.0 Profile System.

    ProfileView Control: Joshua Flanagan has implemented a cool control that you can use in ASP.NET to provide an editing view of your profile personalization data.  You can download the control + its source code from this link.

    ASP.NET 2.0 SQL Table Profile Provider: An alternative Profile Provider implementation for ASP.NET 2.0 that allows you to save Profile properties in schematized Tables or SPROCs (rather than the default storage mechanism which is an XML blob).

    VS 2005 Web Application Project Profile Support: Available as a free download, this utility works with VS 2005 Web Application Projects and enables strongly-typed Profile objects to be used within them.

    Hope this helps,

    Scott

    Share this post: Email it! | bookmark it! | digg it! | reddit!
  • See how big those folders are

    Every couple weeks I end up wondering where all the space on my hard drive is and usually track it down to a Windows folder that seems way too large (5 gigs), and a profile that comes in at over 20 gigs. The problem is that Windows makes it incredibly difficult to track down what is taking up the most space, FolderSize for Windows [found via Darrell Norton] is a nice little utility that makes it easy to see how large each folder is so you can quickly track down what is taking up all that space.

    -James

  • Upcoming Free ASP.NET Team Webcasts -- "Live from Redmond"

    Earlier this spring the ASP.NET Team presented several great MSDN web-casts.  The response to those was so great that we've scheduled a bunch of new ASP.NET 2.0 talks over the next two months.  Below is a list of them, along with a registration URL that you can use to sign-up to watch them for free: 

    Date

    Title

    Speaker

    Registration URL

    25-Jul

    ASP.NET: An Overview of ASP.NET and Windows Workflow Foundation Integration

    Kashif Alam

    Click here

    3-Aug

    ASP.NET: Building Real-World Web Application UI with Master Pages, Themes and Site Navigation

    Pete LePage

    Click here

    10-Aug

    ASP.NET: Creating Web Applications Using Visual Studio 2005 Team System

    Jeff King

    Click here

    17-Aug

    ASP.NET Atlas: A Developers Introduction to Microsoft Atlas

    Joe Stagner

    Click here

    22-Aug

    Best Practices and Techniques for Migration Visual Studio 2003 Web Projects to Visual Studio 2005

    Omar Khan

    Click here

    24-Aug

    ASP.NET: An ASP.NET Developer’s Look at Using RSS

    Joe Stagner

    Click here

    7-Sep

    ASP.NET: Under the Covers - Creating High-Availability, Scalable Web Applications

    Stefan Schackow

    Click here

    14-Sep

    ASP.NET: Using User, Roles, and Profile in ASP.NET 2.0

    Joe Stagner

    Click here

    21-Sep

    ASP.NET: Comparing PHP and ASP.net

    Joe Stagner

    Click here

    28-Sep

    ASP.NET: Security Tips & Tricks for ASP.NET Developers

    Joe Stagner

    Click here

    In addition to the ASP.NET talks above, we also are conducting some great Windows Forms, Commerce Server, and .NET Compact Framework team web-casts.  You can learn more about all of these and register for free here.

    Hope this helps,

    Scott

     

    Share this post: Email it! | bookmark it! | digg it! | reddit!
  • On The Internet, Nobody Knows You’re Guilty

    Information week has been covering the trial of a sysadmin accused of sabotaging 1,000 UBS Paine Webber servers. There is an abundance of circumstantial evidence in this case. Investigators found a printout of malicious code in the defendant’s bedroom, and the defendant bought an outstanding amount of stock puts that would benefit from a drop in UBS's price. Direct evidence, however, is from the ephemeral world of 1s and 0s: VPN logs, tape backups, and server audit trails. The defense called all these technologies into question.

    Wolfe also used his closing arguments to attempt to rebut defense theories. Chris Adams, Duronio's attorney, has argued that hackers could have been responsible for the attack. He also argued that another systems administrator … did the attack, or that it was a penetration test gone awry by Cisco Systems. The attorney at different times went after the first forensics company to work on the case, @Stake Inc., saying that they couldn't be trusted because hackers worked for the company. Then he claimed the U.S. Secret Service, called in to investigate the case, did sloppy investigative work, as did the government's forensics expert. The defense's forensics expert … testified that he couldn't be sure that the logic bomb was responsible for the damage to the UBS system.

    The defense went wild with conspiracy theories. When 40 people have the root password it’s easy to raise a shadow of a doubt. Even if the systems recorded biometric information, would you still trust an audit log? A rouge admin could alter any bit on a computer. The jury in this case found the defendant guily of securities and computer fraud on Wednesday. He'll face a maximum sentence of 6.5 to 8 years.

    If you had to decide the fate of a person, what technologies would you trust as reliable sources of evidence?

  • Displaying a Breadcrumb in the Page's Title

    ASP.NET 2.0 site navigation features includes a breadcrumb web control (SiteMapPath) that, when added to a page that exists within the site map, displays output like:

    Home > Products > Books > Fiction

    Where the nodes in the breadcumb are links back to the respective sections. Internally, the SiteMapPath control finds the current site map node being visited and walks up the site map to the root, generating the output. The SiteMapPath is great for displaying a breadcrumb as text in a web page, but wouldn't it be nice to have the web page's title automatically set to the same breadcrumb text? (The page's title is what appears in the browser's title bar and is the default text used when bookmarking a page.)

    It's really quite easy to add this functionality to your site. The site map's structure and data can be accessed programmatically via the SiteMap class. If you're using a master page, you can just drop the following code in the Page_Load event handler, otherwise you'll need to add this on a page-by-page basis:

        1 // put the "default" title here

        2 string title = "Welcome to My Website!";

        3 

        4 if (SiteMap.CurrentNode != null)

        5 {

        6     SiteMapNode current = SiteMap.CurrentNode;

        7     title = current.Title;

        8     current = current.ParentNode;

        9 

       10     while (current != null)

       11     {

       12         title = string.Concat(current.Title, " :: ", title);

       13         current = current.ParentNode;

       14     }

       15 }

       16 

       17 // finally, set the page's title to the title variable

       18 Page.Title = title;

    That's all there is to it! Initialize the title variable to the value you want displayed if the currently requested page is not in the site map. To set the page's title, simply use Page.Title (see Dynamically Setting the Page's Title in ASP.NET 2.0 for more info).

    The tutorials in my Working with Data in ASP.NET 2.0 series just leave the pages' titles set to “Untitled Page“. In hindsight, I wish I would have added the above code snippet into the master page in the Master Pages and Site Navigation tutorial, so instead of seeing “Untitled Page“ we'd see something like:

    For more information on ASP.NET 2.0's site navigation system, check out my multi-part series on 4Guys, Examining ASP.NET 2.0's Site Navigation.

  • Dynamically Loading Controls in ASP.NET Is A Pain

    Q: I'm using LoadControl to dynamically place objects into my web form. I've struggled with missing events and a host of other strange problems. I think Microsoft did a poor job designing this feature - it's a pain in my butt.

    A: If you are just rotating advertisements on a page, using LoadControl is simple.

    If you have a complex control with ViewState and events firing during postback, then LoadControl is difficult. It's not just LoadControl either - newing up a server side control and adding it to a Controls collection is also tricky.

    ASP.NET provides a thick layer of abstraction for building web applications, but dynamically loading controls requires intimate knowledge of what is happening underneath the covers. You'll need to know the page lifecycle inside and out. You'll need to know how ViewState works, and how the runtime raises postback events. It takes some time, experience, trail, and error.

    Here is a tip: keep it simple. I've seen developers overly complicate pages with dynamically loaded controls. In some scenarios, we can get the same behavior by adding the controls in markup and toggling the Visible property. The page is easier to test and modify, and generally will have fewer bugs.

    Also, this "feature" doesn't have a bad design, really. You have to realize before going down this path that you'll be shouldering many responsibilities for your control that ASP.NET would otherwise take care of. It would be difficult for Microsoft to provide a general-purpose solution to dynamically loaded controls (but they might be able to cover 60% of the use cases).

    If you still need dynamic controls, then read everything Scott Mitchell writes:

    Dynamic Controls in ASP.NET
    Working With Dynamically Created Controls
    Dynamic Web Controls, Postbacks, and View State
    Control building and ViewState Redux
    Tip: When Adding Dynamic Controls, Specify an ID

  • Building a Photo Tagging Application using ASP.NET 2.0, LINQ, and Atlas

     

    Over the last few days I’ve spent some spare time playing around with LINQ and LINQ for SQL (aka DLINQ) – both of which are incredibly cool technologies. 

     

    Specifically, I’ve been experimenting with building a photo management application that provides “tagging” support.  If you aren’t familiar with photo tagging, you might want to check out FlickR – which implements a tagging mechanism that enables users to easily annotate pictures with textual words that provide a way to easily organize and sort them.

     

    For my photo-browser I wanted to implement a “tag cloud” on every page of the site that lists the most popular tags in use on the left-hand side, and enables users to be able to click a tag within the “tag cloud” to filter the pictures by them:

     

     

    When a user clicks on an individual picture I then wanted them to see a more detailed version of the picture, as well as all the tags it has been annotated with:

     

     

    I then wanted end-users to be able to click on the “edit tags” link on the page to switch into an edit mode using Ajax, where they can easily create or edit new tags for the picture.  Any word can be suggested:

     

     

    When the tags are saved, I wanted the “tag cloud” to dynamically update with the current list of tags being used across all photos on the site, and size each tag within the cloud based on the tag’s frequency (higher usage frequency produces bigger font sizes for that tag):

     

     

    Implementing the above application is really easy using ASP.NET 2.0, LINQ and Atlas, and provides a nice demonstration of some of the really cool new data capabilities that LINQ enables.

     

    Click Here to Read My Step-By-Step Tutorial of How to Build the Above Application using LINQ, ASP.NET 2.0 and Atlas (full source code provided)

     

    Hope this helps,

     

    Scott

     

     

    Share this post: Email it! | bookmark it! | digg it! | reddit!
  • Dogfood

    Q: Has Microsoft built and shipped any products with .NET?

    A: A quick look around turns up the following frameworks, applications, and utilities with at least some managed code inside. I'm sure there are others I don't know about.

    BizTalk ServerTeam Foundation Server, SQL Server Reporting Services, SQL Server Integration Services , Microsoft Small Business Accouting, SharePoint Services, Content Management Server, MSDN Online, Media Center, Visual Studio 2005

    What else?

  • Remote Membership/Roles Management of ASP.NET 2.0 Applications

    Peter Kellner recently published parts 3 and 4 of his popular how-to series on building a custom remote security management application for ASP.NET 2.0's Membership and Roles feature.  Part 3 covers Ajax enabling it with Atlas, and Part 4 covers adding personalization support with profiles.  You can find the entire series on MSDN here:

    For more ASP.NET 2.0 Security Resources, please also check out my ASP.NET 2.0 Security Resources Page.

    Hope this helps,

    Scott

    P.S. IIS 7.0 includes built-in support within its GUI Admin tool for ASP.NET 2.0 Membership and Role Management -- making both local and remote management of sites super easy.  It will work with any custom provider you've built (so it is not limited to only working with the built-in ones).  It also does all of its remote management using HTTP based web-services -- which means it can work through firewalls as well as in shared hosting environments.  I'll post some screen-shots of this in the near future showing it off (it is pretty darn cool).

     

    Share this post: Email it! | bookmark it! | digg it! | reddit!
  • PowerShell and AppPool Names

    Yesterday we looked at stopping ASP.NET worker processes using PowerShell. However, I don't always want to stop the process by exe name or process ID, but by the name of the IIS application pool that the process is hosting. One way to do the job is with the iisapp.vbs script that ships with Windows Server.

    PS>iisapp.vbs
    W3WP.exe PID: 4420   AppPoolId: aspNet20
    W3WP.exe PID: 2572   AppPoolId: DefaultAppPool
    

    How does iisapp.vbs figure this out? The script uses WMI to look at the command line that started w3wp.exe. There is a parameter (-ap) that specifies the application pool by name.

    I beat my head against the wall trying to figure out a nice way to do this in PowerShell. Finally, I came across a post by abhishek, who wrote some script to find the services living inside svchost.exe, and everything became clear.

    function get-aspnetwp([string]$name="*")
    {
       $list = get-process w3wp
       foreach($p in $list)
       {
          $filter = "Handle='" + $p.Id + "'"
          $wmip = get-WmiObject Win32_Process -filter $filter

          if($wmip.CommandLine -match "-ap `"(.+)`"")
          {
             $appName = $matches[1]
             $p | add-member NoteProperty AppPoolName $appName
          }
       }
       $list | where { $_.AppPoolName -like $name }
    }

    This is a function named get-aspnetwp. I can put this in my home configuration so it's always available. The function first gets a list of all processes named w3wp. The System.Diagnostics.Process objects in the list do not expose a property to inspect the command line, but we can use a WMI query to fetch the command line. A regular expression (-match) can parse out the application pool name (which always follows the -ap switch).

    The function dynamically adds a property with the add-member cmdlet. The new property (AppPoolName) holds the application pool name. Ah, the power of a dynamic language! The last step in the function is to filter the list of objects against the incoming name parameter.

    Now we can party...

    PS> get-aspnetwp
    
    Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
    -------  ------    -----      ----- -----   ------     -- -----------
        419      30    31128       3924   144     2.09   2572 w3wp
        387      14    24580       7232   157     1.00   4420 w3wp
    

    and …

    PS> get-aspnetwp | select Id, AppPoolName, StartTime | format-list
    
    Id          : 4420
    AppPoolName : aspNet20
    StartTime   : 7/10/2006 10:31:08 PM
    
    Id          : 6064
    AppPoolName : DefaultAppPool
    StartTime   : 7/10/2006 11:56:57 PM
    

    and …

    PS> get-aspnetwp DefaultAppPool | kill
    

    The little function gives us object we can pipe to other cmdlets, like measure-object, where-object, select-object, etc. Sweetness.

    For more PowerShell goodness, check out the Powershell blog, the free IDE, and Scott Hanselman's podcast.

  • 50 Ways to Kill a Process

    I've been learning PowerShell and alternating between frustration and fascination. PowerShell is potent but comes with a learning curve. ScottGu recently posted about using tasklist and taskkill to stop an ASP.NET worker process, and I thought it might be a good experience to give this a whirl at the PS prompt.

    Cmdlets are the built-in commands of PowerShell. The get-process cmdlet is equivalent to tasklist, and can return all running processes:

    PS> get-process | where { $_.Name -eq "w3wp" }
    
    Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
    -------  ------    -----      ----- -----   ------     -- -----------
        480      14    26288      11552   159     1.52   2580 w3wp
        351      21    12464      22360   111     0.45   4616 w3wp
    

    Here we've filtered the process list by piping into the where-object cmdlet. The two worker processes pass the filter and appear in the output.

    One of the significant concepts behind PS is that it doesn't pipe plain text - it passes objects in the pipeline. The get-process cmdlet returns a collection of System.Diagnostics.Process objects - the same Process class we know and love from the .NET base class library, and the same class that has a Kill method.

    PS> get-process | where { $_.Name -eq "w3wp" } |
        foreach { $_.Kill() }
    

    $_ represents the current pipeline object, so the above command will invoke the Kill method of each Process object that makes it's way through the filter. We can use some shortcuts for less typing.

    PS> get-process w3wp | stop-process
    

    This filters the process list using a parameter to get-process, and pipes the output into a stop-process cmdlet. If this still seems too wordy, we can take a couple more shortcuts and use the get-process alias of gps, and the stop-processes alias of kill:

    PS> gps w3wp | kill
    

    Tune in tomorrow when we find the application pool name and uptime of each worker process.

    The problem is all inside your head
    She said to me
    The answer is easy if you
    Take it logically
    I’d like to help you in your struggle
    To be free
    There must be fifty ways
    To kill a process

    CHORUS:
    You need a PowerShell hack, Jack
    Do a task scan, Stan
    You don’t need to destroy, Roy
    Just get yourself free
    Write in C++, Gus
    You don’t need to discuss much
    Just drop the PID, Lee
    And get yourself free…

    Apologies to Paul Simon.

  • Books: The Perks of Being a Wallflower by Stephen Chbosky

    I have gotten really behind blogging about what books I have been reading. For awhile I used to blog about them on a monthly basis, but I am going to start just writing about them when I actually finish them. I have a ton to catch-up on since I haven't talked about any of the books I read on vacation or since then, so might as well get started.

    I picked up this book on a whim from B&N while browsing around. I wasn’t really sure what to expect considering that it’s published in some sort of micro-book format. It’s about the size of a paperback but more square and only about 200 pages. I was a little worried by the fact that it’s aimed at the young adult crowd and is actually published by MTV. The back sounded interesting though, and at 200 pages it wasn't too much of a time investment.

    The book is basically a collection of letters from a shy teenager to an unknown recipient about a year of his life. There is obviously something wrong with the kid from the beginning, but for the sake of not spoiling the plot I will just say he is very troubled. At times the book does an awesome job of capturing the awkwardness of being a teenager and going to high school for the first time. Unfortunately the book also relies on cliches instead of developing truly unique and believable characters.

    Overall the book was an enjoyable read but falls way short of the lofty goal of being compared to Catcher in the Rye and other real literature that capture youth, frustration, and growing into the world.

    -James

  • Annoucing Windows Developer Power Tools

    I have been a little burned out lately, which is probably why I wasn't the first, second, third, fourth, fifth, sixth, or seventh person to blog about the new book I have been working on. I think I get to the be the eighth person though.

    I am very excited about this book. It’s called Windows Developer Power Tools, is being publishing by O’Reilly, and is written by myself and my good friend Jim Holmes.

    The idea behind the book is to create a huge reference encyclopedia on some of the great time-saving and project improving tools available to you as a Windows developer. The book doesn't try to be a reference for each tool. There are whole books out there dedicated to some of these tools. Instead the book covers each tool, what it is used for, what situations it is best suited to, and then a quick introduction on how to get started with the tool. We have something like over 150 tools in over a 1000 pages so it’s definitely a big book. One thing I learned from Visual Studio Hacks is that having people write about their own tools is a very cool thing, so we continued that with WDPT. We have a plethora of great tool authors writing about their tools.

    This book has representing a couple firsts for me. It was my first time really working with a co-author. It was a very enjoyable experience, I think Jim and I will still be friends when it is all said and done. It is also the first time I have been part of the new book publishing craze of getting a beta version out, you can download it from Rough Cuts right now. I really hope we get some valuable feedback from the program to incorporate in the final edition; which we are working on right now.

    If you want to check the book out you can read through the table of contents and download a couple of sample chapters over on a small site Jim has set up. Please let us know what you think.

    -James

     

  • Credibility Returns to Scoble

    About half-way through reading Robert’s post on Microsoft Research I realized something, I believe him again. It’s not that I think he was lying before, but for his entire tenure at Microsoft there was always something in the back of my head that said “He works for Microsoft, of course he thinks that way”. 

    Welcome back Robert.

    -James

  • In Search of Windows Forms Patterns

    I have done a limited amount of Windows Forms development, especially when compared to ASP.NET. I don’t feel like I have ever truly done it right, there has always been an uncomfortable amount of duplicate code and way too much crap in the UI.

    I am working on a side project that uses Windows Forms and I want to do it right, but I have been having a hard time finding good guidance on how to best architect a Windows Forms presentation layer.

    Most of the Windows Forms books I have browsed through focus almost completely on the technology details (how to databind, how to show a dialog, etc), not how to best implement it. Patterns and Practices has some decent guidance in this area, but I keep hoping to find something more comprehensive. (This would be a great book opportunity for someone)

    Here are some of the things I have found useful so far:

    Any Windows Forms developers want to chime in with some other good resources?

     

  • Community News

    I'm excited to be part of By The Community, For The Community on the ASP.NET site. Go vote for the sample you'd like to see built, and an MVP will build it. If you have any suggestions for future samples, drop me a comment here.

    Here is how some of my compadres are spending their time:

    Sahil Malik set up shop on a new site: Winsmarts.Com. He's got his blog on and is going to run an ADO.NET boot camp this month.[1]

    Bill Ryan has been writing a book for MS Learning and making covert trips to the mothership in Redmond. [2]

    Wally McClure continues to smother the world with Wally. Wally in audio. Wally in print. [3]

    Frans Bouma just shipped v2.0 of the O/R mapper and generator LLBLGen Pro.[4]

    David Totzke is part of the team behind the launch of InfoQ.com - "Tracking change and innovation in the enterprise software development community". [5]

    DonXML just shipped XPathMania. Devil

    Sonu Kapoor continues to expand the ultra-aggregating DotNetSlackers.

    Gavin Joyce launched DotNetKicks.

    Great people, all of them.

    [1] I've diagnosed Sahil with abdominochoreophobia - a fear of belly dancers.

    [2] I'm not sure how many books Bill is currently coauthoring - I think it's around 50. Better him then me.

    [3] Oh, and Wally made an Atlas video, too.

    [4] I can't say anything about Frans; he'd argue with me and win.

    [5] When I think of Dave, I think of Canada - home of the real Smarties (which don't seem to be available here in the U.S.). 

    Devil Don has read more Heinlein than anyone I know, which makes him cool.  

  • The Next Batch of "Working with Data in ASP.NET 2.0" Tutorials are Online!

    Eight new “Working with Data in ASP.NET 2.0” Tutorials are now available online at www.asp.net. These new eight tutorials show how to edit, insert, and delete data in the GridView, DetailsView, and FormView controls using the ObjectDataSource and tiered architecture examined in the previous tutorials.

    • An Overview of Inserting, Updating, and Deleting Data
    • Examining the Events Associated with Inserting, Updating, and Deleting
    • Handling BLL- and DAL-Level Exceptions in an ASP.NET Page
    • Adding Validation Controls to the Editing and Inserting Interfaces
    • Customizing the Data Modification Interface
    • Implementing Optimistic Concurrency
    • Adding Client-Side Confirmation When Deleting
    • Limiting Data Modification Functionality Based on the User

    Like the previous 15, each tutorial is available in both a C# and VB version, can have its entire code downloaded as a self-extracting ZIP file, and can be downloaded as a PDF for offline viewing.

    Check 'em all out - http://www.asp.net/Learn/DataAccess

  • Tip/Trick: Online Database Schema Samples Library

    Problem:

    You are building a web application, and are trying to figure out how to best model the particular database schema you need for the application.

    Solution:

    One great resource I found recently on the web that I recommend checking out is a really nice library of free database models.  You can browse the library online here.

    The library includes hundreds of sample database schemas for tons of topics – ranging from “Airline Reservations” to “Organizations and People” to “Car Servicing” to “Pizza Delivery”.  A sample schema for modeling “Clients and Fees” can be seen below:

    The next time you start creating a new database, I'd recommend checking out the library to garner a few thoughts on how to think about the topic-space, and how to structure the table schema.

     

    How Do I ASP.NET Data Video

    To learn more about how to create new databases and tables within Visual Web Developer or Visual Studio, I’d recommend watching this “Create Data Driven Websites Video” that is listed on the www.asp.net web-site’s new Video Tutorials section (if you haven’t checked this out yet you should – in now contains dozens of videos with great content, with weekly new videos coming).  This particular video demonstrates how to use the database explorer within Visual Web Developer to create new tables, enter data, and build a simple three-tier data access app against it.

     

    ASP.NET Data Tutorials

    I’d also strongly recommend checking out the great ASP.NET 2.0 Data Tutorials series on the www.asp.net website which now includes 23 unique tutorials that walkthrough how to create three-tier data access applications using ASP.NET 2.0 (they cover everything from creating a new DAL, creating master/details reporting UI, creating data entry and editing pages, implementing optimistic concurrency, etc). 

    Each tutorial is written in both VB and C#, and includes full sample source code to review.  There are also PDF versions of each sample that you can download to print out as well.  We still have another 20 data tutorials still to publish -- so make sure to keep an eye on the site for updates.

    Hope this helps,

    Scott

     

    Share this post: Email it! | bookmark it! | digg it! | reddit!
  • Impersonation and Application_Start in ASP.NET

    Q: I want to query my database and cache some static data during the Application_Start event. SQL Server requires a trusted connection, and I'm using impersonation in web.config.

    <identity impersonate="true" userName="jacque" password="crackme"/>

    This works everywhere except Application_Start. The code in that method can't connect to the database. What's the dilly?

    A: The short answer is that impersonation isn't "on" during Application_Start, so SQL Server is seeing the worker process identity (NETWORK SERVICE or ASPNET) instead of Jacque's identity.

    Application_Start is an odd event. It's not really a request related event, but of course it won't fire until the first event arrives. The ASP.NET runtime doesn't start impersonation until it begins to process the request in earnest. This event fires just before impersonation begins, during a time when ASP.NET is laying out the cocktail napkins and setting up for the party.

    There are at least a couple workarounds for the problem. You could use a Singleton* design pattern, and initialize the Singleton during a request when impersonation is active (perhaps during the BeginRequest event). You could also run the worker process under an identity with rights in SQL Server.

    * Note: The article points to a "Double-Check Locking Is Broken" paper. DBCL is a problem in NET 1.x without special pre-cautions, but is not an issue in the stronger memory model of 2.0 (see rule #5 in section "Strong Model 2" of this Vance Morrison article).

  • Recipe: Enabling Windows Authentication within an Intranet ASP.NET Web application

    Problem:

    You are building an Intranet web application for your organization, and you want to authenticate the users visiting your site.  Specifically, you want to ensure that they are logged in using a valid Windows account on the network, and you want to be able to retrieve each incoming user's Windows account name and Windows group membership within your application code on the server.

    Discussion:

    Authentication is the process of identifying and validating the identity of a client accessing an application.  Put more simply -- it is the process of identifying “who” the end-user is when they visit a website. 

    Authentication is typically used in combination with Authorization -- which is the process of figuring out whether the authenticated user has permissions to access a particular page/resource or to perform some action.  For example, when an end-user in a browser tries to access a page, ASP.NET might authenticate the user as “Scott”, and would then run through the configured authorization rules for the requested page to figure out whether “Scott” has permission to access it.

    ASP.NET supports multiple ways to authenticate browser users visiting a web application, and implements a flexible set of ways to authorize which permissions they have within the application.

    For Internet web applications, the most common authentication scenario to use it called Forms Authentication.  Forms Authentication enables a developer to provide a standard HTML login form within their application, and then validate the username/password an end-user submits against a database or other credential store.  Assuming the username/password combination is correct, the developer can then ask ASP.NET to issue an encrypted HTTP cookie to identify and track the user.

    For Intranet web applications, the most common authentication scenario to use is called Windows Authentication.  Windows Authentication avoids the need to create a login form within an application, and does not require end-users to manually enter their username/password credentials to login to the application.  Instead, ASP.NET and IIS can automatically retrieve and validate the Windows username of the end-user visiting the site in a secure way.  The benefit of this approach is that it improves the end-user customer experience since users don’t have to re-type their passwords, and/or maintain separate accounts.  It also allows companies to re-use a common security identity system across their entire corporate networks (Windows clients, servers, file-shares, printers, and web apps).

    Solution:

    To enable Windows Authentication within an ASP.NET Application, you should make sure that you have “Integrated Windows Authentication” (formerly called NTLM authentication) enabled within IIS for the application you are building. 
     
    You should then add a web.config file to the root directory of your ASP.NET application that contains an <authentication> section which sets the mode to “Windows”. 

    You should also then add an <authorization> section to the same web.config file that denies access to “anonymous” users visiting the site.  This will force ASP.NET to always authenticate the incoming browser user using Windows Authentication – and ensure that from within code on the server you can always access the username and Windows group membership of the incoming user.

    The below web.config file demonstrates how to configure both steps described above:

     <configuration>

        <system.web>

            <authentication mode="Windows" />

             <authorization>
                 <deny users="?"/>
              </authorization>
         
        </system.web>
     
    </configuration>

    Note that the <deny users=”?”/> directive within the <authorization> section above is what tells ASP.NET to deny access to the application to all “anonymous” users to the site (the “?” character means anonymous user).  This forces Windows to authenticate the user, and ensures that the username is always available from code on the server.

    Obtaining the Logged-in Username via Code

    Once you follow the above configuration steps, you can easily access the logged-in username and role/group mappings for the authenticated user within ASP.NET.  For example, you could use the code-snippet below within an ASP.NET page to easily obtain the username of the visiting user:

    Dim username As String
    username = User.Identity.Name 

    The code-snippet above works because there is a “User” property built-in to all ASP.NET pages and user-controls.  If you want to gain access to this user data from within a regular class or business object (which doesn’t have this property provided), you can write code like below to achieve the same result:

    Dim User As System.Security.Principal.IPrincipal
    User = System.Web.HttpContext.Current.User

    Dim username As String
    username = User.Identity.Name

    The code above obtains the User IPrincipal object for the current request by accessing it via the static HttpContext.Current property that ASP.NET provides (this in turn uses call-context to retrieve it from the active ASP.NET worker thread).  This avoids you having to pass this User object into your business classes directly, and instead allows you to access the User object from anywhere in the application.
     
    Outputting the Logged-in Username on a Page

    You can use the username string we retrieved above to programmatically output the username to a page however you want.  For example, you could easily add an <asp:label> control to the page and write code like so to set it:

    Label1.Text = "Welcome " & User.Identity.Name

    ASP.NET 2.0 also ships with a built-in <asp:LoginName> control that you can use to declaratively output the user-name to the page:

    <asp:LoginName ID="LoginName1" FormatString="Welcome {0}!" runat="server" />

    This control provides an easy way to display the username within the application without having to write any code at all (note the use of the “FormatString” property on the control above – which allows you to easily specify a text mask to use with it).

    Looking up Role/Group information for a User

    ASP.NET provides a useful “Role Management” capability, which allows developers to map users into logical “Roles” that can then be used to better control end-user capabilities and authorization access.  For example, as a developer I could create a role called “managers” for my web application, and then limit access to portions of the site to only those users within the “managers” role (note: I will be posting additional recipes in the future that discuss how to fully use the Role Management authorization and capabilities features more).

    When using Windows Authentication, ASP.NET allows developers to create and populate roles from multiple sources.  For example, a developer could setup the built-in ASP.NET 2.0 SqlRoleProvider to map Windows users to custom application roles that are store within a database.  This approach is very useful for scenarios where there might be application-specific role mappings that don’t make sense to push into a centralized Active Directory tree/store.

    ASP.NET also makes it easy to access central Windows and Active Directory group mappings from within an application as well.  For example, if there is a Windows group on the Active Directory network called “DOMAIN\managers”, an ASP.NET application could lookup whether the current Windows authenticated user visiting the ASP.NET site belongs to this group by writing code like this:

    If User.IsInRole("DOMAIN\managers") Then
         Label1.Text = User.Identity.Name & " is a manager"
    Else
         Label1.Text = User.Identity.Name & " is not a manager"
    End If

    Note that the role/group look-up is done via the “User.IsInRole(rolename)” method that is a peer of the User.Identity.Name property. 

    Next Steps

    Once you understand the basics above, you know how to authenticate and identify Windows users visiting your Intranet application, as well as to lookup what Windows groups and roles they belong to.

    In a future Recipe we’ll walkthrough more advanced role-management scenarios, and also discuss ways to authorize and restrict access and capabilities within an ASP.NET application based on the authenticated user’s authorization rights.

    Additional Discussion:

    • Links to Tons of ASP.NET Security Content
    • How To: Use Windows Authentication in ASP.NET 2.0

    Hope this helps,

    Scott

     

    Share this post: Email it! | bookmark it! | digg it! | reddit!
  • Lightning Visio: Step 3

    Informative Diagrams for the Artistically Challenged

    Step 1 gave us raw material to mold. Step 2 molded material into a readable diagram. The final step, step 3, is going to add some aesthetic touches. What? I thought this was a pragmatic process! Yes, that’s true. But we can always take 2 minutes to add finishing touches. We want to make the diagram easier to read, and we can use some additional formatting to draw attention to significant concepts in the drawing.

    Here are three possible responses a developer might give when looking at our diagram:

    A: Ahhhhh, I understand, now.
    B: This is the most beautifully detailed diagram I’ve ever seen.
    C: Who let their 3 year run amok with the plotter?

    Our goal is to elicit response A.

    The first thing I’ll do is generally add some thickness to the connector and shape lines. The spindly, thin lines that come by default are difficult to see and look weak. Choose varying line thickness to accent portions of the diagram. A line with a 9-point weight is a solid boundary - the kind of boundary you might want around a secure process. Right-click a shape and select Format –> Line to set the line properties. CTRL-click multiple shapes to set their properties all at once. This is also a good time to make the arrowheads on directional connectors stand out by adding thickness.

    Finally, add a splash by filling your geometrical shapes with some color. Nothing too fancy, but white filled boxes on white paper don't stand out and can be hard to read. Right-click shapes, then select Format –> Fill. This is also a good time to add a title.

    Voila! In less than 10 minutes we’ve created a diagram worth at least a few hundred words. We can hang it on walls, and include it in the architecture documentation. In this case, what we’ve built is actually more political commentary than software documentation, but the process worked just as well.

    visio step 3

  • An Interview with Patrick Chu from ItsYourTurn.com

    ItsYourTurn.com is a play-by-play game website that I was turned onto several years ago by a colleague. Since I joined the free site in October 4th, 2002, I've played 2,286 games (although I'm sure you'll be delighted to know I've won 58.7% of the games I've played).

    ItsYourTurn.com (IYT) runs on the Microsoft web stack - ASP.NET 2.0, SQL Server 2005, IIS 6.0 - and is run, full time, by Patrick Chu, two other developers, and a part time support staff. IYT has over 2.5 million registered accounts, a database with over 470 million active records, and records around four million page views per day.

    Recently I interviewed Patrick, asking an array of technological and business-related questions. Patrick provided very in-depth and thought out answers, including information on IYT's hardware and hosting configuration, the motivation and rationale behind starting this business, his thoughts on AJAX, life during the dot com bubble, and his views on the future of web development.

    You can read the interview on 4Guys, at A Conversation with Patrick Chu.

    Enjoy!

  • Tip/Trick: Fast HTML Editor Navigation within VS 2005

     

    Problem

     

    You have a large ASP.NET page that you are working on within Visual Studio, and you want to quickly navigate back and forth between design-view and source-view without getting lost in the deeply nested HTML content, or have to spend a lot of time finding your place again in the document.

     

    Solution

     

    Visual Web Developer and Visual Studio 2005 provide a number of subtle, but useful, features that you can take advantage of to navigate quickly around an HTML page.  To see them in action, open a page with a lot of HTML content (in the examples below I’m going to use the Default.aspx page from the built-in “Personal Starter Kit” sample). 

     

    Switch the page into design-view and either select some content, or simply move the cursor to a location within the page where you want to examine the HTML.  For example, in the screen-shot below notice that I’ve selected the “ipsum” text within the second <li> of my <ul> list:

     

     

    Now click the “source” tab within Visual Studio and notice the text selection and cursor within source view:

     

     

    As you can see above, VS has automatically highlighted and scrolled to the HTML that corresponds to the selected content within design-view, and positioned the cursor in the exact same region.  You can now type or start to cursor around within the editor without having to scan up and down the document to find the specific place you wanted to work on.

     

    You can use the same trick when moving from source->design-view.  In fact, if you position your cursor in HTML source-view on an ASP.NET Server Control element, and then switch into design-view, the control will be selected within the WYSIWYG designer and the property grid presented for that control.  For example, notice how the cursor is on the <asp:formview> control below:

     

     

    When we flip back into design-view it will be automatically selected within the designer and the formview will show up in the property grid:

     

     

    One last helpful navigation feature to make sure to take advantage of is the “tag navigator” control that shows up at the bottom of the HTML editor in both design-view and source-view:

     

     

    This lists the element hierarchy from the current location of the cursor up to the root <html> element in the document.  You can use this navigator to quickly see how the current element or cursor position is nested within the page and what CSS rules apply to it.  For example, in the picture above the cursor is within a <h4> element, which is within a <div> which has an id value of “content” (this is indicated by the “#” character above), which is within a <div> which has an id of “home” and a css class rule called “page” (which is indicated by the “.” character above), etc. 

     

    In addition to displaying the hierarchy of parent elements, you can also use the tag navigator to quickly navigate/select any of the parent elements.  Just click on the parent element name within the navigator and it will select it.  Right-click on an element and get even more control – allowing you to select everything (including the element itself), or just its inner contents: 

     

     

    This works in both source and design-view.

     

    Additional Reading

    Hope this helps,

     

    Scott

     

    Share this post: Email it! | bookmark it! | digg it! | reddit!
  • Lightning Visio: Step 2

    Fast Diagrams for the Artistically Challenged

    Step 1 produced the raw materials we need. Step 2 is molding the raw materials into a comprehensible diagram. There is a fine line between making a diagram comprehensible and adding little touches for the sake of aesthetics. As time ticks on, remember the ultimate objective is to communicate ideas to a team of software developers, not sell the diagram at an art exhibition. We need something more permanent than a whiteboard sketch, but that only requires a minimum amount of time.

    My first action is adjusting the font sizes in the diagram. The default size is too small to read easily, so I select all the objects in the diagram and crank up the font size (CTRL+A, right-click the diagram, Format -> Text).

    Visio connector tool

    Next, I’ll add connecting lines and arrows. I’m a fan of the “Dynamic Connector” for straight lines between shapes, and “Wavy Connector 1” for a less formal directional line. Connectors should always glue to a connection point because moving shapes around will be easier (the connectors will move with the shape). Many shapes already have connection points at logical locations (the small blue x symbol), but you can add or move connection points, too. Click the Connection Point Tool on the standard tool bar, select a shape, then hold down the CTRL key while clicking the location to add a connection point.

    Finally, I’ll start moving shapes around to achieve alignment and symmetry. Nothing too fancy at this point, just make sure the spacing is consistent and that nothing is so unbalanced as to attract attention. Some tools that can help at this point include:

    • The Align Shapes dialog
    • The Snap and Glue toolbar
    • The keyboard arrow keys

    The align shapes dialog (Shape –> Align Shapes) can quickly align shapes along their centers, tops, bottoms, left sides, or right sides. CTRL + click shapes to select multiple shapes for aligning.

    snap toolbar

    I use the Snap and Glue toolbar to toggle the snap feature (the first button in the toolbar). Snapping is a quick and easy way to get shapes spaced perfectly. I turn off the snap feature when I have some text I need to sit in the diagram at a precise location.

    I find it easier to use the arrow keys instead of the mouse to move shapes. I get a precise amount of movement from a keystroke. Select a shape and use the arrow keys to make coarse movements. Hold down a Shift key when using the arrow keys for fine-grained movements.

    Finally, too much white space can make a diagram hard to comprehend. Step 2 can be an iterative process of moving, shaping, aligning, and compacting. The diagram should become smaller and more symmetrical. Here is our diagram after step 2.

    visio step 2

    Tune in tomorrow evening as we apply the final changes in step 3.

  • Lightning Visio: Step 1

    Effective Diagrams for the Artistically Challenged

    Over the years, I’ve had to whip up quite a few Visio diagrams. I used to spend a long time fiddling with different shapes and formatting, but not getting anything done. These days I have a three-step process that helps me crank out diagrams to communicate ideas. The diagrams won’t be the type you’ll include in product literature, nor will they win awards for innovation, but they are perfect to hang on the wall for a few weeks while a team is turning ideas into working software.

    Step 1: A Shape for Every Entity

    By the time I’ve reached Step 1, I have an idea of what I want to communicate in the drawing. For instance, I’ll know I want to show how account data comes into Service Foo (which is hosted in Process Bar) and runs through a series of pipes and filters.

    I’ll create a blank drawing and open only the “Blocks” and “Connectors” shapes. In the File -> Shapes menu, these shapes are under “Block Diagrams” and “Visio Extras”. The other 3 bazillion shapes in Visio can be distracting, and keeping just boxes, circles, and arrows on hand helps me to focus.

    The goal of Step 1 is to drag a shape into the drawing for each thing in the idea I need to communicate. I’ll add text to the shapes, but I don’t worry about connectors, arrows, colors, formatting, or precise positioning. That’s all fluff that comes later. By sticking to the basics, I’ll only spend 5 minutes dragging and dropping instead of 25 minutes debating the various aesthetics of the “Reference Callout 1” shape versus the “Reference Callout 2” shape.

    This diagram I’m working on has four boxes and a dump truck. Yes, I broke my own rules by adding clip art. The art only took an extra 10 seconds thanks to the clip art “search for” feature, and I’ll justify it later. I now have a diagram with all the “things” I need to manipulate.

    Visio Step 1

    Tomorrow evening we will take the diagram through step 2.

  • August's Toolbox Column in MSDN Magazine

    My eighth Toolbox column in the August 2006 issue of MSDN Magazine is now avaiable online. The August issue examines three products:

    • Red-Gate Software's SQL Data Compare (version 5) - allows the data within two schema-identical databases to be compared and synchronized; very useful if you have a test and production database whose underlying data you want to sync (for example, pulling back the live data back to the test database for some 'real world' testing)
    • Error Logging Modules and Handlers (ELMAH) - a free, open-source collection of HTTP Modules and Handlers created by Atif Aziz for automatically logging unhandled exceptions and providing UIs for displaying the error log. ELMAH is the first thing I add to all of my new ASP.NET projects... [See this blog entry for more information...]
    • Sky Software's Shell MegaPack (version 7.1) - Shell MegaPack includes a series of ActiveX and .NET controls for providing the native Windows Explorer shell experience in a WinForms application.

    Due to space limitations, this issue of the Toolbox column does not include a book review; it's been pushed to the September 2006 issue (sorry, I am just too verbose).

    As always, if you have any suggestions for products or books to review for the Toolbox column, please send them into toolsmm@microsoft.com

    You can keep abreast of the latest Toolbox articles through the column's RSS feed or the Toolbox column category here on my blog.

  • .NET Performance

    Q: I need my application to perform better. Do you know any good resources on .NET performance?

    A: I know one great resource. The resource is the "Improving .NET Application Performance and Scalability" book from Microsoft's Patterns and Practices group (or whatever their name is this quarter). You can read the book online, download the PDF, or buy the 1152 page paperback.

    The book includes chapters dedicated to manage code performance, ASP.NET performance, and ADO.NET performance, among others. There guide also include How To articles and checklists you can use for reviews. It's an oldie but a goodie.

  • Giving a CAPTCHA a Whirl

    Comment spam is evil. I've been getting on the tune of 25-50 comment spams per day the past several weeks. My custom utility to quickly delete comments in .Text has helped delete comment spams after the fact; additionally, SQL triggers have, to date, proactively nuked over 20,700 comment spams (although they have also stopped valid posters who have added common spam 'keywords' to their posts).

    Since the SQL triggers are clearly no longer working, I'm going to give CAPTCHAs a try. In theory, CAPTCHAs can be broken... easily. However, I'm hoping/assuming that the vast majority of scum known as comment spammers aren't using programs that can decode CAPTCHAs and aren't using the social engineering/free ***!! techniques detailed here. Rather, I'm assuming a scant few of the comment spams (the ones I get like one or two of a day) are entered by actual humans; the majority, of which I get a blast of, say, 30 in a five second period, are probably coming from a pretty dumb HTTP screen scraping/HTTP posting program. If my assumptions are sound, then the CAPTCHA ought to drastically reduce the amount of comment spam appearing on my blog.

    I've taken down my comment spam-related triggers and replaced them with Miguel Jimenez's free Clearscreen SharpHIP CAPTCHA Control. The nice thing about this control is that it automatically checks for validity on postback so it integrates with .Text without having to modify the codebase. One downside, however, is that any other postback sections on the web page will no longer work unless the CAPTCHA is filled out (you may have noticed the blog entry rating feature has been removed).

    Hopefully the CAPTCHA cuts down on the comment spam, as having to wade through and delete 50+ comments every day or two is really started to get mundane and annoying. (I do take removing comment spam seriously, though. I challenge you to find a single piece of irrefutable spam in one of my blog entries that's older than, say, a week.)

  • Build Failed With No Errors

    MSBuild does a good job of reporting build errors, but MSBuild can only report errors that the underlying Tasks report. Custom tasks add a lot of variation to quality of the error messages. Case in point is the following message, which popped up as a deadline loomed.

    Build FAILED.
        0 Warning(s)
        0 Error(s)
    
    Time Elapsed 00:00:05.85
    

    The build failed, but there are no errors to report. Yup. It's strange messages like this that make me want to curse in German, but I don't know German, so I make the noises an angry Klingon might make after living in Berlin for 5 years.

    I couldn't find any problems in the output until I set MSBuild for maximum verbosity (/verbosity:diagnostic, /v:diag for short), at which point I found this in the output:

    	
    Done building target "PrepareRdlFiles" in project "...".
    Target "RunRdlCompiler" in file "...":
      Building target "RunRdlCompiler" completely.
      Output file "obj\Debug\RdlCompile.compiled" does not exist.
      Using "RdlCompile" task from assembly "Microsoft.ReportViewer.Common ...".
      Task "RdlCompile"
      Done executing task "RdlCompile" -- FAILED.
    Done building target "RunRdlCompiler" in project "CareAlertsWeb.csproj" -- FAILED.
    

    Someone had added .rdlc files to the project. These are "Client Report Definition" files - think of Reporting Services reports without a report server. Something was going wrong compiling the .rdlc files, but there still wasn't any information to determine what the problem was. Without knowing what else to do I started looking at the RdlCompile task with Reflector.

    The RdlCompile task is interesting. The task doesn't compile files in the traditional sense (transform inputs into outputs). The task validates the report definition inside the .rdlc file. This step ensures we'll get compile time errors instead of runtime errors from the ReportViewer control if the report definition is invalid.

    The assembly hosting RdlCompile referenced another assembly that was not on the build machine (Microsoft.ReportViewer.ProcessingObjectModel). Mysterious. Why this caused the task to fail without reporting a more specific error is also a mystery.

    With all the assemblies were in place, the RdlCompile task finished with success. Running ReportViewer.exe installs all the required assemblies, you can find it in %Program Files%\Microsoft Visual Studio 8\SDK\v2.0\BootStrapper\Packages\ReportViewer.

  • My Blog's Three Year Anniversary

    Holy cripes, over the weekend my blog turned three years old! This whole mess started back on July 2nd, 2003, when I posted the following immortal words:

    Ok, so I decided to jump onto the "blog bandwagon" and create my own blog.  I am such a tool.

    I feel so old. It really is amazing how fast time seems to pass by.....

    Anywho, some exciting news - I've got a cool interview with Patrick Chu, found of ItsYourTurn.com, that I'll be posting here sometime in the next week or so. ItsYourTurn.com is a turn-by-turn game site that I've lost untold hours at over the years playing (primarily) chess and Stack4x4. ItsYourTurn.com is powered by the “Microsoft stack” (custom ISAPI, ASP.NET 2.0, SQL Server, etc.) and has a fair share of load - ~700,000 game moves every day and a database with over 470 million records. The interview has some great technical tidbits and advice along with a view from the inside of a small company (two full-time programmers and a part-time support staff member).

This Blog

Syndication

Powered by Community Server, by Telligent Systems
'