Scott Hanselman

ASP 4 - Whirlwind Tour around .NET 4 (and Visual Studio 2010) Beta 1

May 19, '09 Comments [14] Posted in ASP.NET | ASP.NET Dynamic Data | ASP.NET MVC | TechEd
Sponsored By

Hey, we released Visual Studio 2010 Beta 1. JasonZ has a great post with piles of details and a metric crapload of screenshots. Definitely take a moment (or eight) and check out his very detailed post. You can get it NOW if you're an MSDN Subscriber, or after the general announcement on Weds if you're not.

UPDATE: My bad, of course it's called ASP.NET 4 and not ASP 4. Sorry, typo.

Should You Freak Out?

I don't think so. There's a lot of stuff that's new and added in .NET 4, but not in that "overwhelming-I-need-to-relearn-everything" way. More in that, "oh, this is way easier/simpler now" way. Like, moving data around with ADO.NET DataServices is easy, binding with client templates is easy, there's F# if you need it, the "dynamic" keyword if you need it, Silverlight's already installed, oh, and the parallel stuff will freak you out, but in a good way.

I'll do a series of posts on what I think is cool with lots of details. I'll put code samples up also as I can. I will also point out where you can already do much of this with 3.5 SP1, as well.

Here's a general outline of a small part of the goodness:

  • New Shell, new File|New, new Extensions Manager
  • Lots of focus on "Code First" (TDD-friendly, etc)
  • Office and COM Interop that is actually fun to do.
  • Automatic Properties for VB, no more "_" for multi-line, inline subs, collection initializers
  • C# gets the dynamic keyword
  • F# is included out of the box
  • WPF Databinding in the Designer
  • Silverlight included out of the box
  • Piles of HTML Snippets for non-designer people
  • Better JavaScript Intellisense
  • MSBuild for C++
  • UML for VS Team Architecture
  • TFS Branch and Changeset visualizers
  • Parallel computing
  • Workflow speedup, new designer
  • SharePoint tooling

Rather than try to top Jason with a laundry list of what's new and what not, here's some details on a few things that I find particularly interesting. They may be obscure to you, and perhaps not deeply interesting, but they were interesting enough to me that I used them for demos at TechEd last week (with a hat tip to Jonathan Carter and Jason Olson).

This is just a smattering of the features (hence: "Whirlwind" although "totally random cool stuff" would have also worked) coming in .NET 4. These are features I'm interested in because they've solved problems I've had in the past.

I'm realizing I'll definitely do these as separate posts because they're going to get long. First, ASP.NET and Ajax.

ASP.NET 4

There is an excellent whitepaper at http://www.asp.net/learn/whitepapers/aspnet40/ with a lot of detail on the changes in ASP.NET 4.

There's lots new in ASP.NET 4, but at TechEd09 I showed two. First was control over my controls' client ids. Rather than getting a generated ID like ctl09_list45_whatever99, I can make my control ids more predictable.

More Control over ClientIDs in WebForms

For example, here's a ListView (ol/li) of Television shows. It uses jQuery to be sortable. Notice the new attributes in asp:ListView, specifically ClientIDRowSuffix and ClientIDMode.

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Television Series Picker</title>
<link href="Default.css" rel="stylesheet" type="text/css" />
<script src="jquery-1.3.2.min.js" type="text/javascript"></script>
<script src="ui.core.js" type="text/javascript"></script>
<script src="ui.sortable.js" type="text/javascript"></script>
<script type="text/javascript">

$(document).ready(function() {
$("#televisionList li").append("<div><span>Click</span></div>");
$("#televisionList").sortable({ handle: $("#televisionList li div") });
});
</script>
</head>
<body>
<form runat="server">
<h1>Television Series Picker</h1>
<p>Order the following television series' based on which you think is most awesome:</p>
<asp:ListView
DataSourceID="televisionDataSource"
ClientIDRowSuffix="ID"
ClientIDMode="Predictable"
runat="server">
<LayoutTemplate>
<ol id="televisionList">
<asp:PlaceHolder ID="itemPlaceHolder" runat="server" />
</ol>
</LayoutTemplate>
<ItemTemplate>
<li id="televisionItem" runat="server">
<%# Eval("Name") %>
</li>
</ItemTemplate>
</asp:ListView>
<asp:ObjectDataSource
ID="televisionDataSource"
TypeName="_01_ClientId.TelevisionDataProvider"
SelectMethod="GetTelevisionSeries"
runat="server" />
</form>
</body>
</html>

The list is populated using an ObjectDataSource and I want the client id's to be created with a suffix using the ID property from the Television object.

Routing and WebForms

