Upto Visual Studio 2008, one can set the Title of the page declaratively or through program using Page.Title.  However, as more and more web traffic is happening through search engines, Page’s Title, Keyword and description become more important.  Although the Keyword feature was exploited and hence many search engines today ignore it, Page Description is something still major search engines such as Google, Bing use for identifying and indexing pages based on content.

The new feature in ASP.NET 4.0 allows users to programmatically set the Page Description and Keywords as follows:-

protected void Page_Load(object sender, EventArgs e)
{

this.Page.Title = “My ASP.NET Blog”;

this.Page.MetaKeywords = “ASP.NET, Web Development, Blog, ASP.NET Blog”;

this.Page.MetaDescription = “This Blog contains posts related to ASP.NET and Web Development”;

}

The above code appends the following markup

<meta content=”ASP.NET, Web Development, Blog, ASP.NET Blog” />

<meta content=”This Blog contains posts related to ASP.NET and Web Development” />

And the way it works is that, if the meta tags are already present in the HTML markup, whatever is set in the code behind  will fill up the “content” part alone if the “name” tag is matching.

Although this looks simple, it is very useful in cases where you want to set these dynamically based on a condition / criteria.  So far, these were set statically in the HTML.  Now with Page Class level access, these can be set dynamically.

ASP.NET 4.0 has many improvements for different set of scenarios such as Webforms, Dynamic Data & AJAX based web development.  There are also a lot of enhancements to the core runtime that powers ASP.NET such as Caching, Session & Request/Response objects.

For this post, we will examine some of the web form enhancements.  There are sure a lot of them and we will examine some of them in the future posts.

Controlling View State using the ViewStateMode Property – Performance Enhancement

One of the most complained thing in ASP.NET Webform is the growing viewstate which becomes a concern for performance.  While earlier you can set the EnableViewState property to true or false, post that, all the controls, by default inherit and even if you set it to enabled at control level, the behaviour was inconsistent.

With ASP.NET 4.0, the ViewStateMode property helps to determine for every control, whether the ViewState should be enabled, disabled or inherited accordingly.  Ex.-

<asp:Panel ID=”pnlViewState” runat=”server” ViewStateMode=”Disabled”>
Disabled: <asp:Label runat=”server”  Text=”Value set in markup” ViewStateMode=”Inherit” /><br />
Enabled: <asp:Label  runat=”server” Text=”Value set in markup” ViewStateMode=”Enabled” />
<hr />
<asp:button ID=”Button1″ runat=”server”  Text=”Postback” />
</asp:Panel>

In the code-behind

protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
label1.Text = “Value set in code behind”;
label2.Text = “Value set in code behind”;
}
}

When you run the above page, you can find that the intial value for both the labels is set to “Value set in code behind” whereas after clicking on the button (postback), the value of label1 changes to “Value set in markup” whereas the value of label2 remains unchanged.  As you can see, the Panel which holds both these lables has ViewStateMode set to Disabled and label1 is inherting the mode (this is the default if not specified) and label2 has it enabled.  That is the reason label2 maintains viewstate while label1 loses it.

While it is arguably possible using the simple EnableViewState property earlier, it was never consistent.  Considering the fact that in most of our performance sessions, we talk about disabling viewstate and then enabling it at control level while it doesnt work, this ViewStateMode is a welcome architectural change to improve performance.

New for the Web

  • Dynamic IntelliSense for JavaScript with vastly superior performance and completeness relative to VS08
  • A new editor for web developers with code-focused productivity through HTML/ASP.Net snippets
  • Seamless packaging and publishing of web applications to hosted and enterprise IIS servers
  • Config transformations for packaging and deployment scenarios
  • Standards based CSS 2.1 rendering in Design View
  • Silverlight 3 support with interactive XAML designer
  • Multi-targeting support to build applications for ASP.NET 2.0, 3.5 and 4.0

Dynamic IntelliSense for JavaScript

This is one of the coolest features in Visual Studio 2010.  IntelliSense for dynamic languages like JavaScript has always be problematic.  Types and even functions can be added to classes dynamically at runtime.  Now in Visual Studio you’ll have IntelliSense on these dynamically created types.  Shown below is an example where jQuery was dynamically extended with a new detonate effect and the IntelliSense that follows.

pic1

Snippets for HTML and JavaScript

HTML, ASPX and JavaScript files now have full support for Visual Studio’s snippets.  No more having to type runat=”server” on every control.  There are hundreds of new snippets included in Visual Studio 2010.

For example field validation can now be added in just a few key strokes.  After the snippet is inserted you’ll only need to fill-in the unique pieces of information highlighted below.

pic2

Packaging and Deployment

