I recently grabbed the ASP.NET Personal Web Site Starter Kit that we wrote for VS2005\.NET Framework 2.0 and opened it up in VS2008 to see how the new tool and platform could help. 

It was fun and painless to Ajax Enable the site with the new features in ASP.NET 3.5 and VS2008.  Here is a run down of a improvements I have made.

Download the full source code for this project

 

 

VS2008 Can Target .NET Framework 2.0

First, I opened up the project in VS2008, but did not upgrade to .NET Framework 3.5.  This is a HUGE feature for VS2008... It means that you can move to the latest and greats dev tool WITHOUT requiring the whole team to move or change all your servers over. 

In VS2005, I spent most of my time in markup view... while I love the full control of that environment, I do miss seeing immediately what I get. In VS2008, we added split view, which enables you to edit in markup and see the code right away (or vice-versa). 

image

I also love the new CSS code editor.. this is where intelllense really saves you... VS knows all the appropriate CSS properties and what their arguments are.  The CSS Manager is also a great tool for visually adding new styles to your CSS. 

image image

 

Upgrade to ASP.NET 3.5 and Take Advantage of Linq

Next, I upgraded the project to .NET Framework 3.5... This was very easy to do.  Right click on the project, select properties, then build.

image

This upgrades all my framework references and gives me some new power. Not the least of which is the new Linq support that changes the way you work with data..

With full statement completion, this code is a breeze to write... Can imagine writing it in TSQL in an unverifiable string within your application?  Linq makes this very easy to write and read later!

GridView3.DataSource = fromlocation intravel.PlacesVisited
                       wherelocation.Distance > 1000
                       orderby location.Country, location.City
                       selectlocation;
GridView3.DataBind();

TravelOrganizer travelSkipTake = newTravelOrganizer();
GridView4.DataSource = (fromlocation intravelSkipTake.PlacesVisited
                        orderby location.Distance descending
                        select
location).Skip(1).Take(5);
GridView4.DataBind();

// Calculate farthest city away
LocationfarthestCity = (fromlocation intravel.PlacesVisited
                         orderby location.Distance descending
                         select
location).First();

MaxCityNameTxt.Text = farthestCity.City;
MaxCityDistanceTxt.Text = "("+ farthestCity.Distance + " miles)";

// Calculate total city distances of all cities inside US
int totalDistance = (fromlocation intravel.PlacesVisited
                     wherelocation.Country == "USA"
                   
selectlocation).Sum(loc => loc.Distance);
TotalDistanceTxt.Text = totalDistance + " miles";

// Calculate average city distances of each city trip
doubleaverageDistance = travel.PlacesVisited.Average(loc => loc.Distance);
AverageDistanceTxt.Text = averageDistance + " miles";

Ajax Enabling the Site

Next, I picked a few parts of the site to improve with some of the new Ajax support in ASP.NET 3.5.   

First I noticed that in the slideshow, the full page refreshed every time the slide changed.  This is distracting and annoying to many users.  Luckily I didn't have to re-implement the while slide show in client side JavaScript to fix this. I simply wrapped the existing controls in an UpdatePanel and the blink went away! 

1: <asp:UpdatePanel runat="server" ID="updatepanel">
2:  <ContentTemplate>
4:
5:        <asp:formview id="FormView1" runat="server"    datasourceid="ObjectDataSource1" cssclass="view"
6:            borderstyle="none" borderwidth="0" CellPadding="0" cellspacing="0" EnableViewState="false" AllowPaging="true">
7:           <itemtemplate>
8: <%-- deleted to save space --%>
9:            </itemtemplate>
10:        </asp:formview>

11: </ContentTemplate>
12: </asp:UpdatePanel>

I simply added lines 1 and 2 and 11 and 12... Nothing in else needed to change!

Next, I wanted to give users an immediate response when they clicked to advance the slide show.  Even if there were network delays or server load issues, I wanted users to know that the app was responsive.    So I added an UpdateProgress control with an animated gif (notice there are a TON of these on the web).  The UpdateProgress pops up whenever the UpdatePanel calls back to the server and automatically closes down as soon as the request comes back.   Again, very easy to do, with no client side javascript code.

        <asp:UpdateProgress ID="UpdateProgress1" runat="server">
            <ProgressTemplate>
                <div id="box">
                    <img id="Img1" runat="server" alt="Loading" src="~/Images/ajax-loader.gif" /></div>
            </ProgressTemplate>
        </asp:UpdateProgress>

