What’s new in ASP.NET 4.0

With Visual Studio 2010 Beta 1 and .NET Framework Beta 1 out for some time, this post is due from me for a long time.   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 ID="label1" runat="server"  Text="Value set in markup" ViewStateMode="Inherit"  /><br />
           Enabled: <asp:Label ID="label2"  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.

Page Meta Keyword & Description – Search Engine Optimization feature

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 name="keywords" content="ASP.NET, Web Development, Blog, ASP.NET Blog" />

<meta name="description" 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.

There are many more enhancements to Webforms such as Routing improvements, setting ClientID etc., which we will examine in the future posts.

Cheers !!!

Posted in: asp.net | Tags: asp.net asp.net 4.0 .net 4.0 meta keyword description seo eventargs webform clientid

New Feature in asp.net 4: Using Browser Capabilities Providers

In ASP.NET version 3.5 Service Pack 1, you can define the capabilities that a browser has in the following ways:

· At the machine level, you create or update a .browser XML file in the following folder:

\Windows\Microsoft.NET\Framework\v2.0.50727\CONFIG\Browsers

After you define the browser capability, you run the following command from the Visual Studio Command Prompt in order to rebuild the browser capabilities assembly and add it to the GAC:

aspnet_regbrowsers.exe –I c

· For an individual application, you create a .browser file in the application’s App_Browsers folder.

These approaches require you to change XML files, and for machine-level changes, you must restart the application after you run the aspnet_regbrowsers.exe process.

ASP.NET 4 includes a feature referred to as browser capabilities providers. As the name suggests, this lets you build a provider that in turn lets you use your own code to determine browser capabilities.

In practice, developers often do not define custom browser capabilities. Browser files are hard to update, the process for updating them is fairly complicated, and the XML syntax for .browser files can be complex to use and define. What would make this process much easier is if there were a common browser definition syntax, or a database that contained up-to-date browser definitions, or even a Web service for such a database. The new browser capabilities providers feature makes these scenarios possible and practical for third-party developers.

There are two main approaches for using the new ASP.NET 4 browser capabilities provider feature: extending the ASP.NET browser capabilities definition functionality, or totally replacing it. The following sections describe first how to replace the functionality, and then how to extend it.

Posted in: asp.net | Tags: asp.net 4.0 config new feature broser capabilities providers provider gac aspnet_regbrowsers

Replacing the ASP.NET Browser Capabilities Functionality in asp.net 4.0

To replace the ASP.NET browser capabilities definition functionality completely, follow these steps:

1. Create a provider class that derives from HttpCapabilitiesProvider and that overrides the GetBrowserCapabilities method, as in the following example:

public class CustomProvider : HttpCapabilitiesProvider

{

public override HttpBrowserCapabilities

GetBrowserCapabilities(HttpRequest request)

{

HttpBrowserCapabilities browserCaps = new HttpBrowserCapabilities();

Hashtable values = new Hashtable(180, StringComparer.OrdinalIgnoreCase);

values[String.Empty] = request.UserAgent;

values["browser"] = "MyCustomBrowser";

browserCaps.Capabilities = values;

return browserCaps;

}

}

The code in this example creates a new HttpBrowserCapabilities object, specifying only the capability named browser and setting that capability to MyCustomBrowser.

2. Register the provider with the application.

In order to use a provider with an application, you must add the provider attribute to the browserCaps section in the Web.config or Machine.config files. (You can also define the provider attributes in a location element for specific directories in application, such as in a folder for a specific mobile device.) The following example shows how to set the provider attribute in a configuration file:

<system.web>

<browserCaps provider="ClassLibrary2.CustomProvider, ClassLibrary2,

Version=1.0.0.0, Culture=neutral" />

</system.web>

Another way to register the new browser capability definition is to use code, as shown in the following example:

void Application_Start(object sender, EventArgs e)

{

HttpCapabilitiesBase.BrowserCapabilitiesProvider =

new ClassLibrary2.CustomProvider();

// ...

}

This code must run in the Application_Start event of the Global.asax file. Any change to the BrowserCapabilitiesProvider class must occur before any code in the application executes, in order to make sure that the cache remains in a valid state for the resolved HttpCapabilitiesBase object.

Caching the HttpBrowserCapabilities Object