Visual Studio 2010 now has the ability to completely package and deploy a web application including all it’s IIS settings, Databases and Application logic.

There is a new 1-click publishing experience that simplifies publishing and updating your sites.

In addition to 1-click publishing there are extensive packaging options to control what specific IIS settings you want included with your package.

You can even include custom database scripts to run when your package is installed.

As part of the packaging process you can also run custom transforms on web.config that allow you update any section of web.config with custom settings unique to the deployment.

For example you can replace database connection strings and web service end points.

pic3

CSS 2.1 Layout Rendering in Design View

The HTLM and ASPX designer has been updated with support for CSS 2.1 layout rendering including attribute selectors.  The designer will now faithfully render your CSS 2.1 standards compliant markup.

if it is helpful, plese dont forget to leave a comment.

It’s the next gen of next-gen applications. Visual Studio 2010 is being designed inside and out to give developers and development teams every advantage in getting groundbreaking applications to market—faster and easier than ever.

The Beta is coming soon.

Take a look at what we’re working on.

Enhanced User Experience

Enhanced User Experience

Microsoft Visual Studio 2010 delivers a modern, enhanced user experience that makes understanding the current context more natural.

  • Clear UI Organization
  • Reduced clutter and complexity
  • Improved editor
  • Better support for floating documents and windows
  • Enhanced document targeting
  • Focused animations for action feedback

SharePoint Development in Visual Studio 2010

Usability and functionality for SharePoint developers is much more advanced with this Visual Studio release.

  • Enhanced customization abilities with new templates, designers and explorers
  • Design your own association and initiation forms for workflows
  • F5 deployment and debugging for SharePoint apps
  • Easier SharePoint site navigation with Server Explorer

Democratizing Application Lifecycle Management

Democratizing Application Lifecycle Management

Visual Studio Team System 2010 delivers new capabilities for everyone on a project, including architects, developers, project managers and testers.

  • Discover existing code assets with the new Architecture Explorer
  • Design and share multiple diagram types, including use case, activity and sequence diagrams
  • Tooling for better documentation of test scenarios and more thorough collection of test data
  • Run tests impacted by a code change with the new Test Impact View
  • Gated check-in, branch visualization and build workflow allow for enhanced version control

Inspiring Developer Delight

Visual Studio has made application development more productive, efficient and flexible for both developers and companies. Visual Studio 2010 continues this legacy.

  • Contextual support helps developers better understand existing code – and write new code more efficiently
  • First class C++ development experience that helps developers navigate and understand complex C++ source bases
  • Build new Windows® 7 applications or upgrade existing applications
  • Enable Office tools to make your solutions more flexible and productive for specific needs

Web Development

Web Development

With Visual Studio 2010, we’re continuing our investment in great Web development tools.

  • A high-performance and standards-compliant JavaScript IntelliSense® engine
  • “One Click Deployment” that quickly publishes files and configuration settings from development machines to the final deployed site
  • Full support for Silverlight™ for cutting-edge, rich Internet applications

Cloud Development

With Windows Azure™ Tools for Visual Studio, it’s easy for developers to build, debug and deploy services and applications for Microsoft’s new cloud platform.

  • C# and VB Project Templates for building Cloud Services
  • Tools to change the Service Role configuration
  • Integrated local development via Development Fabric and Development Storage services
  • Debugging Cloud Service Roles running in the Development Fabric
  • Building and packaging of Cloud Service Packages
  • Browsing to the Azure Services Developer Portal

More Databases

More Databases

With the Visual Studio partner ecosystem, developers will now be able to work with IBM DB2 and Oracle databases in addition to Microsoft SQL Server™ databases.

IBM has committed to develop, sell and support a Database Schema Provider (DSP) to let developers working with DB2 on the Windows, Linux or Unix platforms do offline design, development, testing and change management using Visual Studio Team System 2010 Development Edition.

Quest Software have made a similar commitment develop, sell and support a DSP which will enable Oracle Developers to work with their databases just as easily.

Parallel Programming

Parallel programming is simplified, so both native- and managed-code developers can productively build innovative applications.

  • IDE support for parallel programming
  • Native C++ libraries that use lambda functions and align well with STL
  • Parallel Extensions to the .NET Framework offers support for imperative data and task parallelism, declarative data parallelism, and more
  • Resource management of the multicore hardware and task scheduling enabled by Concurrency Runtime
  • Parallel debugging windows and profiling views

if it is helpful, plese dont forget to leave a comment.

Introduction

One of the new features being added to version 4.0 of ASP.NET is the ability to control the client side IDs that are generated by the framework.  Previously the framework would modify the client side IDs to uniquely identify each control.  This some times left you with the ID you defined in markup or sometimes left you with something that looks like this, “ctl00_MasterPageBody_ctl01_Textbox1.”

