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.

September 2006 - Posts

  • Tip/Trick: Guard Against SQL Injection Attacks

    SQL Injection attacks are really nasty security vulnerabilities, and something all web developers (regardless of platform, technology or data layer) need to make sure they understand and protect themselves against.  Unfortunately developers too often neglect putting focused time on this - and leave their applications (and worse their customers) extremely vulnerable.

    Michael Sutton recently published a very sobering post about just how widespread this issue is on the public web.  He built a C# client application that uses the Google Search API to look for sites vulnerable to SQL Injection Attacks.  The steps to achieve this were simple:

    1. Look for sites that have querystring values (example: search for URLs with "id=" in the URL)
    2. Send a request to the sites identified as dynamic with an altered id= statement that adds an extra quote to attempt to cancel the SQL statement (example: id=6')
    3. Parse the response sent back to look for words like "SQL" and "query" - which typically indicate that the app is often sending back detailed error messages (also bad)
    4. Review whether the error message indicates that the parameter sent to SQL wasn't encoded correctly (in which case the site is open to SQL Injection Attacks)

    Of a random sampling of 1000 sites he found via his Google search, he detected possible SQL Injection Attack vulnerability with 11.3% of them.  That is really, really scary.  It means hackers can remotely exploit the data in those applications, retrieve any unhashed/encrypted passwords or credit-card data, and potentially even log themselves in as administrators to the application.  This is bad not only for the developer who built the application, but even worse for any consumer/user of the application who has provided data to the site thinking it will be secure.

    So what the heck is a SQL Injection Attack?

    There are a couple of scenarios that make SQL Injection attacks possible.  The most common cause are cases where you are dynamically constructing SQL statements without using correctly encoded parameters.  For example, consider this SQL query code that searches for Authors based on a social security number provided via a querystring:

    Dim SSN as String
    Dim 
    SqlQuery as String

    SSN Request.QueryString("SSN")
    SqlQuery 
    "SELECT au_lname, au_fname FROM authors WHERE au_id = '" + SSN + "'"

    If you have SQL code like the snippet above, then your entire database and application can be hacked remotely.  How?  Well in the normal scenario users will hit the site using a social security number which will be executed like so:

    ' URL to the page containing the above code
    http://mysite.com/listauthordetails.aspx?SSN=172-32-9999

    ' SQL Query executed against the database 
    SELECT au_lname, au_fname FROM authors WHERE au_id '172-32-9999'

    This does what the developer expected, and searches the database for author information filtered by the social security number.  But because the parameter value hasn't been SQL encoded, a hacker could just as easily modify the querystring value to embed additional SQL statements after the value to execute.  For example:

    ' URL to the page containing the above code
    http://mysite.com/listauthordetails.aspx?SSN=172-32-9999';DROP DATABASE pubs --

    ' SQL Query executed against the database 
    SELECT au_lname, au_fname FROM authors WHERE au_id = '';DROP DATABASE pubs --

    Notice how I was able to add the ';DROP DATABASE pubs -- clause to the SSN querystring value and use it to terminate the current SQL statement (via the ";" character), and then add my own malicious SQL statement to the string, and then comment out the rest of the statement (via the "--" characters).  Because we are just manually concatenating the SQL statement in our code, we will end up passing this to the database - which will execute first the query against the authors table, and then delete our pubs database table.  Bang - it is now gone.

    In case you think the idea of anonymous hackers deleting your database tables is bad, that is unfortunately actually one of the better scenarios when a SQL Injection Attack is involved.  Rather than just destroy data, a hacker could instead use the above code vulnerability to perform a JOIN that retrieves all of the data within your database and displays it on the page (allowing them to retrieve username/passwords/credit-cards).  They could also add UPDATE/INSERT statements to modify product prices, add new admin users, and really screw up your life (imagine auditing your inventory at the end of the month, only to discover that the actual number of products in your warehouse is different then what your accounting system reports...). 

    How do you protect yourself?

    SQL Injection Attacks are something you need to worry about regardless of the web programming technology you are using (all web frameworks need to worry about it).  A couple of very basic rules you must always follow:

    1) Don't construct dynamic SQL Statements without using a type-safe parameter encoding mechanism.  Most data APIs (including ADO + ADO.NET) have support for allowing you to specify the exact type of a parameter being provided (for example: string, integer, date) and can ensure that they are escaped/encoded for you to avoid hackers trying to exploit it.  Always use these features

    For example, with dynamic SQL using ADO.NET you could re-write the code above like below to make it safe:

    Dim SSN as String Request.QueryString("SSN")

    Dim cmd As 
    new SqlCommand("SELECT au_lname, au_fname FROM authors WHERE au_id = @au_id")
    Dim param 
    = new SqlParameter("au_id", SqlDbType.VarChar)
    param.Value 
    SSN
    cmd.Parameters.Add(param)

    This will prevent someone from trying to sneak in additional SQL expressions (since ADO.NET above knows to string encode the au_id value), and avoid other data problems (incorrectly type-casting values, etc).  Note that the TableAdapter/DataSet designer built-into VS 2005 uses this mechanism automatically, as do the ASP.NET 2.0 data source controls. 

    One common misperception is that if you are using SPROCs or a ORM you are completely safe from SQL Injection Attacks.  This isn't true - you still need to make sure you are careful when you pass values to a SPROC, and/or when you escape or customize a query with an ORM that you do it in a safe way.

    2) Always conduct a security review of your application before ever put it in production, and establish a formal security process to review all code anytime you make updates.  This later point is super important.  Too often I hear of teams that conduct a really detailed security review before going live, then have some "really minor" update they make to the site weeks/months later where they skip doing a security review ("it is just a tiny update - we'll code review it later").  Always do a security review.

    3) Never store sensitive data in clear-text within a database.  My personal opinion is that passwords should always be one-way hashed (I don't even like to store them encrypted).  The ASP.NET 2.0 Membership API does this for you automatically by default (and also implements secure SALT randomization behavior).  If you decide to build your own membership database store, I'd recommend checking out the source code for our own Membership provider implementation that we published here.  Also make sure to encrypt credit-card and other private data in your database.  This way even if your database was compromised, at least your customer private data can't be exploited.

    4) Ensure you write automation unit tests that specifically verify your data access layer and application against SQL Injection attacks.  This is really important to help catch the "it is just a tiny update so I'll be safe" scenario, and provide an additional safety layer to avoid accidentally introducing a bad security bug into your application.

    5) Lock down your database to only grant the web application accessing it the minimal set of permissions that it needs to function.  If the web application doesn't need access to certain tables, then make sure it doesn't have permissions to them.  If it is only read-only generating reports from your account payables table then make sure you disable insert/update/delete access. 

    How to Learn More

    The Microsoft Prescriptive Architecture Guidance (PAG) team has posted a number of really good security guideline documents that you should set aside some time to read:

    And these additional PAG How-To articles are useful for learning more about how to protect yourself against injection attacks:

    You can also find useful ASP.NET security information from this security blog post of mine, and from my ASP.NET Tips/Tricks page here.

    Hope this helps,

    Scott

    Share this post: Email it! | bookmark it! | digg it! | reddit!
  • ComponentArt Releases Web.UI for ASP.NET AJAX

    ComponentArt today announced a commercial version of their Web.UI controls that integrate with the ASP.NET AJAX Extensions (aka "Atlas"). 

    Click here to view some of their online demos (which are pretty impressive).  You can also download a beta edition of the controls from their site, as well as check out the client-side API reference they've added (using the ASP.NET AJAX Library) for the controls they built.

    One of the things I'm really looking forward to seeing are all of the great controls that are going to be built (both commercial and open source) using ASP.NET AJAX as it approaches the fully-support 1.0 release version.  Seeing really cool controls like the ones ComponentArt are doing is just great, and are going to enable developers to build really responsive UI's in a short amount of time.

    Hope this helps,

    Scott

    Share this post: Email it! | bookmark it! | digg it! | reddit!
  • Custom Build Numbers in Team Build

    The Team Build service in Team Foundation Server includes the current date in the build number by default. To me, the string looks like the random gibberish of a disk head crash.

    FooBarBuild_20060928.1
    FooBarBuild_20060928.2

    I know some people are fond of including the date in a build label, but it's a turn off for me. Build labels have a tendency to show up in many places, and a friendly number is easier on the eyes.

    FooBar_2.5.1
    FooBar_2.5.2

    FooBar_2.5.176

    Fortunately, it's easier to change Team Build with a custom MSBuild task. There are some examples of how to do this out there, but none that generate a truly friendly name. Ideally, the task will start with a base name like "FooBar_2.5" and just generate an extra identity digit. One of the properties in play during a team build is LastBuildNumber, which we can inspect during the task and use to generate the build number we want. The code would look something like this:

    using System;
    using Microsoft.Build.Utilities;
    using Microsoft.Build.Framework;

    namespace TfsBuildUtilities
    {
      
    public class GetBuildNumber : Task
       {
          
    public override bool Execute()
          {
            
    bool result = true;

            
    try
             {
                ValidateProperties();

                
    string buildNumber = GetLastBuildNumber();
                _buildNumber = BaseBuildName +
    "." + buildNumber;
             }
            
    catch (Exception e)
             {
                result =
    false;

                BuildErrorEventArgs eventArgs;
                eventArgs =
    new BuildErrorEventArgs
                    (
                        
    "",
                        
    "",
                        BuildEngine.ProjectFileOfTaskNode,
                        BuildEngine.LineNumberOfTaskNode,
                        BuildEngine.ColumnNumberOfTaskNode,
                        0, 0,
                        
    "GetBuildNumber failed: " + e.Message,
                        
    "", ""
                    );

                BuildEngine.LogErrorEvent(eventArgs);

                
    throw;
             }

            
    return result;
          }

          
    private string GetLastBuildNumber()
          {
            
    string buildNumber = null;

            
    // if there is no last build, or it looks as if the
             // last build was not using our name,
             // we will reset to ".1";
             if (String.IsNullOrEmpty(LastBuildNumber) ||
                !LastBuildNumber.StartsWith(BaseBuildName))
             {
                buildNumber =
    "1";
             }
            
    // otherwise we need to parse out the last number and increment it
             else
             {
                
    string[] parts = LastBuildNumber.Split('.');
                
    int number = 1;
                
    bool parseResult = Int32.TryParse(
                      parts[parts.Length - 1],
                      
    out number
                   );
                
                
    if (parseResult)
                {
                   number++;
                   buildNumber = number.ToString();
                }
             }

            
    if (String.IsNullOrEmpty(buildNumber))
             {
                
    throw new InvalidOperationException(
                      
    "Could not generate a valid build number"
                   );
             }

            
    return buildNumber;
          }

          
    private void ValidateProperties()
          {
            
    if (String.IsNullOrEmpty(BaseBuildName))
             {
                
    throw new ArgumentException("BaseBuildName is null");
             }
          }

          [Output]
          
    public string BuildNumber
          {
            
    get { return _buildNumber; }
            
    set { _buildNumber = value; }
          }
          
    private string _buildNumber = String.Empty;

          [Required]
          
    public string BaseBuildName
          {
            
    get { return _baseBuildName; }
            
    set { _baseBuildName = value; }
          }
          
    private string _baseBuildName;

          
    public string LastBuildNumber
          {
            
    get { return _lastBuildNumber; }
            
    set { _lastBuildNumber = value; }
          }
          
    private string _lastBuildNumber;
       }
    }

    Then, register the task in TFSBuild.proj file. I like to deploy the assembly into the MSBuild extensions path to use from multiple projects.

    <UsingTask
     TaskName="TfsBuildUtilities.GetBuildNumber"  
     AssemblyFile=
    "$(MSBuildExtensionsPath)\MyDir\TfsBuildUtilities.dll"/>

    Finally, in the same .proj file, override the build number target to spit a new build label into the system.

    <Target Name = "BuildNumberOverrideTarget" >    
      <GetBuildNumber BaseBuildName=
    "FooBar_2.5"
                      LastBuildNumber=
    "$(LastBuildNumber)">
        <Output TaskParameter=
    "BuildNumber"
                 PropertyName=
    "BuildNumber"/>      
      </GetBuildNumber>
    </Target>

    TFS is making the CM job easy…

  • Tip/Trick: Patterns and Practices Guidance Explorer for .NET and ASP.NET

    I blogged about the cool new .NET and ASP.NET Guidance Explorer that the Microsoft Patterns and Practices Team has been working on back in June. 

    Since then the team has been hard at work and recently moved the project to be hosted on CodePlex.  You can visit and join the project here.  All source code for the Guidance Explorer UI (which is of course built using .NET and Windows Forms) can also now be downloaded for free from the CodePlex project site.

    The Guidance Explorer provides a database of recommendations and best practices for ASP.NET, ADO.NET, and the .NET Framework that you can easily filter and search.  Particularly useful are some of the checklists you can easily follow for performance and security best practices prior to deployment.

    You can create custom views of the library of just those recommendations you care about.  What is cool is that you can now also easily publish these custom views to your friends or other members of your team:

    You will also be able to subscribe to feeds of guidance either on a local share or on the web:

    Best of all, you can also now create your own recommendations and add them into the library (and share them with others). 

    Download the project (and optionally the full source code) from its CodePlex Project and start using it today!

    Hope this helps,

    Scott

    Share this post: Email it! | bookmark it! | digg it! | reddit!
  • Vista will NOT support Developers

    So first most of the meat was taken out of Vista, and the best of what remains (the poorly named .NET v3.0) runs on XP.  Now we find out that we can't use Vista for development, since VS 2003 (or 2002) won't be supported.  For that matter, even VS 2005 will require SP1 which is just now in beta, and even that we are told will have issues after its official release.  So (1) who actually wants, let alone needs, Vista, and (2) why does MS just keep screwing up and pushing out this stuff before its ready?  Don't get me wrong, as I like VS 2005 very much, but its no secret that MS made some bad decisions that still impacts a lot of people.  But even for those of us that do like VS 2005, most of us still have to continue to support VS 2003 also for some time.  And its not like this is the only thing that seems to not be ready with Vista, but this will pretty much guarantee developers won't move to Vista in large quantities.  So either MS should delay Vista until its really ready and useful for more than generating income, or we developers need to tell everyone to ignore Vista since its clearly not ready.  

    Share this post: Email it! | bookmark it! | digg it! | reddit!
  • Removing Features Considered Harmful

    I get the occasional earful from people who are upset with Microsoft. These rants might come electronically, or they might come in person. If I know anything about the particular problem the person is having, I might try to give them some perspective or background on why Microsoft made the software do whatever it is that is causing the person great pain and suffering. I might know a workaround, or I might not. I might make them happier, or I might not. I do try. C'est la vie.

    Today, I am on the other side of the fence.

    I updated ActiveSync from 3.something to 4.2 today, only to find they removed the ability to synch a device over the network.

    Let me express my feelings about this decision by saying - it sucks. It sucks really large, rotten, ostrich eggs.

  • Check out Ruby on Rails

    Stephen Chu has a great article on why .NET developers should check out rails. [via Scott Hanselman]

    -James

  • WOXY is alive to play another day?

    Just a couple days ago it looked like WOXY was actually going off the air for good, but now it has been confirmed that they have once again risen from the ashes.

    If you haven’t listened before stay tuned and check it out. (it’s not on the air yet, but should be soon).

    -James

  • Visual Studio 2005 Service Pack 1 Beta

    Somasegar announced the available of the first beta for the upcoming service pack for Visual Studio 2005. I am extremely glad to see this coming, and I am tempted to go ahead and install the beta. I might throw it on a second machine to see how stable it is first though.

    -James

     

     

  • What's Wrong With This Code (#6)

    Joe Developer is working on a new application with for a book publisher. Authors can publish zero or more books. Books can have zero or more authors.

    Book and Author schema

    Joe wrote a query to get a total count of all authors, and a total count of all books. Joe read on the Internet that the DISTINCT keyword is good to use in these scenarios.

    SELECT DISTINCT
      COUNT(Authors.Id) AS TotalAuthors,
      COUNT(Books.Id) As TotalBooks
    FROM
      Authors  
      FULL JOIN AuthorsBooks AB ON Authors.Id = AB.AuthorID
      FULL JOIN Books ON AB.BookID = Books.Id

    The problem is - the numbers seem too high. What's wrong? Is it easy to fix?

  • My Unit Testing Idea : Facilitating Multiple Assertions

    Numerous TDD experts have made the suggestion that there should only be one assertion per test:

    The theory goes that each test should only test one thing, and that should be the name of the test.

    I don’t do a very good job of following that rule. If I wanted to test a method that returned books for an author I would write tests like so:

        1 [Test]

        2 public void GetBooksForAuthorSuccessfull()

        3 {

        4     List<Book> books = AuthorDA.GetBooks(1);

        5     Assert.IsNotNull(books, "Null value returned for books");

        6     Assert.IsTrue(books.Count > 0, "No books returned");

        7     Assert.AreEqual(books.Count, 3, "Incorrect number of books returned");

        8     Assert.AreEqual(books[1].ID, 1, "First book returned is incorrect");

        9     Assert.AreEqual(books[2].ID, 2, "Second book returned is incorrect");

       10     Assert.AreEqual(books[3].ID, 3, "Third book returned is incorrect");

       11 }

       12 

       13 [Test]

       14 public void GetBooksForAuthorNoBooksReturned()

       15 {

       16     List<Book> books = AuthorDA.GetBooks(122);

       17     Assert.IsNotNull(books, "Null value returned for books");

       18     Assert.AreEqual(books.Count, 0, "Books are returned when they shouldn't be");

       19 }

       20 

       21 [Test]

       22 [ExpectedException(typeof(ArgumentException))]

       23 public void GetBooksForAuthorBadAuthorID()

       24 {

       25     AuthorDA.GetBooks(-1);

       26 }

     

    I have three different tests that each test different things, but two of them contain more than one assertion and one of them contains seven assertions. If I wanted to write these tests using the one assertion per test guideline I would have this:

        1 [Test]

        2 public void GetBooksForAuthorSuccessfullNotNull()

        3 {

        4     List<Book> books = AuthorDA.GetBooks(1);

        5     Assert.IsNotNull(books, "Null value returned for books");

        6 }

        7 

        8 [Test]

        9 public void GetBooksForAuthorSuccessfullCountGreaterThanZero()

       10 {

       11     List<Book> books = AuthorDA.GetBooks(1);

       12     Assert.IsTrue(books.Count > 0, "No books returned");

       13 }

       14 

       15 [Test]

       16 public void GetBooksForAuthorSuccessfullCountEqualsThree()

       17 {

       18     List<Book> books = AuthorDA.GetBooks(1);

       19     Assert.AreEqual(books.Count, 3, "Incorrect number of books returned");

       20 }

       21 

       22 [Test]

       23 public void GetBooksForAuthorSuccessfullFirstBookReturnedCorrect()

       24 {

       25     List<Book> books = AuthorDA.GetBooks(1);

       26     Assert.AreEqual(books[1].ID, 1, "First book returned is incorrect");

       27 }

       28 

       29 [Test]

       30 public void GetBooksForAuthorSuccessfullSecondBookReturnedCorrect()

       31 {

       32     List<Book> books = AuthorDA.GetBooks(1);

       33     Assert.AreEqual(books[2].ID, 2, "Second book returned is incorrect");

       34 }

       35 

       36 [Test]

       37 public void GetBooksForAuthorSuccessfullThirdBookReturnedCorrect()

       38 {

       39     List<Book> books = AuthorDA.GetBooks(1);

       40     Assert.AreEqual(books[3].ID, 3, "Third book returned is incorrect");

       41 }

       42 

       43 [Test]

       44 public void GetBooksForAuthorNoBooksReturnedNotNull()

       45 {

       46     List<Book> books = AuthorDA.GetBooks(122);

       47     Assert.AreEqual(books.Count, 0, "Books are returned when they shouldn't be");

       48 }

       49 

       50 [Test]

       51 public void GetBooksForAuthorNoBooksReturnedCountGreaterThan0()

       52 {

       53     List<Book> books = AuthorDA.GetBooks(122);           

       54     Assert.AreEqual(books.Count, 0, "Books are returned when they shouldn't be");

       55 }

       56 

       57 [Test]

       58 [ExpectedException(typeof(ArgumentException))]

       59 public void GetBooksForAuthorBadAuthorID()

       60 {

       61     AuthorDA.GetBooks(-1);

       62 }

    I have a couple problems with this change:

    • I think it’s actually harder to read since the assertions are scattered around in separate methods.
    • It would increase the number of tests. On my current project we have 1800 tests, if we followed the one assertion rule we would have over 6,000 I am sure.
    • If my method breaks and starts returning null then I have 8 tests failing instead of just 2, this means I have to know the dependency tree of my tests to find the real issue.
    • Any code I have to write to setup the data for my test has to be duplicated 8 times. (if I move that setup data to the setup method than I am effectively limiting my fixtures to one fixture per test)
    • I now have over double the amount of code. I am constantly trying to reduce the amount of code in my project, whether test or production, and anything that doubles it better add a ton of value.

    The main drawback to having multiple asserts in a test is that all of the unit testing frameworks I have used fail the test on the first assert that fails. This means that if my first test fails on the third assert (line 82), the remaining assertions are never run:

       76 [Test]

       77 public void GetBooksForAuthorSuccessfull()

       78 {

       79     List<Book> books = AuthorDA.GetBooks(1);

       80     Assert.IsNotNull(books, "Null value returned for books");

       81     Assert.IsTrue(books.Count > 0, "No books returned");

       82     Assert.AreEqual(books.Count, 3, "Incorrect number of books returned"); ‘ This Fails

       83     Assert.AreEqual(books[1].ID, 1, "First book returned is incorrect"); ‘ Never Run

       84     Assert.AreEqual(books[2].ID, 2, "Second book returned is incorrect"); ‘ Never Run

       85     Assert.AreEqual(books[3].ID, 3, "Third book returned is incorrect"); ‘ Never Run

       86 }

    This is the main reason Roy gives in his MSDN article on why you should limit tests to a single assert. My idea is that we should have an attribute we could use to tell the framework that we want it to run all the asserts, something like this:

       76 [MultipleAssertTest]

       77 public void GetBooksForAuthorSuccessfull()

       78 {

       79     List<Book> books = AuthorDA.GetBooks(1);

       80     Assert.IsNotNull(books, "Null value returned for books", false);

       81     Assert.IsTrue(books.Count > 0, "No books returned", false);

       82     Assert.AreEqual(books.Count, 3, "Incorrect number of books returned", true);

       83     Assert.AreEqual(books[1].ID, 1, "First book returned is incorrect", true);

       84     Assert.AreEqual(books[2].ID, 2, "Second book returned is incorrect", true);

       85     Assert.AreEqual(books[3].ID, 3, "Third book returned is incorrect", true);

       86 }

    The new test type would allow me to add an additional parameter to all of my assertions that tells the harness whether or not it should continue with the test. If either of the first two asserts fails I want to abort and not evaluate the other assertions since they will all fail. The last four assertions are not dependent on each other so I want to continue running the rest of the assertions in my test if one of them fails. 

    You would then need to be able to see each of the failure in the GUI, something like a tree would work:

    + GetBooksForAuthorSuccessfull() Failed
        –  2 Failures
            * Incorrect number of books returned
            * Third book returned is incorrect

    This would give me the benefits of one assertion per test without the additional code or huge increase in the number of tests. This would be a great feature for MbUnit.

    -James

  • State Machines In Windows Workflow

    A new article on OdeToCode: State Machines In Windows Workflow. State machines have been a powerful abstraction in software for many years. Using a state machine in Windows Workflow means we get all the tracking, persistence, and meta-data support the workflow runtume offers, which is quite a bonus.

    The state machine designer

  • Tip/Trick: Optimizing ASP.NET 2.0 Web Project Build Performance with VS 2005

    This posts covers how to best optimize the build performance with Visual Studio 2005 when using web projects.  If you are experiencing slow builds or want to learn how to speed them up please read on.

    Quick Background on VS 2005 Web Site Project and VS 2005 Web Application Project options

    VS 2005 supports two project-model options: VS 2005 Web Site Projects and VS 2005 Web Application Projects

    VS 2005 Web Site Projects were built-in with the initial VS 2005 release, and provide a project-less based model for doing web development that uses that same dynamic compilation system that ASP.NET 2.0 uses at runtime.  VS 2005 Web Application Projects were released as a fully supported download earlier this spring, and provide a project model that uses a MSBuild based build system that compiles all code in a project into a single assembly (similar to VS 2003 -- but without many of the limitations that VS 2003 web projects had with regard to FrontPage Server Extensions, IIS dependencies, and other issues).  To learn more about VS 2005 Web Application Projects, please review the tutorials I've published on my http://webproject.scottgu.com web-site.  Note that VS 2005 Web Application Project support will be included in VS 2005 SP1 (so no additional download will be required going forward).

    Both the VS 2005 Web Site Project option and the VS 2005 Web Application Project option will continue to be fully supported going forward with future Visual Studio releases.  What we've found is that some people love one option, while disliking the other, and vice-versa.  From a feature perspective there is no "one best option" to use - it really depends on your personal preferences and team dynamics as to which will work best for you.  For example: a lot of enterprise developers love the VS 2005 Web Application option because it provides a lot more build control and team integration support, while a lot of web developers love the VS 2005 Web Site model because of its "just hit save" dynamic model and flexibility.

    Two articles you might find useful to decide which works best for you is this MSDN whitepaper that includes some comparisons between the two models, and Rick Strahl's Web Application Projects and Web Deployment Projects are Here article that provides a good discussion of the pros/cons of the different options.

    To migrate from the VS 2005 Web Site Project model to the VS 2005 Web Application Project model, please follow this C# or VB tutorial that walks-through the steps for how to-do so.

    So Which Project Option Builds Faster?

    When doing full builds of projects, the VS 2005 Web Application Project option will compile projects much faster that the VS 2005 Web Site Project option.  By "full build" I mean cases where every class and page in a project is being compiled and re-built - either because you selected a "Rebuild" option within your "build" menu, or because you modified code within a dependent class library project or in the /app_code directory and then hit "build" or "ctrl-shift-b" to compile the solution. 

    There are a few reasons why the VS 2005 Web Application Project ends up being significantly faster than Web Site Projects in these "full rebuild" scenarios.  The main reason is that (like VS 2003), the VS 2005 Web Application Project option only compiles your page's code-behind code and other classes within your project.  It does not analyze or compile the content/controls/in-line code within your .aspx pages -- which means it does not need to parse those files.  On the downside this means that during compilation it will not check for errors in those files (unlike the VS 2005 Web Site Project option which will identify any errors there).  On the positive side it makes compilations much faster.

    So does this mean that you should always use the VS 2005 Web Application Project option to get the fastest build times with large projects?  No -- not necessarily.  One nice feature that you can enable with the VS 2005 Web Site Project option is support for doing "on demand compilation".  This avoids you having to always re-build an entire project when dependent changes are made -- instead you can just re-build those pages you are working on and do it on-demand.  This will lead to significant build performance improvements for your solution, and can give you a very nice workflow when working on very large projects.  I would definitely recommend using this option if you want to improve your build performance, while retaining the flexibility of the web-site model.

    The below sections provide specific tutorials for both the VS 2005 Web Site Project Model and the VS 2005 Web Application Project Model on optimization techniques -- including the "on demand compilation" build option I described above.

    Specific Tips/Tricks for Optimizing VS 2005 Web Site Project Build Times

    When using the VS 2005 Web Site Project model, you can significantly improve build performance times by following these steps:

    1) Verify that you are not suffering from an issue I call "Dueling Assembly References".  I describe how to both detect and fix this condition in this blog post.  If you are ever doing a build and see the compilation appear to pause in the "Validating Web Site" phase of compilation (meaning no output occurs in the output window for more than a few seconds), then it is likely that you are running into this problem.  Use the techniques outlined in this blog post to fix it.

    2) Keep the number of files in your /app_code directory small.  If you end up having a lot of class files within this directory, I'd recommend you instead add a separate class library project to your VS solution and move these classes within that instead since class library projects compile faster than compiling classes using the /app_code directory.  This isn't usually an issue if you just have a small number of files in /app_code, but if you have lots of directories or dozens of files you will be able to get speed improvements by moving these files into a separate class library project and then reference that project from your web-site.

    3) Enable the on-demand compilation option for your web-site projects.  To enable this, right-click on your web-site project and pull up the project properties page.  Click the "Build" tab on the left to pull up its build settings.  Within the "Build" tab settings page change the F5 Start Action from "Build Web Site" to either the "Build Page" or "No Build" option.  Then make sure to uncheck the "Build Web site as part of solution" checkbox:

    When you click ok to accept these changes you will be running in an on-demand compilation mode.  What this means (when you select the "Build Page" option in the dialog above) is that when you edit a page and then hit F5 (run with debugging) or Ctrl-F5 (run without debugging) the solution will compile all of the class library projects like before, then compile the /app_code directory and Global.asax file, and then instead of re-verifying all pages within the web-site it will only verify the current page you are working on, and any user controls that the page references.  With large (and even medium) projects with lots of pages, this can obviously lead to major performance wins.  Note that ASP.NET will automatically re-compile any other page or control you access at runtime -- so you will always have an up-to-date and current running application (you don't need to worry about old code running).  You can optionally also use the "No Build" option to by-pass page-level validation in the IDE, which obviously speeds up the entire process much further (I'd recommend giving both options a try to see which you prefer). 

    By deselecting the "Build Web site as part of solution" checkbox, you will find that the Ctrl-Shift-B keystroke (which builds the solution) will continue compiling all class library projects, but will not re-build all pages within your web-site project.  You will still get full intellisense support in your pages in this scenario - so you won't lose any design-time support.  You will also continue to get warning/error squiggles in code/class when they are open.  If you want a way to force a re-build to occur on pages not open, or across all pages within the web-site, you can use the "Build Page" or "Build Web Site" menu options within the "Build" menu of Visual Studio:

    This gives you control as to which pages on your site you want to verify (and when) - and can significantly improve build performance.  One trick I recommend doing is adding a new shortcut keystroke to your environment to allow you to quickly short-cut the "Build Page" menu option to avoid you having to ever use a mouse/menu for this.  You can do this by selecting the Tools->Customize menu item, and then click the "Keyboards" button on the bottom-left of the customize dialog.  This will bring up a dialog box that allows you to select the VS Build.BuildPage command and associate it within any keystroke you want:

    Once you do this, you can type "Ctrl-Shift-P" (or any other keystroke you set) on any page to cause VS to compile any modified class library project (effectively the same thing that Ctrl-Shift-B does), then verify all classes within the /app_code directory, and then re-build just the page or user control (and any referenced master pages or user controls it uses) that you are working on within the project.

    Once the above steps are applied, you should find that your build performance and flexibility is much improved - and that you have complete control over builds happen.

    Specific Tips/Tricks for Optimizing VS 2005 Web Application Project Build Times

    If you are using the VS 2005 Web Application project option, here are a few optimizations you might want to consider:

    1) If you have a very large project, or are working on an application with many other developers, you might want to consider splitting it up into multiple "sub-web" projects.  I wouldn't necessarily recommend this for performance reasons (unless you have thousands and thousands of pages it probably doesn't make a huge difference), but it can sometimes make it easier to help manage a large project.  Please read this past blog-post of mine on creating sub-web projects to learn how to use this.

    2) Consider adding a VS 2005 Web Deployment project to your solution for deep verification.  I mentioned above that one downside of using the VS 2005 Web Application Project option was that it only compiled the code-behind source code of your pages, and didn't do a deeper verification of the actual .aspx markup (so it will miss cases where you have a mis-typed tag in your .aspx markup).  This provides the same level of verification support that VS 2003 provided (so you aren't loosing anything from that), but not as deep as the Web Site Project option.  One way you can still get this level of verification with VS 2005 Web Application Projects is to optionally add a VS 2005 Web Deployment Project into your solution (web deployment projects work with both web-site and web-application solutions).  You can configure this to run only when building "release" or "staging" builds of your solution (to avoid taking a build hit at development time), and use it to provide a deep verification of both your content and source code prior to shipping your app. 

    Common Tips/Tricks for Optimizing any VS 2005 Build Time

    Here are a few things I recommend checking anytime you have poor performance when building projects/solutions (note: this list will continue to grow as I hear new ones - so check back in the future):

    1) Watch out for Virus Checkers, Spy-Bots, and Search/Indexing Tools

    VS hits the file-system a lot, and obviously needs to reparse any file within a project that has changed the next time it compiles.  One issue I've seen reported several times are cases where virus scanners, spy-bot detecters, and/or desktop search indexing tools end up monitoring a directory containing a project a little too closely, and continually change the timestamps of these files (they don't alter the contents of the file - but they do change a last touched timestamp that VS also uses).  This then causes a pattern of: you make a change, rebuild, and then in the background the virus/search tool goes in and re-searches/re-checks the file and marks it as altered - which then causes VS to have to re-build it again.  Check for this if you are seeing build performance issues, and consider disabling the directories you are working on from being scanned by other programs.  I've also seen reports of certain Spybot utilities causing extreme slowness with VS debugging - so you might want to verify that you aren't having issues with those either.

    2) Turn off AutoToolboxPopulate in the Windows Forms Designer Options

    There is an option in VS 2005 that will cause VS to automatically populate the toolbox with any controls you compile as part of your solution.  This is a useful feature when developing controls since it updates them when you build, but I've seen a few reports from people who find that it can cause VS to end up taking a long time (almost like a hang) in some circumstances.  Note that this applies both to Windows Forms and Web Projects.  To disable this option, select the Tools->Options menu item, and then unselect the Windows Forms Designer/General/AutoToolboxPopulate checkbox option (for a thread on this see: http://forums.asp.net/1108115/ShowPost.aspx).

    3) Examine which 3rd party packages are running in Visual Studio

    There are a lot of great 3rd party VS packages that you can plug into Visual Studio.  These deliver big productivity wins, and offer tons of features.  Occasionally I've seen issues where performance or stability is being affected by them though.  This is often true in cases where an older version (or beta) of one of these packages is being used (always keep an eye out for when a manufacturer updates them with bug-fixes).  If you are seeing issues with performance or stability, you might want to look at trying a VS configuration where you uninstall any additional packages to see if this makes a difference.  If so, you can work with the 3rd party manufacturer to identify the issue. 

    Visual Basic Build Performance HotFix

    The Visual Basic team has released several hotfixes for compilation performance issues with large VB projects.  You can learn how to obtain these hotfixes immediately from this blog post.  The VB team also has a direct email address -- vbperf@microsoft.com -- that you can use to contact them directly if you are running into performance issues.

     

    Hope this helps,

    Scott

    Share this post: Email it! | bookmark it! | digg it! | reddit!
  • Tip/Trick: UpdateProgress Control and AJAX Activity Image Animations

    One of the cool new controls provided with the ASP.NET AJAX Extensions (aka "Atlas") is the UpdateProgress control.  This control allows you to automatically cause UI to display on a page while an AJAX callback is in progress, and also allows you to provide UI to enable a user to optionally cancel the AJAX callback if it is taking too long.  To use this control on a page, simply declare it like so:

        <atlas:UpdateProgress ID="progress1" runat="server">
            
    <ProgressTemplate>
            
                
    <div class="progress">
                    
    <img src="indicator.gif" /> 
                    Please Wait...
                </
    div>
            
            
    </ProgressTemplate>
        
    </atlas:UpdateProgress>

    The content within the <ProgressTemplate> will then display while an AJAX callback is occuring.  You can use CSS rules to position the content displayed anywhere on the page (for example: you might want to fade it in directly on top of a GridView or other element).  Developers often use animated images to indicate progress to users as well within this <ProgressTemplate>.

    Alan Le recently posted a cool link to a few useful sites that provide lots of animated indicator progress icons that you can easily use with the UpdateProgress control to visually indicate a callback operation:

    Each site allows you to download spinning gears and progress icons that you can use.  A few examples can be found below:

    I posted earlier this week about the new release of the Atlas Control Toolkit that now includes an animation library that can be used with the ASP.NET AJAX Extensions.  Used properly with the UpdateProgress control they can add a nice visual feel to your site. 

    Hope this helps,

    Scott

     

    Share this post: Email it! | bookmark it! | digg it! | reddit!
  • When to set AspCompat

    If we interop with a COM component from ASP.NET, we might need to use AspCompat="true" in the @ Page directive. The question is: when do we need AspCompat?

    The answer is that we need AspCompat if the COM component has to run on a thread initialized into a single threaded apartment (STA). This begs the question: how do we know if a component needs to run in an STA?

    One answer is to dig into the HKEY_CLASSES_ROOT section of the registry and find the component by CLSID (or by ProgID, which can give us the CLSID). Inside will be an InprocServer32 key, which holds a ThreadingModel value.

    We could also find this value using the OLE/COM Object Viewer. Locate the component on the left, and look for the ThreadingModel setting on the right.

    If the ThreadingModel value is "Apartment", we need to use AspCompat="true" (and look for ways to get rid of the component). If the value is "Free", "Neutral", or "Both", then we don't need AspCompat.

    This post was brought to you by the Ministry of Boring Trivia, headquartered in a bar in the airport of Savannah, Georgia.

  • New MbUnit Site

    The guys working hard on MbUnit have launched a new site. It doesn't have a ton more than links at the moment, but it should help point people in the right directly and hopefully will have more to offer in the future.

    I was also happy to see Scott linking to me and helping get the word our about MbUnit.

    -James

  • An ASP.NET 2.0 Validator Web Control for CheckBoxes and CheckBoxLists

    ASP.NET provides a variety of validation Web controls that can be used to validate a user's form field inputs. Unfortunately, the validation Web controls do not work with the CheckBox or CheckBoxList Web controls. If you set a validation control's ControlToValidate property to the ID of a CheckBox or CheckBoxList, the page will throw an HttpException, stating: "Control 'controlID' referenced by the ControlToValidate property of 'validationControlID' cannot be validated."

    There may be times, however, when you need to provide validation for a CheckBox or CheckBoxList. In fact, a rather popular article on 4Guys is Creating a Validation Control for CheckBoxLists by Cenk Civici and yours truly, which shows how to create a CheckBoxList validation control to ensure that at least one checkbox from the list is selected. Similarly, I recently got an email from a reader of my Working with Data in ASP.NET 2.0 tutorial series asking about validating a CheckBox being checked. For example, many Web pages with Terms of Service include a CheckBox titled "I agree to the above terms" that must be checked before continuing.

    To provide such validation, we have three choices:

    1. Forgo any sort of validation Web control semantics and perform the validation check using code on postback. The downside of this is that it breaks from the standard validation control metaphor and requires extra effort to include client-side validation.
    2. Use the CustomValidator control and define our own server-side and client-side validation logic. The benefit of this approach is that it adheres to the validation control metaphor; however, the validation logic is tightly bound to the ASP.NET page, meaning that the server-side and client-side validation must be replicated on all pages that need to validate a CheckBox or CheckBoxList.
    3. Create a custom, compiled validation server control that provides the functionality needed. The benefit of this approach is that we have a reusable, easily deployable custom server control that adheres to the validation control metaphor. Unfortunately, this option requires the most upfront code/effort.

    Yesterday, I decided to write a custom, compiled validation control for the CheckBox and one for the CheckBoxList using the .NET Framework 2.0 (thereby targetting ASP.NET 2.0). Unlike the CheckBoxListRequiredFieldValidator created by Cenk, these two validators also include client-side script validation support. You can download the CheckBoxValidator and CheckBoxListValidator controls from My Code Projects; a discussion on the CheckBoxList control can be found in the latest 4Guys article, Creating Validator Controls for the CheckBox and CheckBoxList.

  • Forum Quote Of The Day

    From an ASP.NET discussion:   

    "Real men don't write code, they regenerate it."

    Use the comments to discuss the technological, grammatical, and sociological aspects of this statement.

  • Top Ten ASP.NET Tips and Traps - Presented this Saturday at the SoCal .NET Technical Summit

    This Saturday - September 23rd - I'll be presenting my talk, Top 10 ASP.NET Tips and Traps, at the SoCal .NET Technical Summit in Irvine, California. It's not too late to sign up! For $99 you get a full day of sessions from a variety of top-notch speakers (including Rocky Lhotka, Scott Stanfield, Bill Vaughn, Chris Rolon, and others), organized into four tracks: Web/Atlas, Data, Architecture and Enterprise Practices, and Vista/WPF/WCF/WWF.

    Earlier I listed the tips and traps I was planning on presenting, and asked for any feedback. I ended up settling on the following list (in the following order), organizing the tips/traps into four categories:

    • Caching
      • TIP: Use SQL Cache Dependencies
      • TIP: Use HttpContext.Items as a Per-Request Cache
      • TRAP: Avoid a Common Caching Race Condition
    • Performance
      • TIP: Improve Paging Performance with Custom Paging
      • TIP: Disable View State (Where Appropriate) to Reduce Page Bloat
    • Client-Side
      • TIP: Know the Client-Side Enhancements in ASP.NET 2.0
      • TRAP: Beware Broken Links and Images in Master Pages
    • Design-Time
      • TIP: Master Visual Studio 2005's Enhancements
      • TIP: Use Reflector to Explore Framework Code
      • TRAP: When Using Membership, Don't Forget to Set applicationName

    You can download this presentation at http://datawebcontrols.com/classes/TipsAndTraps.zip; to see it presented in person, head on down to the SoCal .NET Technical Summit! Hope to see you there!

  • September Atlas Control Toolkit Released (Now with Animation Support)

    The latest refresh of the Atlas Control Toolkit, which is a great library of useful ASP.NET AJAX-enabled controls built on top of the core ASP.NET AJAX runtime, was posted late last week.  You can run samples online as well as download it here.

    As I have mentioned in earlier posts, what is cool about the Toolkit is that it includes several controls contributed by non-Microsoft developers.  For example, new in this release is a cool new "Slider" control (click here to see a demo of it in action) that was contributed and which enables smooth client-side range-picking support:

    Also included with this release of the Toolkit is some of the new client-side animation support that is starting to come online.  The animation package can be used both directly from JavaScript, or via a new <atlasToolkit:AnimationExtender> control that you can use to easily compose animation behaviors (for example: you could have text or an image fade in, expand, explode, move, pop-up, etc) in response to user action. 

    What is cool about the Animation package is that you can optionally define animation behaviors declaratively using the <atlas:AnimationExtender> control, which makes defining animation sequences clean and easy. 

    You can learn more about the new Animation package as well as run the demos online here.  Also make sure to check out the Animation Reference Page to learn more about the Animation class framework and all of the methods, properties, and events it supports. 

    In addition to firing animations in response to user clicks or client-side behavior, you can also use the new <AtlasToolkit:UpdatePanelAnimationExtender> to add animation support in response to post-backs that use the new ASP.NET AJAX UpdatePanel control to refresh portions of a page.  This can make highlighting or indicating changed UI cleaner and more user friendly (for example: you could gently fade in changes - or get really fancy and rotate/color-code them if you want to make your users dizzy).  Check out this online demo of the UpdatePanelAnimationExtender to learn more on this control.  Alan Le also posted a nice simple sample showing how you can declaratively compose animations using it here that you should check out as well.

    As always, you can download the Atlas Control Toolkit for free (with complete source) and run it online here.  To learn more about using both ASP.NET AJAX (aka Atlas) as well as the Control Toolkit, also check out this blog post I did a few weeks ago linking to a bunch of great free videos you can watch.

    Hope this helps,

    Scott

     

    Share this post: Email it! | bookmark it! | digg it! | reddit!
  • Tip/Trick: Using IIS7 on Vista with VS 2005

    A few people have pinged me over the last week asking about how to use VS 2005 with an IIS 7.0 web-site on Windows Vista.  Specifically, they've run into an issue where they see a dialog message asking them to install the FrontPage Server Extensions, or they get a "You must be a member of the administrators group" message when they try to connect (see dialog below):

    Bradley has published a nice blog post that describes detailed steps on how to enable VS 2005 to connect to IIS 7.0.  To quickly summarize you need to follow the below two steps to enable it:

    1) You need to make sure that you have the the optional "IIS 6 Management Compatibility" option installed within IIS7.  This installs an API for the new configuration system that is compatible with the old Metabase APIs (which is what VS 2005 uses).  You can select this using the "Turn Windows Features on or Off" option in the Vista Control Panel:

     

    2) You need to make sure you launch VS 2005 with "elevated" privledges so that you have admin privledges to connect to IIS (this is needed to debug a service, as well as create sites and/or change bindings that impact the entire machine).  You can do this by right-clicking on the VS icon and select the "Run as Administrator" option when launching VS:

    Note that this is needed even if your user is already in the administrators group if you have UAC enabled (which is on by default with Vista).  If you disable UAC (which you can also do via the control panel), then this second step isn't required.  Running VS 2005 with "elevated" privledges won't be required if you use the built-in VS 2005 Web-Server (since it has reduced privledges already).  It is only required when connecting and running/debugging with IIS locally.

    We'll be updating Visual Studio 2005 to have more accurate error messages to help guide you to the above steps more naturally in the future.  Until then, just use the above steps and you are good to go.

    Hope this helps,

    Scott

    Share this post: Email it! | bookmark it! | digg it! | reddit!
  • The Art of Escalation in Software Requirement Meetings

    Maybe you've dealt with The Escalator before. The conversations with The Escalator go something like this:

    "Now, what about this scenario? This is a very high-priority scenario for our users. We have to have this feature in the next release".

    "We costed that scenario, and we don't have the time in this release".

    "But this is a high priority scenario."

    "Every feature in this iteration is high priority".

    "You don't understand, our user's can't do their jobs without this feature. If we don't deliver this, the project will fail".

    "But, it was never that important before…"

    "Look – if we don't deliver this – I … will … loose … my … job".

    <blank stares>

    "Please! For the love of God! The mafia will kill my family!" <tears>

    "Um … ok. We might be able to bump something and squeeze it in…"

    "Great! Now, about this other scenario. This is a very high-priority scenario for our users. We have to have this feature in the next release…."

  • Pervasive Tools, a couple more tools

    Mike Gunderloy has a good article about the general categories of tools that every developer should be using, I would add a couple more categories to his list:

    Diagnostic ToolsFiddler, CLR Profiler, DotTrace etc. You need to have a way to figure out what is going on when the debugger fails you.

    Bug Tracking – Even if you are the only developer you still need somewhere to log bugs that you can’t fix right away. It could be something sophisticated or something simple.

    Continuous Integration – This is kind of implied in the Build category, but I think it’s important enough to call it out. Whenever you check in code something should be grabbing all of your code, running all your tests, and giving you reports.

    Code Generation – Your time is too valuable to bang out monotonous code, you need something to write it for you.

    -James

  • Tip/Trick: Enabling Back/Forward-Button Support for ASP.NET AJAX UpdatePanel

    Nikhil recently posted a nice blog post that includes a new ASP.NET AJAX-enabled control called "HistoryControl".  When added to a page it allows developers to programmatically add logical views into a browser's history list.  This enables you to make AJAX enabled sites much more useful, and to follow the standard back/forward navigation paradigm that traditional web apps follow.

    For example, the below code could be written by a developer in response to a selection change within a list to to add the previous list selection to the browser's history via Nikhil's "HistoryControl":

    private void ContentList_SelectedIndexChanged(object sender, EventArgs e) {
       history.AddEntry(contentList.SelectedIndex.ToString()
    ;
    }

    Once you add entries into the history control, the back/forward button will be enabled in the browser.  Nikhil's history control then exposes a "Navigate" event which fires when you press the forward or back button in the browser, and this event then exposes the identifier entry provided before when the view was added into the browser history.  You can then use this to restore the page to whatever state it should be in to match the previous history item and update the page:

    private void HistoryControl_Navigate(object sender, HistoryEventArgs e) {

        
    int selectedIndex 0;

        if 
    (String.IsNullOrEmpty(e.Identifier) == false) {
            selectedIndex 
    Int32.Parse(e.Identifier);
        
    }

        
    // Update the content being displayed in the page
        
    contentList.SelectedIndex selectedIndex;

        
    // Mark the update panels as needing an update
        
    mainUpdatePanel.Update();
    }

    And now your end-users get forward/back button history navigation working with AJAX.  You can download the code for Nikhil's history control and start using it here.

    Hope this helps,

    Scott

    Share this post: Email it! | bookmark it! | digg it! | reddit!
  • Five New Data Tutorials

    My Working with Data in ASP.NET 2.0 tutorial series has been updated to include five new tutorials: one on working with custom Button actions and four on displaying data with the DataList and Repeater controls!

    The four tutorials on the DataList and Repeater begin the second phase of the tutorial series, turning attention from the GridView, DetailsView, and FormView controls to the DataList and Repeater controls. Over the course of the four new ones and 14 remaining tutorials yet to be published, we'll look at how to do edits and deletes, paging and sorting, and utilize custom Button actions with the DataList and Repeater controls.

    Also, a word of thanks to the many people who've read the tutorials. I've been getting about a dozen emails a day from folks with questions, pointing out typos, comments, and so on, and have tried my best to respond as quickly as possible (although some replies have taken several days - sorry!).

    Enjoy!

  • Let's Get Threaded

    Threading. It's the new frontier. At least, that's what all the cool articles say these days.

    The premise is that we have these new fangled dual core chips, but our applications aren't taking advantage of all the horsepower available because we don't use enough threads. We need to use more threads, they say. We have to grab those chips by their cores and bend every transistor to the will of our application.

    Imagine if your local government doubled the width of all the roads in your area, and car manufacturers followed up by doubling the size of all new cars. Would that be an improvement?

    I'd argue that dual core CPUs allow hardware to finally catch up with today's common usage. I have twice as many processes running today as I did in the old days (when Moore's law allowed processes to keep up). I have streaming audio playing while I'm synching a smart phone and an MP3 player. I have a torrent client running at the same time my desktop search engine is indexing and my newsreader is aggregating. I have at least one virtual machine and Outlook running all the time, and in Vista, everyone will have desktop gadgetry doing whiz-bang animations and back flips in a sidebar.

    The last thing we need in this scenario is some application to come along and crush all the background work with threads of its own. Most applications just need enough to keep the UI responsive and do a little work in between button clicks.

    Share the processor, and your users will thank you.

  • What's Wrong With This Code (#5)

    Joe Developer is working on a bowling program (again). Joe wrote the following code.

    using System;
    using System.Collections.Generic;

    [
    Serializable]
    class Bowlers
    {
        
    List<string> _bowlerList = new List<string>();

        
    public void AddBowler(string name)
        {
            _bowlerList.Add(name);

            
    EventHandler<BowlerAddedEventArgs> handler = BowlerAdded;
            
    if (handler != null)
            {
                handler(
    this, new BowlerAddedEventArgs(name));
            }
        }

        
    public event EventHandler<BowlerAddedEventArgs> BowlerAdded;

        
    // ...
    }

    [
    Serializable]
    class BowlerAddedEventArgs : EventArgs
    {
        
    public BowlerAddedEventArgs(string name)
        {
            Name = name;
        }

        
    public string Name;
    }

    Joe unit tested the code to within an inch of its life, so he was surprised when another developer wrote the following program, which throws an exception.

    using System;
    using System.IO;
    using System.Runtime.Serialization.Formatters.Binary;

    class Test
    {
        
    public static void Main()
        {
            
    Bowlers bowlers = new Bowlers();

            
    string addedMessage = "Added bowler: {0}";
            bowlers.BowlerAdded +=
                
    delegate(object sender, BowlerAddedEventArgs e)
                {
                    
    Console.WriteLine(addedMessage, e.Name);
                };

            bowlers.AddBowler(
    "Bob");
            bowlers.AddBowler(
    "Jan");
            bowlers.AddBowler(
    "Ann");

            
    using (MemoryStream stream = new MemoryStream())
            {
                
    BinaryFormatter formatter = new BinaryFormatter();
                formatter.Serialize(stream, bowlers);
            }
        }
    }  

    What's wrong?

    Hint: the exception is a strange looking serialization exception.

  • Pete Wright is done with Microsoft

    So, today I resigned my job, and completely ended my Microsoft career. I have taken a role as Director with a company at the leading edge of the “Web 2.0” curve. My team and I will write Ruby on Rails code, use Macintosh computers to do so, shun Microsoft technology completely, go to work in shorts and sandals and blast each other with nerf guns.

    Pete Wright

    I have a ton of respect for Pete and look forward to reading about his new experiences. I know more and more .NET developers who are playing around with RoR in their spare time, I wonder how many will convert over the next couple years?

    -James

  • I think Toshiba and HD-DVD just won

    This is bad, bad, bad news for Sony.

    Toshiba Develops 3–Layer DVD and HD-DVD

    Backwards compatibility is a killer feature here. You could buy a DVD and play it in your home HD-DVD player, but then on your portable DVD player on a plane, or the DVD player in your car, etc.

    Do you think they even considered the fact that Blueray and Betamax are both 7 letters, start with a B, and contain two separate words mashed together?

    -James

  • "Atlas" 1.0 Naming and Roadmap

    Over the last year we’ve been working hard on “Atlas”. It has evolved, changed, and grown because of the amazing amount of feedback and early adoption that we’ve seen. We’ve had an unbelievable amount of interest and excitement around the product, with more than 250,000 downloads this year alone.

    Shipping “Atlas” 1.0

    Many people have asked us to deliver a fully-supported 1.0 release of “Atlas” before the next release of Visual Studio. “Fully supported” means that Microsoft product support services are available 24 hours a day, 7 days a week, 365 days a year and that any customer can obtain hotfixes if they encounter a bug affecting their application. It also means that the product has a committed servicing product lifetime of 10 years – which provides companies with the ability to depend on it for mission critical applications.

    I am excited to announce today that we are going to ship this fully supported “Atlas” 1.0 release on top of ASP.NET 2.0 and ensure that it works with Visual Studio 2005. Our goal is to ship the “Atlas” 1.0 release around the end of this year. The plan is to first have a Beta, then an RC, and then decide on the final date based on customer feedback.

    “Atlas” Feature Delivery Plan

    To help expedite the schedule and get out a fully supported release this year, we are going to focus on delivering a “core” set of fully supported functionality.  This core set of functionality includes all the common components needed to enable developers to build client-side controls/components, as well as the server-side functionality that provides integration within ASP.NET (including the super-popular update-panel and other server controls).

    There are features of the current “Atlas” CTP drops that won’t be in the fully supported “core” bucket. These features will continue to be available in a separate download and will continue to work on top of the supported “core” release. We aren’t pulling back from these features at all.  We are simply trying to optimize the timing of the first fully supported set of features and also make sure that we have the flexibility to continue to evolve and innovate some features in a more agile fashion (whereas we are trying to “bake down” the core set of features and avoid having it change dramatically in the future).

    We will obviously continue to support a Go-Live license for all features going forward. Enterprise customers who only want to use products backed by a full support agreement can optionally choose to only use those features in the “core” release.

    Over time we will be moving more and more features into the fully supported bucket. We will also be publishing a detailed white paper listing features, release plans, and product changes from the CTPs to help with planning over the next few weeks.

    “Atlas” Naming

    As part of releasing “Atlas”, we have also finally locked on an official set of product names that we will begin using moving forward. What was formerly called “Atlas” will now have a few names:

    1) The client-side “Atlas” javascript library is going to be called the Microsoft AJAX Library. This will work with any browser, and also support any backend web server (read these blog posts to see how to run it on PHP and ColdFusion).

    2) The server-side “Atlas” functionality that nicely integrates with ASP.NET will be called the ASP.NET 2.0 AJAX Extensions. As part of this change the tag prefix for the “Atlas” controls will change from <atlas:>to <asp:>. These controls will also be built-in to ASP.NET vNext.

    3) The “Atlas” Control Toolkit today is a set of free, shared source controls and components that help you get the most value from the ASP.NET AJAX Extensions. Going forward, the name of the project will change to be the ASP.NET AJAX Control Toolkit.

    In closing

    We are really excited about being able to get a fully supported 1.0 release out. It will be 100% cross-browser and cross-platform. It will simplify adding rich AJAX functionality to ASP.NET applications, and it will enable hugely improved UX for end users. Getting this functionality into your hands in the most flexible way possible is our number one priority and we think the plan I outline above does just that.

    Things will get even better next year with Visual Studio “Orcas” where we are adding rich JavaScript intellisense, debugging and WYSIWYG designer support for the ASP.NET AJAX Extensions within Visual Studio and many other great features to take advantage of.

    Thanks,

    Scott

    Share this post: Email it! | bookmark it! | digg it! | reddit!
  • October's Toolbox Column in MSDN Magazine

    My tenth Toolbox column in the October 2006 issue of MSDN Magazine is now avaiable online. The October issue examines two products:

    • PreEmtive Solutions Dotfuscator (version 3.0) - obfuscate your .NET assemblies to protect your company's intellectual property. Obfuscation (IMO) is a must if you develop a product that is shipped to customers.
    • NHibernate - quickly persist and retrieve information from a database using NHibernate to automate the process of building the necessary code and query capabilities. NHibernate is a free, open-source framework tool for quickly building a data access layer between your business objects and data store.

    This month's issue reviewed Eric Brown's book SQL Server 2005 Distilled. Eric provides a nice high-level overview of the key features and changes in SQL Server 2005 that is a must-read for any organization that's contemplating upgrading to 2005. From the review:

    Most computer trade books focus on exploring a particular subset of features in great depth and are ideal for developers interested in mastering a new technology. If, however, you want a high-level overview of a technology suitable for evaluation purposes (or for just gaining a broad understanding of the technology) you'll instead need to turn to a book like SQL Server 2005 Distilled (Addison-Wesley, 2006). Authored by former SQL Server team member Eric Brown, the book provides an executive summary of key features, such as security, database management, developer tools, business intelligence, working with XML data, CLR integration, and so on.

    Apart from Chapter 6, "The Code Chapter," which has a hodgepodge of examples for performing various queries and administrative tasks, you won't find much T-SQL syntax or DBA-level walkthroughs. Instead, the other chapters provide their high-level overviews using mostly prose mixed with architectural and use case diagrams. And at 336 pages, SQL Server 2005 Distilled provides a digestible overview that can be read cover-to-cover over the course of a weekend.

    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.

  • This Could Be a Team Foundation Server Kind of Week

    A few weeks ago, the company I'm working with made an acquisition, thus becoming a slightly bigger, more distributed company. The acquisition started a chain of events that ultimately resulted in me pitching Team Foundation Server (TFS) to a group of executives and developers. The pitch was successful - at least I've been told the licenses can be purchased this week. It was an interesting (and sometimes frustrating) experience getting to this point….

    Problems
    The acquisition forced a reevaluation of existing tools and processes. With the exception of Visual Studio and SQL Server, all the tools used for product development are a hodgepodge of free software and custom-built applications. The build engine, for example, is a Windows service I wrote years ago, and before I heard of a tool called NAnt. Only two people on the planet are willing to write XML scripts for my build engine - which is one problem.

    A solution would be to replace my build engine with NAnt, but that only solves one of the problems. Technologies like Sharepoint only get a team so far in tracking issues, projects, bugs, and customer requirements. I experimented with a trail version of TFS and decided its features, and the tight integration with Visual Studio, would be a great boon to the team's productivity.

    I was also encouraged by TFS customizations I've seen. For example, take a look at Mitch Denny's "Yesterday's Weather" post.

    The next step was to get a ballpark figure for licensing. I could float this figure around and see if the approach was tenable…

    Pricing
    If you ask Microsoft how to buy Team Foundation Server, they will tell you to contact an authorized reseller, or a Microsoft partner. Well, this company is a Microsoft partner. I logged into the partner website to find information, but came up empty, so I contacted the partner program directly. I would have had more success calling the psychic hotline and asking for my tarot reading, because the people I talked to in the partner program were clueless. The experience only furthered my belief that the partner program is the dimwitted step-cousin of the marketing department.

    Still trying to get an approximate cost for the retooling, I started searching reseller websites.

    I thought my head was going to explode.

    It turned out there were too many permutations of SKUs and licenses to make this a job I wanted to do. I read the "Software Assurance" FAQ. I looked to see what "Microsoft Open License" was. All the while, I was also trying to judge if the price I was seeing was an upgrade, or a renewal, or included an MSDN subscription, or was actually the U.S. dollar figure that resembled the price we would pay. The pain of searching through item descriptions was excruciating, so I gave up.

    In the end, I contacted a reseller directly (CDW, to be exact), and talked to a sales rep. The guy was fantastic, although it still took some time to figure out the exact part numbers.

    The Demo
    The quotes I received for licensing met a favorable response, but no one else had seen TFS, so they were still a little edgy. I took the TFS Virtual PC image available to MSDN subscribers and worked up a 30-minute presentation on Team System. The execs liked the reports, work item visibility, and integration with Excel and Project. Developers liked the features, too - like how a completed work item contains a link to its changeset.

    There is still some concern over how much administration TFS will require. Another risk is the future of TFS, which is unclear to me. Will future versions hike up the price? Will there be backward compatibility? Despite these unknowns, I think TFS is a great choice for a relatively small company. Nothing else offers this range of features in this price range.

  • CSS Control Adapters for ASP.NET 2.0

    A control adapter allows you to plug-in into any ASP.NET server control and override, modify and/or tweak the rendering output logic of that control.

    ScottGu

    I wasn’t aware of these until we wrote about them for the book, now there is a new version available.

    -James

     

     

  • CSS Control Adapter Toolkit Update

    Today we released a refresh of the CSS Control Adapters for ASP.NET 2.0.  You can download it for free and immediately begin using it to enable pure CSS optimized markup for the following ASP.NET controls:

    • Menu
    • TreeView
    • GridView (new)
    • DetailsView
    • FormsView
    • DataList
    • Login (new)
    • ChangePassword (new)
    • CreateUser (new)
    • PasswordRecovery (new)
    • LoginStatus (new)

    As I blogged about with the first release of the CSS Control Adapters, these control adapters use a new built-in extensibility mechanism in ASP.NET 2.0 called "control adapters".  A control adapter allows you to plug-in into any ASP.NET server control and override, modify and/or tweak the rendering output logic of that control.

    What is cool about control adapters is that they do not require a page developer to program against a new control, or modify the control programming model semantics (you still use the same control properties, methods, events and templates you did before).  A developer building a page can be entirely oblivious that a control adapter is being used (the control adapter model makes it very clean to register and encapsulate this support).

    Quick Getting Started Walkthrough

    To use the CSS Control Adapter Toolkit, simply follow the below steps using either Visual Web Developer (which is free) or Visual Studio 2005:

    Step 1: Install the CSS Control Adapter Toolkit:  

    Download and install the CSS Control Adapters on your machine.  Click here to download a .VSI template project for Visual Studio that will create a ready-to-run project template with the CSS control adapters installed.  This is a safe download that doesn't modify any files or settings within VS or ASP.NET, so you don't need to worry about it causing any problems with existing code.

    Step 2: Create a New Web Site with the CS Control Adpaters Registered:

    Within Visual Web Developer or VS 2005, choose the "File->New Web Site" menu option.  This will bring up the "New Website" dialog.  Choose your language and then select the new "CSS Friendly Web Site" project template option that has been installed:

    This will create a new web-site project for you that already has the CSS Control Adapters included as source code within your app_code directory.  It also then includes some default CSS stylesheet files with pre-defined class names for you to easily customize with whatever CSS markup you want:

    Step 3: Try out some of the CSS styled control samples: 

    To see how the control adapters adapt server control markup, explore the "walkthrough" sub-directory that is also added by default to the new project:

    For example, the "SimpleMenu.aspx" page statically defines a menu control like below that also has an "OnClick" event handler wired up (alternatively you could use navigation to directly navigate to a specific page):

    <asp:Menu ID="EntertainmentMenu" runat="server" Orientation="Horizontal" onmenuitemclick="Menu_OnClick" CssSelectorClass="SimpleEntertainmentMenu">
        
    <Items>
            
    <asp:MenuItem Text="Music">
                
    <asp:MenuItem Text="Classical" />
                <
    asp:MenuItem Text="Rock">
                    
    <asp:MenuItem Text="Electric" />
                    <
    asp:MenuItem Text="Acoustical" />
                </
    asp:MenuItem>
                
    <asp:MenuItem Text="Jazz" />
            </
    asp:MenuItem>
            
    <asp:MenuItem Text="Movies" Selectable="false">
                
    <asp:MenuItem Text="Action" />
                <
    asp:MenuItem Text="Drama" />
                <
    asp:MenuItem Text="Musical" />
            </
    asp:MenuItem>
        
    </Items>
    </asp:Menu>

    Where the code for the Menu_OnClick event looks like this in the code-behind:

        Public Sub Menu_OnClick(ByVal sender As ObjectByVal As MenuEventArgs)
            MessageLabel.Text 
    "You selected " & e.Item.Text & "."
            
    e.Item.Selected = True
        End Sub

    At runtime the CSS Control Adapter causes the menu to output CSS styleable output using <li> and <ul> elements instead of tables, and when we apply a CSS stylesheet to the page we get a nice hierarchical drop-down menu:

    While you are looking at the samples, you might also want to checkout the CheckBoxTreeView sample - which demonstrates how to use CSS to stylize the <asp:treeview> control to enable inline checkboxes:

     

    So How Do Control Adapters Work?

    Control Adapters are classs that derive via the System.Web.UI.Adapters.ControlAdapter base class, and which implement rendering methods that allow a control adapter to completely customize how the markup of an individual control is rendered.  When you create a new web site project using the "CSS Friendly Web Site" project template, the source code for 11 pre-build CSS friendly control adapters are automatically added to your app_code directory:

    You can use these control adapter classes as-is to get pure CSS friendly output (no need to change the code), or you can tweak them if you want to customize the rendering output however you want. 

    ControlAdapters are then registered with ASP.NET by added a .browser file to the /App_Browsers directory immediately underneath the project's application root.  A .browser file includes simple markup like below that allows you to specify which Control Adapter should be used for which control:

    <browsers>
      
    <browser refID="Default">
        
    <controlAdapters>
          
    <adapter controlType="System.Web.UI.WebControls.Menu" adapterType="CSSFriendly.MenuAdapter" />
          <
    adapter controlType="System.Web.UI.WebControls.TreeView" adapterType="CSSFriendly.TreeViewAdapter" />
          <
    adapter controlType="System.Web.UI.WebControls.DetailsView" adapterType="CSSFriendly.DetailsViewAdapter" />
          <
    adapter controlType="System.Web.UI.WebControls.FormView" adapterType="CSSFriendly.FormViewAdapter" />
          <
    adapter controlType="System.Web.UI.WebControls.DataList" adapterType="CSSFriendly.DataListAdapter" />
          <
    adapter controlType="System.Web.UI.WebControls.GridView" adapterType="CSSFriendly.GridViewAdapter" />
          <
    adapter controlType="System.Web.UI.WebControls.ChangePassword" adapterType="CSSFriendly.ChangePasswordAdapter" />
          <
    adapter controlType="System.Web.UI.WebControls.Login" adapterType="CSSFriendly.LoginAdapter" />
          <
    adapter controlType="System.Web.UI.WebControls.LoginStatus" adapterType="CSSFriendly.LoginStatusAdapter" />
          <
    adapter controlType="System.Web.UI.WebControls.CreateUserWizard" adapterType="CSSFriendly.CreateUserWizardAdapter" />
          <
    adapter controlType="System.Web.UI.WebControls.PasswordRecovery" adapterType="CSSFriendly.PasswordRecoveryAdapter" />
        </
    controlAdapters>
      
    </browser>
    </browsers>

    You can customize different control adapters for different browsers if you want, or just define them for "Default" to apply them by default to all browsers that visit your app.

    Once you do that you are good to go - and can use standard CSS stylesheets to customize all style information.

    For questions or reporting any bugs/issues, please visit the CSS Control Adapters Forum on the http://forums.asp.net web-site.

    Hope this helps,

    Scott

    P.S. The CSS Control Adapters above work both with the VS 2005 Web Site Project Model and the VS 2005 Web Application Project Model.  There are also both VB and C# versions of the control adapters that you can use.

    Share this post: Email it! | bookmark it! | digg it! | reddit!
  • I have seen the light and it is called MbUnit

    I have been using NUnit for a number of years now and more recently started using Team System on a number of projects. As an MVP I get a free copy of Team System so the cost was never an issue. On my most recent project we decided to use Team System because of the very useful built in code coverage (this was before nCover was even revised for .NET 2.0) and because of the new useful assertions (which are now becoming available in NUnit 2.4). I don’t really have any issues with Team System testing, its a good solid unit testing framework.

    Recently while getting started on a new side project I thought I would re-examine the unit testing landscape. After reading about how much people like MbUnit, and a quick chat with Phil, I decided to give it a whirl. I was floored. MbUnit is like unit testing on crack. Sure, it has all your basic Asserts and other standard methods, but then on top of it there are some awesome features:

    [RowTest]
    This is probably the #1 feature to me. Normally when writing unit tests you end up with a number of different tests for various scenarios. For instance I might have (this is all mocked up, ignore any syntax errors, or mock me and point them out in the comments):

        1 [Test]

        2 public void AddValidUser()

        3 {

        4     User u = new User();

        5     u.Name = "James";

        6     u.Email = "myemail@email.com";

        7 

        8     u.Save();

        9 

       10     User newUser = User.Retrieve(u.ID);

       11     Assert.IsNotNull(newUser, "User not found");

       12     Assert.IsTrue(newUser.Name == u.Name, "Name not saved correctly");

       13     Assert.IsTrue(newUser.Email == newUser.Email, "Email not saved correctly");

       14 }

       15 

       16 [Test]

       17 [ExpectedException(typeof(InvalidUserException))]

       18 public void AddInvalidUserMissingEmail()

       19 {

       20     User u = new User();

       21     u.Name = "James";

       22     u.Save();

       23 }

       24 

       25 [Test]

       26 [ExpectedException(typeof(InvalidUserException))]

       27 public void AddInvalidUserMissingName()

       28 {

       29     User u = new User();

       30     u.Email = "myemail@email.com";

       31     u.Save();

       32 }

       33 

       34 [Test]

       35 [ExpectedException(typeof(InvalidUserExperience))]

       36 public void AddInvalidUserBadEmail()

       37 {

       38     User u = new User();

       39     u.Email = "mybademail.com";

       40     u.Save();

       41 }

    I have four tests to test a couple different scenarios for different scenarios with my user object, on a larger object and with more rules I get even more tests. If I add a new required field I have to add it to every test.

    The [RowTest] attribute helps put all of this into one easier to maintain test:

        1 [RowTest]

        2 [Row("James", "myemail@email.com")]

        3 [Row("James", "", ExpectedException=typeof(InvalidUserException))]

        4 [Row("", "myemail@emai.com", ExpectedException = typeof(InvalidUserException))]

        5 [Row("James", "mybademail.com", ExpectedException = typeof(InvalidUserException))]

        6 public void AddValidUser(string name, string email)

        7 {

        8     User u = new User();

        9     u.Name = name;

       10     u.Email = email;

       11 

       12     u.Save();

       13 

       14     User newUser = User.Retrieve(u.ID);

       15     Assert.IsNotNull(newUser, "User not found");

       16     Assert.IsTrue(newUser.Name == u.Name, "Name not saved correctly");

       17     Assert.IsTrue(newUser.Email == newUser.Email, "Email not saved correctly");

       18 }

    How freaking sweet is that?

    [Rollback]
    Instead of manually rolling back database changes this attribute with use Roy’s brilliant method of wrapping it all up in a COM+ transactions.

    Jim is also a big fan of the pairwise testing, but I haven’t really used it enough to have an opinion yet. Another cool part is that it all works perfectly with testdriven.net (obviously) and if you use testdriven.net then you can still use Team System code coverage.

    If you are starting a new project I would definitely take a good look at MbUnit.

    -James

  • IIS 7.0 RC1

    As you might have already heard, Windows Vista RC1 was released late last week.  I've been running it on my primary machine the last few days and have been really impressed with it.  Zero crashes so far, and it is running really smoothly for me. 

    The code in Vista that I've been very involved with is IIS 7.0 - which is a major update to the Microsoft web server platform, and brings tons of goodness.  Earlier this summer we launched the www.iis.net web-site, which you can visit to learn more about IIS7 and all the cool things you can do with it.  Bill Staples, who runs the IIS7 team, has recently written a good blog post about some of the cool changes/improvements that the team has done with the RC1 release.  One of the things he mentioned was some of the changes we recently made to the new Admin UI interface:

    In my talk in Phoenix earlier today, I demoed some of the cool new things you can now do with the new Admin Tool.  A few I'll briefly mention here include:

    1) You can now use the admin tool to create and manage any number of sites on a Windows Client machine.  You are no longer limited to a single site (note the three I've created above).  Likewise, there is no longer a 10 connection limit.

    2) We've integrated the IIS and ASP.NET administration settings into a single admin tool.  So you can now view and set authentication and authorization rules in 1 place instead of multiple different dialogs.  This provides a much more consistent and clearer UI for admins, and a unified administration story for the web platform.

    3) The admin tool uses the new distributed web.config configuration system.  IIS7 no longer has a single metabase configuration store, and instead uses the same web.config file model that ASP.NET supports to enable configuration settings to be stored and deployed with application content (meaning you can xcopy or FTP your settings with your application to your remote server - no need to write admin scripts to custom configure things anymore). 

    4) The admin tool supports "delegated administration", which means hosting providers can enable customers to use the admin tool to remotely manage their shared hosting sites (in which case the admin tool obviously only shows the settings specific to the individual customer -- and not for the entire box).  We use HTTP based web-services internally to also support connections across firewalls (unlike the old IIS admin tool which uses DCOM which was often blocked).

    5) The admin tool is written using .NET and Windows Forms, and is extensible.  This means you can add custom UI modules into the admin tool to provide administration support for your own HTTP runtime modules and configuration settings.

    6) The admin tool provides built-in admin UI support for the ASP.NET 2.0 Membership and Role Management systems.  This means you can create and manage roles, users, and map users to roles all within the admin tool.  This will work against any Membership and Role Provider you build for ASP.NET 2.0 -- just implement the standard ASP.NET 2.0 Provider Contracts and you now have full admin UI support for them (even remotely in shared host environments!). 

    For example, I could click on the .NET Roles icon above to create and manage the roles specific to my "SampleSite":

    And then I could click on the .NET Users icon to create and manage my users, and map them into whatever roles I want for my application:

    There are a ton of other goodies in IIS 7.0 we'll be blogging about in the future.  Visit the www.iis.net site and/or subscribe to its RSS feed to learn more today.

    Hope this helps,

    Scott

    Share this post: Email it! | bookmark it! | digg it! | reddit!
  • XGL on Ubuntu vs Aero on Vista

    Which one of these videos blows you away?

    XGL or Aero.

    Are there any impressive Aero videos out there?

    -James

  • More on Atlas

    Yesterday I wrote one of those blog posts that I almost deleted instead of posting, but just decided to go ahead and post anyway. After reading through it today and all of the comments here are some more thoughts.

    As a number of people have pointed out, Atlas is just a CTP and I am probably expecting way too much from it. I think my expectations were inflated by a number of people telling me how they are using it on their current project and the fact that there is a go-live license. I will reserve judgment on Atlas until it is officially released, I can admit there has been a great deal of improvement since the first time I used it (wow, almost a year ago now).

    Secondly, Brian Madsen was wondering why on earth I was using a CTP release in a production environment. Basically we are just trying out Atlas on a small number of pages in the application, removing Atlas will probably take less than a day. Whenever I use a beta, alpha, or CTP release I always do so with caution. Atlas is not a central part of the application and prototyping it out on a small number of pages did not introduce any un-reasonable risk to the project considering we are still four months away from production.

    Lastly, ScottGu wondered what the precise issues I was having were and what I did to try and resolve them. Most of the issues we found were either acknowledged bugs or were things we ended up writing custom javascript to get around. Here is a sampling of some of what we encountered:

    • State Information has been corrupted errors (in IE)
    • If you include an UpdatePanel with a ComponentArt grid the callbacks from the grid don’t work anymore. (I haven’t tracked this one down yet)
    • The AutoCompleteExtender has a frustrating limitation of a hard-set signature. It has to be (string prefixText, int count). In our application we also needed to pass along the selected value of another dropdown. (a good example would be you want to select a car manufacturer and then limit the results returned to cars under that manufacturer) In this case we basically had to re-implement using our own solution.
    • You can’t set the focus to the autocomplete textbox when the page loads. (also haven’t had time to track down the cause of this)
    • Runtime errors with autocompletes and update panels (workaround here)

    Based on the issues we have had we are going to switch over to another solution for this project, but I will definitely re-evaluate Atlas when it is released.

    -James

  • IronPython 1.0 Released

    I'm really excited to announce that today we released V1.0 of the IronPython project for .NET.  Click here to download the binaries, source code, and tutorials for it for free from CodePlex.

    IronPython is an implementation of the Python programming language for .NET.  It supports an interactive console with full dynamic compilation support and makes all .NET libraries easily available to Python programmers -- while still maintaining full compatibility with the Python language.

    IronPython provides a great example of how languages can leverage some of the new dynamic language features that we added into the CLR with last year's .NET 2.0 release.  For example, CLR features like "lightweight code-generation" now make it possible for a dynamic language to quickly compile and JIT source in-memory, but also have the ability to garbage collect it out later (meaning you can quickly adapt types on the fly and not have to leak generated code). 

    IronPython is also a good example of how we are looking to blend the benefits of dynamic languages with a rich class framework and execution environment like .NET together.  Jim Hugunin (the lead architect for IronPython at Microsoft) recently did a great videocast with Jon Udell where he demonstrates a bunch of cool code scenarios that really show this off.  His demos included building a calculator application written in Python that uses WPF (aka Avalon) and integrates with the Speech APIs.  He also showed how you can optionally refactor performance critical code from Python into strongly typed languages like C# and seamlessly work across the two.  You can watch his full video-cast by clicking on the screen-capture below:

    Going forward, you are going to see even more dynamic languages appear on .NET, and a bunch of cool new scenarios become enabled. 

    Hope this helps,

    Scott

    Share this post: Email it! | bookmark it! | digg it! | reddit!
  • Atlas is weighing on me

    I made the decision to use Atlas on our project, despite some earlier doubts, and I am paying for it now. So far it has been nothing but trouble. We have run into multiple bugs, strange behavior, and conflicts with our existing ComponentArt controls. I think what bothers me most is that unlike some of the simple or open-source solutions I don’t even know where to start with tracking down or fixing these bugs. At the moment we are having to work around these issues by doing things like turning off viewstate validation or turning off debugging in the config file or all kinds of ugly work-arounds.

    Another thing that bugs me is that Atlas seems exceedingly fragile. For instance, when creating an autocomplete textbox you have to be sure and name the parameters in your service the exact right thing. What if you need to pass an extra parameter along? Too bad, you have to hack it using something like querystring. It’s stuff like this that re-enforces my belief that the only proper way to build a good framework is by extracting it from an application. If you built a real application you would realize that you will need to pass in additional parameters for an autocomplete textbox.

    Right now I am trying to decide if I should cut and run and retrofit our app using Ajax.Net Professional before it’s too late or hope that the next version of Atlas is better.

    -James

  • Tip/Trick: Creating Re-Usable Project and Item Templates with VS 2005

    Typically when you work on projects you have a standard approach that you like to use to structure and organize your code (folder layout, default namespaces included, assembly references included by default, standard CSS stylesheets included, etc).  This is often the first thing developers setup and do when they first start a new project.

    One nice feature that is new in both VS 2005 and Visual Web Developer is the ability to easily create both "Project Templates" and "Item Templates" that allow you to capture your personal coding preferences and default project items and encapsulate them in re-usable templates that you can quickly use when starting a new project or adding a new item to it.  This can both save you a lot of manual time, as well as ensure on new projects that everything is setup exactly the way you like them.

    "Project Templates" allow you to specify the initial set of files (and their layout and content), assembly references, and other preferences when you create a new project (you'll see these listed in the "My Templates" section of your "Create New Project" or "Create New WebSite" dialog box).  "Item Templates" allow you to create a customized template that you add new files to a project (you'll see these listed in the "My Templates" section of your "Add New Item" dialog box):

    You can name each project and item template using a descriptive name, and have any number of them that you want in VS 2005.  You can also use built-in macro replacement tokens to customize things like names, namespaces, paths, date/times, etc.  You can also easily publish them and share them with others -- allowing you to easily distribute them across a team or your own community of friends.

    To learn how to-do this, check out this blog post that I wrote a year ago on how to create a re-usable Item Template for Web Site items.

    Ameet Phadnis has recently published an even better article on ASPAlliance.com that goes into more detail on how you can create and customize both Item and Project Templates.  You can read his article here.

    Hope this helps,

    Scott

    Share this post: Email it! | bookmark it! | digg it! | reddit!
  • Books: Bryson's Dictionary of Troublesome Words: A Writer's Guide to Getting It Right by Bill Bryson

    While writing my latest book I realized that I want my next writing project to be a non-technical non-fiction or fiction book. I enjoy writing technical books and articles, but I am ready to try and challenge myself in a different way. The problem is that I haven’t done much non-technical writing since high school and college, so I decided to do my research and pick up a couple books to work on my writing skills.

    One of the books I picked up was this Dictionary of Troublesome Words by Bill Bryson. This book is an incredibly useful reference to common words and phrases that people get wrong, often quoting mistakes in well-known newspapers. For example:

    conceived “Last week, twenty-five years after it was first conceived…” (Time). Delete first. Something can be conceived only once. Similarly with “initially conceived” and “originally conceived.”

    After reading the book I spot common mistakes like this all over the place. I even found out that I have mis-used one of my favorite words in the past (plethora should only be used to represent an absurd amount, not just a lot). This book should be required reading for anyone who cares about using words correctly in their emails, blogs, books, etc.

    -James

     

     

  • Upgrade Complete

    This blog, as well as better in a song, is now running SubText 1.9. I continue to be impressed with how easy it is to upgrade and use. Check out one of the new skins over on betterinasong.com.

    -James

  • Writing Custom Web Parts for SharePoint 2007

    Sahil Malik recently published a nice article that covers how to write a custom web part using ASP.NET 2.0 and host it within SharePoint 2007.

    As I mentioned in an earlier blog post, SharePoint 2007 is built on top of ASP.NET 2.0, which means you can now use ASP.NET 2.0 features (Forms Authentication, Master Pages, Membership, Site Navigation, New Data Controls, etc) when building SharePoint sites.  This is true for both the new Windows SharePoint Services 3.0 version (which will be a free download) as well as Microsoft Office SharePoint Server 2007 (which costs money).

    One of the cool developer scenarios is the ability to create your own Web Part controls that can be used in both SharePoint sites, as well as regular vanilla ASP.NET 2.0 applications.  This allows you to re-use all of the built-in SharePoint features for collaboration, document sharing, and content management - while also adding your own custom UI and behaviors (for example: if you want to integrate custom data editing and reporting to a site).

    Sahil's article above describes how to create a Web Part control as a compiled custom control.  You can also now build Web Parts using ASP.NET User Controls (.ascx files) -- which makes composing and encapsulating UI functionality even easier.  Several people asked in follow-up comments to my previous post whether it will be possible to host Web Parts built as ASP.NET 2.0 User Controls within SharePoint 2007.  I checked with the SharePoint team, and they told me that this will be a supported scenario via an additional component you add to SharePoint -- and that they'll have a whitepaper and sample on how to-do this published later this year.

    This Channel9 video of the SharePoint team provides more information about some of the cool new features in SharePoint 2007 (including its new Wiki feature support).  Mark Kruger also has a great list of SharePoint posts summarized here.  Sahil has a number of nice posts below that talk more about some of its customization/development scenarios that you might want to check out as well:

    Fritz Onion wrote a great article last month that talks about how you can use the new Asynchronous features within ASP.NET to perform efficient network calls within a Web Part control without blocking the processing request thread.  This allows you to perform multiple network requests at the same time from different web parts and render the page much faster and more efficiently. 

    Hope this helps,

    Scott

    Share this post: Email it! | bookmark it! | digg it! | reddit!
  • Understanding LINQ to SQL Query Translations

    I posted two blog posts last weekend about using LINQ to easily perform data access against a database.  Several people have asked me for more details on LINQ to SQL since then.

    Sahil Malik made some excellent posts earlier this summer that go into more detail about LINQ to SQL (aka DLINQ) and how it works.  You can read his posts here:

    Bill Wagner has also recently made several great posts that go into more detail about how LINQ queries are translated and executed as SQL.  You can read his posts here:

    As I talked about in this recent blog post, one of the really cool things about LINQ is that you can always hover over a LINQ query while in the debugger to drill in and see the underlying SQL query that is ultimately executed:

    You can then expand the debug visualizer to both see and execute the underlying SQL query while in the debugger:

    This provides a really cool way to see what is happening under the covers and to easily experiment and adapt your queries however you want. 

    Hope this helps,

    Scott

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

This Blog

Syndication

Powered by Community Server, by Telligent Systems
'