The preceding example has one problem, which is that the code would run each time the custom provider is invoked in order to get the HttpBrowserCapabilities object. This can happen multiple times during each request. In the example, the code for the provider does not do much. However, if the code in your custom provider performs significant work in order to get the HttpBrowserCapabilities object, this can result in huge overhead. To prevent this from happening, you can cache the HttpBrowserCapabilities object. Follow these steps:

1. Create a class that derives from HttpCapabilitiesProvider, like the one in the following example:

public class CustomProvider : HttpCapabilitiesProvider

{

public override HttpBrowserCapabilities

GetBrowserCapabilities(HttpRequest request)

{

string cacheKey = BuildCacheKey();

int cacheTime = GetCacheTime();

HttpBrowserCapabilities browserCaps =

HttpContext.Current.Cache[cacheKey] as

HttpBrowserCapabilities;

if (browserCaps == null)

{

HttpBrowserCapabilities browserCaps = new

HttpBrowserCapabilities();

Hashtable values = new Hashtable(180,

StringComparer.OrdinalIgnoreCase);

values[String.Empty] = request.UserAgent;

values["browser"] = "MyCustomBrowser";

browserCaps.Capabilities = values;

HttpContext.Current.Cache.Insert(cacheKey,

browserCaps, null, DateTime.MaxValue,

TimeSpan.FromSeconds(cacheTime));

}

return browserCaps;

}

}

In the example, the code generates a cache key by calling a custom BuildCacheKey method, and it gets the length of time to cache by calling a custom GetCacheTime method. The code then adds the resolved HttpBrowserCapabilities object to the cache. The object can be retrieved from the cache and reused on subsequent requests that need your custom provider.

2. Register the provider with the application as described in the preceding procedure.

Posted in: asp.net | Tags: asp.net asp.net 4.0 replace broser capabilities functionality httpcapabilitiesprovider httpbrowsercapabilities

Extending ASP.NET Browser Capabilities Functionality in asp.net 4.0

The previous section described how to create a new HttpBrowserCapabilities object in ASP.NET 4. You can also extend the ASP.NET browser capabilities functionality by adding new browser capabilities definitions to those that are already in ASP.NET. You can do this without using the XML browser definitions. The following procedure shows how.

1. Create a class that derives from HttpCapabilitiesEvaluator and that overrides the GetBrowserCapabilities method, like the one in the following example:

public class CustomProvider : HttpCapabilitiesEvaluator

{

public override HttpBrowserCapabilities

GetBrowserCapabilities(HttpRequest request)

{

HttpBrowserCapabilities browserCaps =

base.GetHttpBrowserCapabilities(request);

if (browserCaps.Browser == "Unknown")

{

browserCaps = MyBrowserCapabilitiesEvaulator(request);

}

return browserCaps;

}

}

This code first uses the ASP.NET browser capabilities functionality to try to identify the browser. However, if no browser is identified based on the information defined in the request (that is, if the Browser property of the HttpBrowserCapabilities object is the string “Unknown”), the code calls the custom provider (MyBrowserCapabilitiesEvaluator) to identify the browser.

2. Register the provider with the application as described in the previous example.

Extending Browser Capabilities Functionality by Adding New Capabilities to Existing Capabilities Definitions

In addition to creating a custom browser definition provider and to dynamically creating new browser definitions, you can extend existing browser definitions with additional capabilities. This lets you use a definition that is close to what you want but lacks only a few capabilities. To do this, use the following steps.

1. Create a class that derives from HttpCapabilitiesEvaluator and that overrides the GetBrowserCapabilities method, like the one in the following example:

public class CustomProvider : HttpCapabilitiesEvaluator

{

public override HttpBrowserCapabilities

GetBrowserCapabilities(HttpRequest request)

{

HttpBrowserCapabilities browserCaps =

base.GetHttpBrowserCapabilities(request);

browserCaps.Frames = true;

browserCaps.Capabilities["MultiTouch"] = "true";

return browserCaps;

}

}

The example code extends the existing ASP.NET HttpCapabilitiesEvaluator class and gets the HttpBrowserCapabilities object that matched the current request definition by using the following code:

HttpBrowserCapabilities browserCaps =

base.GetHttpBrowserCapabilities(request);

The code can then add or modify a capability for this browser. There are two ways to specify a new browser capability:

· Add a key/value pair to the IDictionary object that is exposed by the Capabilities property of the HttpCapabilitiesBase object. In the previous example, the code adds a capability named MultiTouch with a value of true.

· Set existing properties of the HttpCapabilitiesBase object. In the previous example, the code sets the Frames property to true. This property is simply an accessor for the IDictionary object that is exposed by the Capabilities property.