You probably know that System.Web.Routing is a big part of ASP.NET MVC, and you may know it's in .NET 3.5 SP1 as well. In .NET 4 it'll be even more easy to use with better support for WebForms. For example:

public class Global : System.Web.HttpApplication
{
protected void Application_Start(object sender, EventArgs e)
{
RouteTable.Routes.Add("Product",
new Route("Products/{category}",
new PageRouteHandler("~/Products.aspx")));
}
}

Here I'm setting update a route such that /Products/SomeCategory routes to the /Products.aspx WebForms Page. The Category parameter is a RouteParameter and can be retrieved (of course) and used. System.Web.UI.Page has a RouteData parameter now, or you can refer to RouteValues in your ASPX markup. For example:

<p>The following are all the products within this category:</p>
<h2><asp:Literal Text="<%$ RouteValue:Category %>" runat="server" /></h2>

or into a Data Source via <RouteParameter>:

<asp:EntityDataSource
ID="productsDataSource"
ContextTypeName="AdventureWorksLTEntities"
EntitySetName="Products"
OrderBy="it.Name"
Where="it.Category.Name = @Category"
runat="server">
<WhereParameters>
<asp:RouteParameter
Name="Category"
RouteKey="Category"
Type="String" />
</WhereParameters>
</asp:EntityDataSource>

There will also be Routing Extension Methods like GetUrlForRoute or the like, in Beta 2, as well as IgnoreRoute. Basically anything that makes it simple, simple, simple to use Routes with WebForms. This'll be nice for hybrid WebForms/MVC apps as well.

Ajax 4

The Client Templates stuff in Ajax 4 is pretty sweet. This allows for 2-way data-binding using only JavaScript. For example, this template pulls from a JSON DataService at customers.svc. The JavaScript is below. We create a DataContext pointing to that endpoint, two DataViews that take the "customers-template" and "customer-template" HTML elements and creates a binding between them.

Sys.Application.add_init(function()
{
var dataContext = $create(Sys.Data.AdoNetDataContext,
{
serviceUri: "Customers.svc"
});

var customersTemplate = $create(Sys.UI.DataView,
{
dataProvider: dataContext,
fetchOperation: "Customers",
fetchParameters: { $top: 20, $orderby: "FirstName", $expand: "Orders" },
initialSelectedIndex: 0,
selectedItemClass: "selected"
},
null, null,
$get("customers-template"));

var customerTemplate = $create(Sys.UI.DataView,
null, null, null,
$get("customer-template"));

// This imperatively creates the binding
// between the customer grid and the customer
// detail form. When you select a record in
// the grid, it will automatically re-bind
// the detail view as well.
$create(Sys.Binding,
{
defaultValue: null,
source: customersTemplate,
path: "selectedData",
target: customerTemplate,
targetProperty: "data"
});

// This uses jQuery live event bindings to hook up
// the click event for the update button that will be
// "generated" when the customer detail form is bound.
$("#update-button").live("click", function()
{
dataContext.saveChanges();
});
});

Then we use jQuery live events, and then save the changes back to the dataContext. The changes that are made on the client side are tracked automatically, and those changes are sent back via JSON and commited. Note the source: and target: in the $create() call above that sets the master/detail relationship between customers and customer (singular.)

The client-side templates are similar to the server-side templates you probably already know how to use. You can even use expressions like to conditionally apply CSS.

image

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>AdventureWorks AJAX</title>
<link href="Content/Styles/reset-min.css" rel="stylesheet" type="text/css" />
<link href="Content/Styles/Default.css" rel="stylesheet" type="text/css" />

<script src="Content/Scripts/MicrosoftAjax.debug.js" type="text/javascript"></script>
<script src="Content/Scripts/MicrosoftAjaxTemplates.debug.js" type="text/javascript"></script>
<script src="Content/Scripts/MicrosoftAjaxAdoNet.debug.js" type="text/javascript"></script>
<script src="Content/Scripts/jquery-1.3.2.min.js" type="text/javascript"></script>