The result is that as soon as a user hit's next,  this "waiting" icon shows up and it automatically goes away when the image comes in.

image

Next, I wanted to see what I could do with a bit more client side JavaScript code.   Not only does VS have client side JavaScript intellisense..

image

It also has type inferencing which means that VS is able to keep up with what the type of your dynamically variables are by running a javascript compiler in the background while you type!  As you can see from this example, if I change the value in myElement to be a string, VS keeps up with that change and completes it for me.

image

I was also able to set a breakpoint in the javascript code and debug into it from within IE..

image

And all the full magic of VS's debugging support works perfectly.. Stepping, immediate window, watch, etc.

Notice, you do have to have JavaScript debugging enabled in IE, VS detects if you don't and tells you how to turn it on. 

image

 

Ok, next I wanted to move some data between the server and the client.   To do that I created a Ajax-enabled WCF based web service.

image

 

The implementation of the service can be any .NET code taking full advantage of .NET on the server and using all strongly typed .NET objects as parameters and return type.  Then ASP.NET 3.5 turns it into standards base JSON for communication over x=XmlHttp and evaluation on the client in. 

I simply add the service as a reference in my ScriptManager instance on this page

    <asp:ScriptManager runat="server" ID="sm">
        <Services>
            <asp:ServiceReference Path="~/TopCitiesService.svc" />
        </Services>
    </asp:ScriptManager>

Then I get intellsense to call the instance from the client.

image

Then I simply pass a callback per the async nature of javascript and I am done!

<script language="javascript" type="text/javascript">
    function doSomething() {
        var myElement = document.getElementById("myid");
               
        myElement.innerHTML = "....Accessing...";
        TopCitiesService.GetTopCities(setCities);
        
        }
       function setCities (city) {
         var myElement = document.getElementById("myid");
         myElement.innerHTML = city;
        }

</script>

 

Tricking out the site with the Ajax Control Toolkit

I then had a little fun with the Ajax Control Toolkit

First, in default.aspx, I changed the inline image to be a popup using the ModalPopupExtender

image

    <asp:Panel ID="Panel1" runat="server" BackColor="White" Style="display: none" Width="500px">
        <p>
            <asp:Image ID="Image2" runat="server" ImageUrl="~/Images/IntelliSense.jpg" /></p>
        <div align="center">
            <p>
                <asp:Button ID="ButtonClose" runat="server" Text="Close" /></p>
        </div>
    </asp:Panel>
    <cc1:ModalPopupExtender ID="ModalPopupExtender1" 
        runat="server" OkControlID="ButtonClose"
        PopupControlID="Panel1" TargetControlID="LinkButton1">
    </cc1:ModalPopupExtender>

 

Next, in Admin/Albums.aspx i changed the validator on the title control to be more Ajax-like by using a pop-up via the ValidatorCalloutExtender.

image

    <asp:RequiredFieldValidator    ID="RequiredFieldValidator1"
     Runat="server" 
     ErrorMessage="You must choose a    title." 
     ControlToValidate="TextBox1" 
     Display="None"
     Enabled="true"
      />

    <cc1:ValidatorCalloutExtender
     ID="ValidatorCalloutExtender1"
      runat="server" 
      TargetControlID="RequiredFieldValidator1">
    </cc1:ValidatorCalloutExtender>

 

Next, to Admin/Photos.aspx I added ConfirmButtonExtender  to ensure that users really, really wanted to delete the photo. 

 

image

        <cc1:ConfirmButtonExtender ID="ConfirmButtonExtender1" 
            runat="server" ConfirmText="Are you sure you want delete?"
            TargetControlID="ImageButton3">
        </cc1:ConfirmButtonExtender>

 

Finally, to register.aspx I wanted to help users pick a strong password and give them a hint as to what to use for the security question.  I did this with the PasswordStrength and TextBoxWatermarkExtender

image

 

    <cc1:PasswordStrength 
        ID="Password_PasswordStrength"
         runat="server" Enabled="True"
        TargetControlID="Password">
    </cc1:PasswordStrength>
    <cc1:TextBoxWatermarkExtender 
        ID="Question_TextBoxWatermarkExtender"
        runat="server"
        Enabled="True" TargetControlID="Question" 
        WatermarkCssClass="watermarked" 
        WatermarkText="example: pet's name, etc">
    </cc1:TextBoxWatermarkExtender>

 

Well, there is certainly more we could do with the starter kit, but this is all I had time for... I'd love to hear your other ideas or see the ways you have Ajax enabled other starter kits.