Note   This model applies to any property of HttpBrowserCapabilities, including control adapters.

2. Register the provider with the application as described in the earlier procedure.

Posted in: asp.net | Tags: asp.net 4.0 broser capabilities httpbrowsercapabilities httpcapabilitiesevaluator getbrowsercapabilities extend key value

Routing in ASP.NET 4

ASP.NET 4 adds built-in support for using routing with Web Forms. Routing lets you configure an application to accept request URLs that do not map to physical files. Instead, you can use routing to define URLs that are meaningful to users and that can help with search-engine optimization (SEO) for your application. For example, the URL for a page that displays product categories in an existing application might look like the following example:

http://website/products.aspx?categoryid=12

By using routing, you can configure the application to accept the following URL to render the same information:

http://website/products/software

Routing has been available starting with ASP.NET 3.5 SP1. However, ASP.NET 4 includes some features that make it easier to use routing, including the following:

· The PageRouteHandler class, which is a simple HTTP handler that you use when you define routes. The class passes data to the page that the request is routed to.

· The new properties HttpRequest.RequestContext and Page.RouteData (which is a proxy for the HttpRequest.RequestContext.RouteData object). These properties make it easier to access information that is passed from the route.

· The following new expression builders, which are defined in System.Web.Compilation.RouteUrlExpressionBuilder and System.Web.Compilation.RouteValueExpressionBuilder:

· RouteUrl, which provides a simple way to create a URL that corresponds to a route URL format within an ASP.NET server control.

· RouteValue, which provides a simple way to extract information from the RouteContext object.

· The RouteParameter class, which makes it easier to pass data contained in a RouteContext object to a query for a data source control (similar to FormParameter).

Routing for Web Forms Pages

The following example shows how to define a Web Forms route by using the new MapPageRoute method of the Route class:

public class Global : System.Web.HttpApplication

{

void Application_Start(object sender, EventArgs e)

{

RouteTable.Routes.MapPageRoute("SearchRoute",

"search/{searchterm}", "~/search.aspx");

RouteTable.Routes.MapPageRoute("UserRoute",

"users/{username}", "~/users.aspx");

}

}

ASP.NET 4 Beta 2 introduces the MapPageRoute method. The following example is equivalent to the SearchRoute definition shown in the previous example, but uses the PageRouteHandler class.

RouteTable.Routes.Add("SearchRoute", new Route("search/{searchterm}",

new PageRouteHandler("~/search.aspx")));

The code in the example maps the route to a physical page (in the first route, to ~/search.aspx). The first route definition also specifies that the parameter named searchterm should be extracted from the URL and passed to the page.

The MapPageRoute method supports the following method overloads:

· MapPageRoute(string routeName, string routeUrl, string physicalFile, bool checkPhysicalUrlAccess)

· MapPageRoute(string routeName, string routeUrl, string physicalFile, bool checkPhysicalUrlAccess, RouteValueDictionary defaults)

· MapPageRoute(string routeName, string routeUrl, string physicalFile, bool checkPhysicalUrlAccess, RouteValueDictionary defaults, RouteValueDictionary constraints)

The checkPhysicalUrlAccess parameter specifies whether the route should check the security permissions for the physical page being routed to (in this case, search.aspx) and the permissions on the incoming URL (in this case, search/{searchterm}). If the value of checkPhysicalUrlAccess is false, only the permissions of the incoming URL will be checked. These permissions are defined in the Web.config file with settings such as the following:

<configuration>

<location path="search.aspx">

<system.web>

<authorization>

<allow roles="admin"/>

<deny users="*"/>

</authorization>

</system.web>

</location>

<location path="search">

<system.web>

<authorization>

<allow users="*"/>

</authorization>

</system.web>

</location>

</configuration>

In the example configuration, access is denied to the physical page search.aspx for all users except those who are in the admin role. When the checkPhysicalUrlAccess parameter is set to true (which is its default value), only admin users are allowed to access the URL /search/{searchterm}, because the physical page search.aspx is restricted to users in that role. If checkPhysicalUrlAccess is set to false and the site is configured as shown in the previous example, all authenticated users are allowed to access the URL /search/{searchterm}.

Posted in: asp.net | Tags: xml asp.net asp.net 4.0 eventargs routing pageroutehandler httprequest requestcontext routevalueexpressionbuilder web form page authorization location configuration