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).
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.
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.
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
TravelOrganizer travelSkipTake = newTravelOrganizer();
GridView4.DataSource = (fromlocation intravelSkipTake.PlacesVisited
orderby location.Distance descending
// Calculate farthest city away
LocationfarthestCity = (fromlocation intravel.PlacesVisited
orderby location.Distance descending
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.
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!
<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.
And all the full magic of VS’s debugging support works perfectly.. Stepping, immediate window, watch, etc.
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.
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.
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
<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.
<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.
<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.
<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.