<script src="Content/Scripts/Default.js" type="text/javascript"></script>
</head>
<body
xmlns:sys="javascript:Sys"
xmlns:class="http://schemas.microsoft.com/aspnet/class">
<h1>Customer Directory</h1>
<table cellspacing="0">
<thead>
<tr>
<th>Title</th>
<th>First Name</th>
<th>Middle Name</th>
<th>Last Name</th>
<th>Suffix</th>
</tr>
</thead>
<tbody id="customers-template" class="sys-template">
<tr sys:command="select" class:odd="{{ $index % 2 != 0 }}">
<td>{binding Title, defaultValue=}</td>
<td>{binding FirstName}</td>
<td>{binding MiddleName, defaultValue=}</td>
<td>{binding LastName}</td>
<td>{binding Suffix, defaultValue=}</td>
</tr>
</tbody>
</table>
<fieldset id="customer-template" class="sys-template">
<legend>{{ FirstName + " " + LastName }}</legend>
<label for="first-name">
<span>First Name:</span>
<input type="text" id="first-name" value="{binding FirstName}" />
</label>
<label for="middle-name">
<span>Middle Name:</span>
<input type="text" id="middle-name" value="{binding MiddleName, defaultValue=}" />
</label>
<label for="last-name">
<span>Last Name:</span>
<input type="text" id="last-name" value="{binding LastName}" />
</label>
<input id="update-button" type="button" value="Update" />
</fieldset>
</body>
</html>

This exact scenario can also be done declaratively with you having to write ANY JavaScript at all. The "declarations" from the JavaScript file above are replaced with declarative namespace statements like:

<fieldset
class="sys-template"
sys:attach="dataview"
dataview:data="{binding selectedData, source={{customersTemplate}}}"
dataview:sys-key="customerTemplate">
<legend>{{ FirstName + " " + LastName }}</legend>
...

And the result is the same as above:

image

It's important to point out that while you can go get the VS 2010 Beta 1, you can also play with this stuff TODAY running on .NET 3.5 SP1. Go over to the ASP.NET 4 Ajax Preview site on CodePlex.

Also, don't freak out that ASP.NET MVC isn't baked into VS2010 Beta 1. Phil explains here.

Related Links

Have fun!

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. I am a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by ORCS Web
Tuesday, May 19, 2009 11:20:03 PM UTC
Silverlight is included by default but doesn't work unless you install the Developer Runtime and SDK manually. I am sure they'll fix it though.
Wednesday, May 20, 2009 1:50:40 AM UTC
Mentioned it many times before... But unless you're ready to serve xml-compliant data, xml namespaces should never be used. Xhtml by default is not freely extensible either and as such the doctype is not compliant. What you have is xhtml+ms extensions served as text/html.

I am at loss to understand how anyone thought this would be a good idea.

See the very long discussion about aria on TAG and the various issues that browsers have with namespaces when using non-xml parsers and differences when serving as xhtml+xml and as text/html.

This is a minefiled, and certainly not one ms should've gone ahead with IMO.

Wednesday, May 20, 2009 3:20:01 AM UTC
@serialseb: I thought XHTML was a browser issue, not a server issue? I'm pretty sure ASP is XHTML capable.
Wednesday, May 20, 2009 3:54:39 AM UTC
@serialseb
> "Xhtml by default is not freely extensible"
"Document developers and user agent designers are constantly discovering new ways to express their ideas through new markup. In XML, it is relatively easy to introduce new elements or additional element attributes. The XHTML family is designed to accommodate these extensions [...]" (from the XHTML 1 spec)

> "unless you're ready to serve xml-compliant data, xml namespaces should never be used"
We're perfectly ready to serve xml-compliant data. It's IE that's not ready to accept it. From W3C again: "If the Accept header explicitly contains text/html [...] deliver the document using that media type." and "The combination of elements and attributes from various grammars via the XML Namespace mechanism results in a compound document. XHTML-family markup languages can be used in these documents." and also "the approach defined here permits the definition of markup languages that are XML and XML namespaces conforming"

> "What you have is xhtml+ms extensions served as text/html"
What we have is legal XML extensions from Microsoft. The document as a whole is legal XML and yes, we serve it as text/html. We could serve it with an xml content type if IE understood that but unfortunately the reality is that today it doesn't.
We are being pragmatic here and are trying to stay true to the spirit of XHTML (the X still stands for extensible) while enabling some form of validation. Namespaces are used so that we don't step on other extensions' feet which is again why they were invented. Finally, as Scott shows, none of this is mandatory. You can perfectly use all features in Microsoft Ajax from pure JavaScript, without having to use the markup extensions if you find them objectionable. So let me ask you, what is the right way of doing declarative instantiation of components over HTML?