The Problem

The modification of the client side id property works great to ensure that each element is uniquely identified, however, to anyone that has tried to do any sort of client side scripting this becomes very frustrating. Chances are that if you have worked in ASP.NET for any time at all you have run into this issue.  The problem is that until runtime you do not what the client side ID could be, making it difficult to do any kind of client side scripting.  In addition any modification of the page, adding removing controls, can result in a different client side ID being generated.

Old Solution

Again if you have worked with ASP.NET for any amount of time you know there is a work around for this issue.  Each control has a property called ClientID that is a read only and supplies the unique client side ID.  You can use this in a code behind when dynamically adding scripts, or more commonly use inline code (old ASP style) to supply the value to and client side scripts.

<script type="text/javascript">
    function DoSomething(){
        alert('<%= Control.ClientID %>');
    }
</script>

ASP.NET 4.0 Solution

First off let me start by explaining why we decided to tackle this problem in version 4.0 of the framework.  While we provided a way of supplying the developer with the client side ID, with the growth of client side scripting this solution has become some what hacky.  There is not really a clean way to use this with lots of controls and lots of external script files.  Also it might have had something to do with the developer asking for control over this.  Developers do love to have control of everything, weather they use it or not, it’s just our nature 🙂 The solution that we came up has four ‘modes’ that a user can use giving them everything from existing behavior to full control.  The controls ID property is modified according to the ClientIDMode mode and then used as the client side id.

Modes and what they do

There is now a new property on every control (this includes pages and master pages as they inherit from control) called ClientIDMode that is used to select the behavior of the client side ID.

<asp:Label ID="Label1" runat="server" ClientIDMode="[Mode Type]" />

The Mode Types

  • Legacy: The default value if ClientIDMode is not set anywhere in the control hierarchy.  This causes client side IDs to behave the way they did in version 2.0 (3.0 and 3.5 did not change this code path) of the framework. This mode will generate an ID similar to “ctl00_MasterPageBody_ctl01_Textbox1.”
  • Inherit: This is the default behavior for every control.  This looks to the controls parent to get its value for ClientIDMode.  You do not need to set this on every control as it is the default, this is used only when the ClientIDMode has been changed and the new desired behavior is to inherit from the controls parent.
  • Static: This mode does exactly what you think it would, it makes the client side ID static. Meaning that what you put for the ID is what will be used for the client side ID.  Warning, this means that if a static ClientIDMode is used in a repeating control the developer is responsible for ensuring client side ID uniqueness.
  • Predictable: This mode is used when the framework needs to ensure uniqueness but it needs to be done so in a predictable way.  The most common use for this mode is on databound controls.  The framework will traverse the control hierarchy prefixing the supplied ID with it’s parent control ID until it reaches a control in the hierarchy whose ClientIDMode is defined as static.  In the event that the control is placed inside a databound control a suffix with a value that identifies that instance will also be added to the supplied ID.  The ClientIDRowSuffix property is used to control the value that will be used as a suffix (see samples).  This mode will generate an ID similar to “Gridview1_Label1_0”

Samples

Legacy Mode

Legacy mode is pretty straight forward, it generates a client side ID the way that it had in version 2.0 of the framework.

markup:

<asp :TextBox ID ="txtEcho" runat ="server" Width ="65%" ClientIDMode ="Legacy" />

output:

<input id="ctl00_MasterPageBody_ctl00_txtEcho" style="width: 65%" name="ctl00$MasterPageBody$ctl00$txtEcho" />

Static Mode

Static is the most basic of all ClientIDMode modes, what you give for the ID is what you get for the client side ID. Once again a warning that if a static ClientIDMode is used inside of a repeated control it is the developer’s responsibility to ensure client side ID uniqueness.

markup:

<asp:TextBox ID="txtEcho2" runat="server" Width="65%" ClientIDMode="Static" />

output:

<input id="txtEcho2" style="width: 65%" name="ctl00$MasterPageBody$ctl00$txtEcho2" />

Predictable Mode

Predictable mode really tackles the heart of the problem.  The framework previously generated it’s unique IDs to prevent ID collisions and the most common place for these types of collisions are inside databound controls.  Predictable mode is really designed to work with databound controls but does not have to.  There is three ways to uses the predictable mode, each one of these is defined through the ClientIDRowSuffix property that specifies the suffix for each instance.  The ClientIDRowSuffix uses values from the control’s datakeys collection, so if the control does not have a datakeys collection this property is not viable.  If this property is not set or is not available the row index will be used in it’s place.

1. With no ClientIDRowSuffix defined, this is also the behavior for databound controls without a datakeys collection e.g. Repeater Control.  Notice that the framework has traversed the control hierarchy and prefixed the ID with the parent’s ID and suffixed the ID with row index.

