First of all it's worth mentioning that Microsoft brought enhancements to the ASP.NET AJAX Extensions. Now we can use a History control which allows us to use the back button to navigate back to a state before the last async postback happened.
Then there is Dynamic Data which is a framework that discoveres the data model and determines the UI which is best suited, dynamically, during runtime. This sounds weird but it can be of big help! Ex: When you try to display a DateTime value in a GridView, you can use a <asp:DynamicField ... /> which will automatically print your DateTime value nicely formatted. To achieve this with the Normal <asp:BoundField ... /> you needed to set HtmlEncode="false" and DataFormatString="{0:D}". If your DataField is a simple string, this will render a LiteralControl. Not only do these work in Read-Only mode, this also happens in Edit mode which can big of big help.
For those who are bored with HttpContext.RewritePath(), and for those who are tired of using the regular expression based configuration of most URLRewriting modules ... there is good news for you! ASP.NET 3.5 SP1 introduces: URL Routing. In URL routing, you define URL patterns that contain placeholders for values that are used when you handle URL requests. At run time, the pieces of the URL that follow the application name are parsed into discrete values, based on a URL pattern that you have defined.
But now ... the piece de la resistance ...
Ladies and Gentleman, would you please welcome the new ADO.NET Data Platform.
One thing was desperately missing from ADO.NET. Working directly against a Relational Storage Schema (in english: the Typed DataSets) is fun, but it can be very difficult to maintain. Once a database schema changes a little bit, chances are that the change on the application part will be substantial, and once again, very difficult to maintain!
As a solution this sounds probably familiar to those who have heard about ORM. But for all those who didn't have anything in common with ORM, well here's a short intro!
ORM - Object Relation Mapping, The problem is that data in the database is very difficult and time consuming to present to the application in a logic manner! The aim is to create a virtual object database, each object representing a relation in your database tables! Ex: a row in the table Customer would correspond to an object Customer in your application; in the same way the tables: Order and OrderProducts; an object Order which contains a List<OrderProducts> would model this situation well!
There are a bunch of products available on the market some free others not, but to get an idea here are some examples: NHibernate, LLBLGen Pro, EntitySpaces, OPF.NET, etc.
Now, to ADO.NET Entity Framework, a part of the ADO.NET Data Platform. It generates the underlying conceptual object model from a database, which you can program against. This way you have access to data from an Object level! Why this is good? It scales well, it's easy to maintain, and most importantly it's very quick to program against.
Microsoft also provides LINQ to Entities. If anybody has used LINQ queries agains simple collections, well you can use LINQ to query Entities:
EDMEntities entities = new EDMEntities();
IQueryable<Companies> query = from c in entities.Companies
where c.aspnet_Users.UserId == UserId
select c;
//query.Count() now contains the number of Companies owned by a User
The .NET Framework 3.5 SP1 brings allot of nice enhancement, and gladly not only for the web developer!