I really wish we could concentrate on the fantastic features in Microsoft Ajax 4 instead of discussing dogma.
Wednesday, May 20, 2009 8:15:49 AM UTC
@Bertrand
There are lots of developers concentrating on these fantastic features. Unfortunately it seems it is only the whiners that get heard! Keep up the good work and please remember to try and answer our preview-related questions - it is sometimes difficult to evaluate these brand new technologies because the documentation is (understandably) lacking.
Matt
Wednesday, May 20, 2009 1:46:17 PM UTC
Very exciting features.
Abdalaziz
Wednesday, May 20, 2009 2:46:51 PM UTC
Ahhh I'm pretty excited to check out the webforms routing stuff. I just finished a 4 month mvc/webfrom hybrid application that would have benefited from these changes. Does anyone else have any examples of MVC/Webform hybrid applications they've launched???
Thursday, May 21, 2009 9:02:46 PM UTC
Oh please, don't call it ASP! (in your headline) I always have to explain the difference between ASP (which is, believe it or not, alive in developers daily routine) and ASP.NET to new developers, because it's really confusing them. So we should keep it clear by naming it correctly.

Thanks, Thomas ;-)
Thomas
Thursday, May 21, 2009 9:23:38 PM UTC
Ooops! Yes, it's ASP.NET 4. My bad.
Sunday, May 24, 2009 11:08:05 PM UTC
"We're perfectly ready to serve xml-compliant data. It's IE that's not ready to accept it"

Unfortunately we are developing for the IE browsers that currently exist not what we hope will be there in the years to come. I can use content negotiation to send xhtml to browsers that accept xml content and html to browsers that don't (IE that is). Many people would argue that xhtml served as text/html is simply not xhtml - http://www.sitepoint.com/forums/showthread.php?t=393445 - and I tend to agree. We all love the rules of xhtml (don't devs just love structure) and I think it clouds thinking sometimes. As things stand we have a proliferation of web pages out there with an xhtml transitional doctype transitioning to nothing and probably created yesterday not created as part of a temporary transition from html to xhtml strict. People have lost their way with xhtml.

Forgive my ignorance but what is wrong with using a class declaration to define the behaviour of an element - class="sys-template attach-dataview" for example?

"I really wish we could concentrate on the fantastic features in Microsoft Ajax 4 instead of discussing dogma."

Theres a certain dogma in asking people not to criticise. Should it simply be a love-in? Nothing wrong with constructive criticism.


Friday, June 12, 2009 1:40:15 PM UTC
I won't respond to the dogma, it's fairly irrelevant to the discussion.

Fact: Xhtml schema as it stands does not allow xml namespace extensions, it won't validate. Hence why the doctype for xhtml+rdfa and xhtml+mathml languages have their own doctypes. It's not dogma, it's the standard, and as far as I know MS was on the board when that format was defined.

Let me quote the spec for you:
The XHTML namespace may be used with other XML namespaces as per [XMLNS], although such documents are not strictly conforming XHTML 1.0 documents as defined above. Work by W3C is addressing ways to specify conformance for documents involving multiple namespaces.

So using namespaces outisde of the xhtml namespace is non-conforming. And if you process it in an xml parser only (without the original non-validating DTD), then you're not including external character references and other oddities present in xhtml.

Fact: Xml namespaces are not to be used in HTML serializations, as HTML does *not* support xml namespaces.

The implementation of xml namespaces in html serializations (sgml for html 4 or the new one in html 5) suffers from incompatibilities across browsers. If you were to look at what happened with aria, that problem is exactly why the attributes are defined with aria-xxx and not using half-baked xml namespaces. It's a complicated state of affairs, and microsoft's approach with those extensions is going to make even more non-conforming documents available on the web.

I'm going to promote the comments to a blog post soon so discussion can be extended in enough details. If you're breaking two standards with a technology, refuse to address the points I showed, and ask me to be all rosy and cheer the ajax team, that's not going to happen. Xhtml / Html may well be a mess, and it's a sad state of affairs, but it is what it is, and a unilateral decision to break those technologies, and disregarding comments higlightin those issues, is not the right thing to do for the web.

Sorry for not being a cheerleader or being seen as a whiner, but after all both HTML4 and XHTML 1.0 were defined with the help of Microsoft weren't they?
Monday, January 04, 2010 8:07:22 PM UTC
Here is an article on some of new features on asp.net 4.0

http://www.codeproject.com/KB/aspnet/Whatis_New_ASP_Net_4.aspx
Monday, January 18, 2010 5:44:23 PM UTC
Dear Scott,

I was reading your article: "ASP Dynamic Data Preview - More ways to exploit ADO.NET Data Services for fun and profit" and I'm still wondering how do you produce or create the file "NorthwindClientEntities.cs" described there

It works beautifuly with the Northwind database but how can I make my own <_MyOwnDatabaseSchema_ClientEntities.cs>?

Carlos Porras (El Salvador)
Monday, January 18, 2010 11:27:19 PM UTC
Hi sir,

I got the file done by means of creating an ADO.Net Data Service. Even tough, thank you.



Carlos Porras (El Salvador)
Comments are closed.

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.