markup:

<asp:GridView ID="EmployeesNoSuffix" runat="server" AutoGenerateColumns="false" ClientIDMode="Predictable" >
    <Columns>
        <asp:TemplateField HeaderText="ID">
            <ItemTemplate>
                <asp:Label ID="EmployeeID" runat="server" Text='<%# Eval("ID") %>' />
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="Name">
            <ItemTemplate>
                <asp:Label ID="EmployeeName" runat="server" Text='<%# Eval("Name") %>' />
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
</asp:GridView>

output:

<table id="EmployeesNoSuffix" style="border-collapse: collapse" cellspacing="0" rules="all" border="1">
    <tbody>
        <tr>
            <th scope="col">ID</th>
            <th scope="col">Name</th>
        </tr>
        <tr>
            <td><span id="EmployeesNoSuffix_EmployeeID_0">1</span></td>
            <td><span id="EmployeesNoSuffix_EmployeeName_0">EmployeeName1</span></td>
        </tr>
        ...
        <tr>
            <td><span id="EmployeesNoSuffix_EmployeeID_8">9</span></td>
            <td><span id="EmployeesNoSuffix_EmployeeName_8">EmployeeName9</span></td>
        </tr>
    </tbody>
</table>

2. With a ClientIDRowSuffix defined, this looks in the control’s datakeys collection for the value and then suffixes the ID with that value.

markup:

<asp:GridView ID="EmployeesSuffix" runat="server" AutoGenerateColumns="false" ClientIDMode="Predictable" ClientIDRowSuffix="ID" >
    <Columns>
        <asp:TemplateField HeaderText="ID">
            <ItemTemplate>
                <asp:Label ID="EmployeeID" runat="server" Text='<%# Eval("ID") %>' />
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="Name">
            <ItemTemplate>
                <asp:Label ID="EmployeeName" runat="server" Text='<%# Eval("Name") %>' />
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
</asp:GridView>

output:

<table id="EmployeesSuffix" style="border-collapse: collapse" cellspacing="0" rules="all" border="1">
    <tbody>
        <tr>
            <th scope="col">ID</th>
            <th scope="col">Name</th>
        </tr>
        <tr>
            <td><span id="EmployeesSuffix_EmployeeID_1">1</span></td>
            <td><span id="EmployeesSuffix_EmployeeName_1">EmployeeName1</span></td>
        </tr>
        ...
        <tr>
            <td><span id="EmployeesSuffix_EmployeeID_9">9</span></td>
            <td><span id="EmployeesSuffix_EmployeeName_9">EmployeeName9</span></td>
        </tr>
    </tbody>
</table>

3. With a ClientIDRowSuffix defined, but instead of just one value a compound value will be used.  Exhibits the same behavior as one value but it will suffix both values onto the ID.

markup:

<asp:GridView ID="EmployeesCompSuffix" runat="server" AutoGenerateColumns="false" ClientIDMode="Predictable" ClientIDRowSuffix="ID, Name" >
    <Columns>
        <asp:TemplateField HeaderText="ID">
            <ItemTemplate>
                <asp:Label ID="EmployeeID" runat="server" Text='<%# Eval("ID") %>' />
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="Name">
            <ItemTemplate>
                <asp:Label ID="EmployeeName" runat="server" Text='<%# Eval("Name") %>' />
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
</asp:GridView>

output:

<table id="EmployeesCompSuffix" style="border-collapse: collapse" cellspacing="0" rules="all" border="1">
    <tbody>
        <tr>
            <th scope="col">ID</th>
            <th scope="col">Name</th>
        </tr>
        <tr>
            <td><span id="EmployeesCompSuffix_EmployeeID_1_EmployeeName1">1</span></td>
            <td><span id="EmployeesCompSuffix_EmployeeName_1_EmployeeName1">EmployeeName1</span></td>
        </tr>
        ...
        <tr>
            <td><span id="EmployeesCompSuffix_EmployeeID_9_EmployeeName9">9</span></td>
            <td><span id="EmployeesCompSuffix_EmployeeName_9_EmployeeName9">EmployeeName9</span></td>
        </tr>
    </tbody>
</table>

Summary

The ability to fully control the client side IDs that are generated by the framework is a request that has not generated much noise but everyone seems to want it when you mention it.  We believe that we have found a good solution to the request and think that it adds some much need functionality for developer that use lots of client side scripting.  There is an early preview and a walk through of this feature in CTP build that we released at PDC 2008.  For more information and a much more detailed description of this feature read Scott Galloway’s blog post.

if it is helpful, plese dont forget to leave a comment.