asynchronous reading and writing http r equest
Post on 25-Dec-2014
4.814 Views
Preview:
DESCRIPTION
TRANSCRIPT
ASP.NET Core Runtime and Framework
Asynchronously Reading and Writing HTTP Requests and Responses
ASP.NET 4 introduced the ability to read an HTTP request entity as a stream using the
HttpRequest.GetBufferlessInputStream method. This method provided streaming access to
the request entity. However, it executed synchronously, which tied up a thread for the
duration of a request.
ASP.NET 4.5 supports the ability to read streams asynchronously on an HTTP request entity,
and the ability to flush asynchronously. ASP.NET 4.5 also gives you the ability to double-buffer
an HTTP request entity, which provides easier integration with downstream HTTP handlers
such as .aspx page handlers and ASP.NET MVC controllers.
Improvements to HttpRequest handling
The Stream reference returned by ASP.NET 4.5 from HttpRequest.GetBufferlessInputStream
supports both synchronous and asynchronous read methods. The Stream object returned
from GetBufferlessInputStream now implements both the BeginRead and EndRead methods.
The asynchronous Stream methods let you asynchronously read the request entity in chunks,
while ASP.NET releases the current thread between each iteration of an asynchronous read
loop.
ASP.NET 4.5 has also added a companion method for reading the request entity in a buffered
way: HttpRequest.GetBufferedInputStream. This new overload works like
GetBufferlessInputStream, supporting both synchronous and asynchronous reads. However,
as it reads, GetBufferedInputStream also copies the entity bytes into ASP.NET internal buffers
so that downstream modules and handlers can still access the request entity. For example, if
some upstream code in the pipeline has already read the request entity using
GetBufferedInputStream, you can still use HttpRequest.Form or HttpRequest.Files. This lets
you perform asynchronous processing on a request (for example, streaming a large file
upload to a database), but still run .aspx pages and MVC ASP.NET controllers afterward.
Asynchronously flushing a response
Sending responses to an HTTP client can take considerable time when the client is far away or
has a low-bandwidth connection. Normally ASP.NET buffers the response bytes as they are
created by an application. ASP.NET then performs a single send operation of the accrued
buffers at the very end of request processing.
If the buffered response is large (for example, streaming a large file to a client), you must
periodically call HttpResponse.Flush to send buffered output to the client and keep memory
usage under control. However, because Flush is a synchronous call, iteratively calling Flush
still consumes a thread for the duration of potentially long-running requests.
ASP.NET 4.5 adds support for performing flushes asynchronously using the BeginFlush and
EndFlush methods of the HttpResponse class. Using these methods, you can create
asynchronous modules and asynchronous handlers that incrementally send data to a client
without tying up operating-system threads. In between BeginFlush and EndFlush calls,
ASP.NET releases the current thread. This substantially reduces the total number of active
threads that are needed in order to support long-running HTTP downloads.
Support for await and Task-Based Asynchronous Modules and Handlers
The .NET Framework 4 introduced an asynchronous programming concept referred to as a
task. Tasks are represented by the Task type and related types in the
System.Threading.Tasks namespace. The .NET Framework 4.5 builds on this with compiler
enhancements that make working with Task objects simple. In the .NET Framework 4.5, the
compilers support two new keywords: await and async. The await keyword is syntactical
shorthand for indicating that a piece of code should asynchronously wait on some other piece
of code. The async keyword represents a hint that you can use to mark methods as task-
based asynchronous methods.
The combination of await, async, and the Task object makes it much easier for you to write
asynchronous code in .NET 4.5. ASP.NET 4.5 supports these simplifications with new APIs that
let you write asynchronous HTTP modules and asynchronous HTTP handlers using the new
compiler enhancements.
Asynchronous HTTP modules
Suppose that you want to perform asynchronous work within a method that returns a Task
object. The following code example defines an asynchronous method that makes an
asynchronous call to download the Microsoft home page. Notice the use of the async keyword
in the method signature and the await call to DownloadStringTaskAsync.
private async Task
ScrapeHtmlPage(object caller, EventArgs e)
{
WebClient wc = new WebClient();
var result = await
wc.DownloadStringTaskAsync("http://www.microsoft.com");
// Do something with the result
}
That's all you have to write — the .NET Framework will automatically handle unwinding the
call stack while waiting for the download to complete, as well as automatically restoring the
call stack after the download is done.
Now suppose that you want to use this asynchronous method in an asynchronous ASP.NET
HTTP module. ASP.NET 4.5 includes a helper method (EventHandlerTaskAsyncHelper) and a
new delegate type (TaskEventHandler) that you can use to integrate task-based
asynchronous methods with the older asynchronous programming model exposed by the
ASP.NET HTTP pipeline. This example shows how:
public void Init(HttpApplication
context)
{
// Wrap the Task-based method so that it can be used with
// the older async programming model.
EventHandlerTaskAsyncHelper helper =
new EventHandlerTaskAsyncHelper(ScrapeHtmlPage);
// The helper object makes it easy to extract Begin/End methods
out of
// a method that returns a Task object. The ASP.NET pipeline
calls the
// Begin and End methods to start and complete calls on
asynchronous
// HTTP modules.
context.AddOnPostAuthorizeRequestAsync(
helper.BeginEventHandler, helper.EndEventHandler);
}
Asynchronous HTTP handlers
The traditional approach to writing asynchronous handlers in ASP.NET is to implement the
IHttpAsyncHandler interface. ASP.NET 4.5 introduces the HttpTaskAsyncHandler
asynchronous base type that you can derive from, which makes it much easier to write
asynchronous handlers.
The HttpTaskAsyncHandler type is abstract and requires you to override the
ProcessRequestAsync method. Internally ASP.NET takes care of integrating the return
signature (a Task object) of ProcessRequestAsync with the older asynchronous programming
model used by the ASP.NET pipeline.
The following example shows how you can use Task and await as part of the implementation
of an asynchronous HTTP handler:
public class MyAsyncHandler : HttpTaskAsyncHandler
{
// ...
// ASP.NET automatically takes care of integrating the Task based
override
// with the ASP.NET pipeline.
public override async Task ProcessRequestAsync(HttpContext context)
{
WebClient wc = new WebClient();
var result = await
wc.DownloadStringTaskAsync("http://www.microsoft.com");
// Do something with the result
}
}
New ASP.NET Request Validation Features
By default, ASP.NET performs request validation — it examines requests to look for markup or
script in fields, headers, cookies, and so on. If any is detected, ASP.NET throws an exception.
This acts as a first line of defense against potential cross-site scripting attacks.
ASP.NET 4.5 makes it easy to selectively read unvalidated request data. ASP.NET 4.5 also
integrates the popular AntiXSS library, which was formerly an external library.
Developers have frequently asked for the ability to selectively turn off request validation for
their applications. For example, if your application is forum software, you might want to allow
users to submit HTML-formatted forum posts and comments, but still make sure that request
validation is checking everything else.
ASP.NET 4.5 introduces two features that make it easy for you to selectively work with
unvalidated input: deferred ("lazy") request validation and access to unvalidated request
data.
Deferred ("lazy") request validation
In ASP.NET 4.5, by default all request data is subject to request validation. However, you can
configure the application to defer request validation until you actually access request data.
(This is sometimes referred to as lazy request validation, based on terms like lazy loading for
certain data scenarios.) You can configure the application to use deferred validation in the
Web.config file by setting the requestValidationMode attribute to 4.5 in the httpRUntime
element, as in the following example:
<httpRuntime requestValidationMode="4.5" ... />
When request validation mode is set to 4.5, request validation is triggered only for a specific
request value and only when your code accesses that value. For example, if your code gets
the value of Request.Form["forum_post"], request validation is invoked only for that element
in the form collection. None of the other elements in the Form collection are validated. In
previous versions of ASP.NET, request validation was triggered for the entire request
collection when any element in the collection was accessed. The new behavior makes it easier
for different application components to look at different pieces of request data without
triggering request validation on other pieces.
Support for unvalidated requests
Deferred request validation alone doesn't solve the problem of selectively bypassing request
validation. The call to Request.Form["forum_post"] still triggers request validation for that
specific request value. However, you might want to access this field without triggering
validation because you want to allow markup in that field.
To allow this, ASP.NET 4.5 now supports unvalidated access to request data. ASP.NET 4.5
includes a new Unvalidated collection property in the HttpRequest class. This collection
provides access to all of the common values of request data, like Form, QueryString, Cookies,
and Url.
Using the forum example, to be able to read unvalidated request data, you first need to
configure the application to use the new request validation mode:
<httpRuntime requestValidationMode="4.5" ...
/>
You can then use the HttpRequest.Unvalidated property to read the unvalidated form value:
var s = context.Request.Unvalidated.Form["forum_post"];
Security Note: Use unvalidated request data with care! ASP.NET 4.5 added the unvalidated
request properties and collections to make it easier for you to access very specific
unvalidated request data. However, you must still perform custom validation on the raw
request data to ensure that dangerous text is not rendered to users.
AntiXSS Library
Due to the popularity of the Microsoft AntiXSS Library, ASP.NET 4.5 now incorporates core
encoding routines from version 4.0 of that library.
The encoding routines are implemented by the AntiXssEncoder type in the new
System.Web.Security.AntiXss namespace. You can use the AntiXssEncoder type directly by
calling any of the static encoding methods that are implemented in the type. However, the
easiest approach for using the new anti-XSS routines is to configure an ASP.NET application to
use the AntiXssEncoder class by default. To do this, add the following attribute to the
Web.config file:
<httpRuntime ...
encoderType="System.Web.Security.AntiXss.AntiXssEncoder,System.Web,
Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
When the encoderType attribute is set to use the AntiXssEncoder type, all output encoding in
ASP.NET automatically uses the new encoding routines.
These are the portions of the external AntiXSS library that have been incorporated into
ASP.NET 4.5:
HtmlEncode, HtmlFormUrlEncode, and HtmlAttributeEncode
XmlAttributeEncode and XmlEncode
UrlEncode and UrlPathEncode (new)
CssEncode
Support for WebSockets Protocol
WebSockets protocol is a standards-based network protocol that defines how to establish
secure, real-time bidirectional communications between a client and a server over HTTP.
Microsoft has worked with both the IETF and W3C standards bodies to help define the
protocol. The WebSockets protocol is supported by any client (not just browsers), with
Microsoft investing substantial resources supporting WebSockets protocol on both client and
mobile operating systems.
WebSockets protocol makes it much easier to create long-running data transfers between a
client and a server. For example, writing a chat application is much easier because you can
establish a true long-running connection between a client and a server. You do not have to
resort to workarounds like periodic polling or HTTP long-polling to simulate the behavior of a
socket.
ASP.NET 4.5 and IIS 8 include low-level WebSockets support, enabling ASP.NET developers to
use managed APIs for asynchronously reading and writing both string and binary data on a
WebSockets object. For ASP.NET 4.5, there is a new System.Web.WebSockets namespace that
contains types for working with WebSockets protocol.
A browser client establishes a WebSockets connection by creating a DOM WebSocket object
that points to a URL in an ASP.NET application, as in the following example:
socket = new WebSocket("ws://contoso.com/MyWebSocketApplication.ashx");
You can create WebSockets endpoints in ASP.NET using any kind of module or handler. In the
previous example, an .ashx file was used, because .ashx files are a quick way to create a
handler.
According to the WebSockets protocol, an ASP.NET application accepts a client's WebSockets
request by indicating that the request should be upgraded from an HTTP GET request to a
WebSockets request. Here's an example:
HttpContext.Current.AcceptWebSocketRequest(// WebSocket delegate goes here)
The AcceptWebSocketRequest method accepts a function delegate because ASP.NET unwinds
the current HTTP request and then transfers control to the function delegate. Conceptually
this approach is similar to how you use System.Threading.Thread, where you define a thread-
start delegate in which background work is performed.
After ASP.NET and the client have successfully completed a WebSockets handshake, ASP.NET
calls your delegate and the WebSockets application starts running. The following code
example shows a simple echo application that uses the built-in WebSockets support in
ASP.NET:
public async Task MyWebSocket(AspNetWebSocketContext context)
{
WebSocket socket = context.WebSocket;
while (true)
{
ArraySegment<byte> buffer = new ArraySegment<byte>(new
byte[1024]);
// Asynchronously wait for a message to arrive from a client
WebSocketReceiveResult result =
await socket.ReceiveAsync(buffer,
CancellationToken.None);
// If the socket is still open, echo the message back to the
client
if (socket.State == WebSocketState.Open)
{
string userMessage =
Encoding.UTF8.GetString(buffer.Array, 0,
result.Count);
userMessage = "You sent: " + userMessage + " at " +
DateTime.Now.ToLongTimeString();
buffer = new
ArraySegment<byte>(Encoding.UTF8.GetBytes(userMessage));
// Asynchronously send a message to the client
await socket.SendAsync(buffer,
WebSocketMessageType.Text,
true, CancellationToken.None);
}
else { break; }
}
}
The support in .NET 4.5 for the await keyword and asynchronous task-based operations is a
natural fit for writing WebSockets applications. The code example shows that a WebSockets
request runs completely asynchronously inside ASP.NET. The application waits
asynchronously for a message to be sent from a client by calling await socket.ReceiveAsync.
Similarly, you can send an asynchronous message to a client by calling await
socket.SendAsync.
In the browser, an application receives WebSockets messages through an onmessage
function. To send a message from a browser, you call the send method of the WebSocket
DOM type, as shown in this example:
// Receive a string message from the server.
socket.onmessage = function(msg)
{
document.getElementById("serverData").innerHTML = msg.data;
};
// Send a string message from the browser.
socket.send(document.getElementById("msgText"));
In the future, we might release updates to this functionality that abstract away some of the
low-level coding that is required in this release for WebSockets applications.
Bundling and Minification
Bundling lets you combine individual JavaScript and CSS files into a bundle that can be
treated like a single file. Minification condenses JavaScript and CSS files by removing
whitespace and other characters that are not required. These features work with Web Forms,
ASP.NET MVC, and Web Pages.
Bundles are created using the Bundle class or one of its child classes, ScriptBundle and
StyleBundle. After configuring an instance of a bundle, the bundle is made available to
incoming requests by simply adding it to a global BundleCollection instance. In the default
templates, bundle configuration is performed in a BundleConfig file. This default configuration
creates bundles for all of the core scripts and css files used by the templates.
Bundles are referenced from within views by using one of a couple possible helper methods.
In order to support rendering different markup for a bundle when in debug vs. release mode,
the ScriptBundle and StyleBundle classes have the helper method, Render. When in debug
mode, Render will generate markup for each resource in the bundle. When in release mode,
Render will generate a single markup element for the entire bundle. Toggling between debug
and release mode can be accomplished by modifying the debug attribute of the compilation
element in web.config as shown below:
<system.web>
<compilation targetframework="4.5" debug="true" />
...</system.web>
Additionally, enabling or disabling optimization can be set directly via the
BundleTable.EnableOptimizations property.
BundleTable.EnableOptimizations = true;
When files are bundled, they are first sorted alphabetically (the way they are displayed in
Solution Explorer). They are then organized so that known libraries and their custom
extensions (such as jQuery, MooTools, and Dojo) are loaded first. For example, the final order
for the bundling of the Scripts folder as shown above will be:
1. jquery-1.6.2.js
2. jquery-ui.js
3. jquery.tools.js
4. a.js
CSS files are also sorted alphabetically and then reorganized so that reset.css and
normalize.css come before any other file. The final sorting of the bundling of the Styles folder
shown above will be this:
1. reset.css
2. content.css
3. forms.css
4. globals.css
5. menu.css
6. styles.css
Performance Improvements for Web Hosting
The .NET Framework 4.5 and Windows 8 introduce features that can help you achieve a
significant performance boost for web-server workloads. This includes a reduction (up to 35%)
in both startup time and in the memory footprint of web hosting sites that use ASP.NET.
Key performance factors
Ideally, all websites should be active and in memory to assure quick response to the next
request, whenever it comes. Factors that can affect site responsiveness include:
The time it takes for a site to restart after an app pool recycles. This is the time it takes
to launch a web server process for the site when the site assemblies are no longer in
memory. (The platform assemblies are still in memory, since they are used by other
sites.) This situation is referred to as "cold site, warm framework startup" or just "cold
site startup."
How much memory the site occupies. Terms for this are "per-site memory consumption"
or "unshared working set."
The new performance improvements focus on both of these factors.
Requirements for New Performance Features
The requirements for the new features can be broken down into these categories:
Improvements that run on the .NET Framework 4.
Improvements that require the .NET Framework 4.5 but can run on any version of
Windows.
Improvements that are available only with .NET Framework 4.5 running on Windows 8.
Performance increases with each level of improvement that you are able to enable.
Some of the .NET Framework 4.5 improvements take advantage of broader performance
features that apply to other scenarios as well.
Sharing Common Assemblies
Requirement: .NET Framework 4 and Visual Studio 11 Developer Preview SDK
Different sites on a server often use the same helper assemblies (for example, assemblies
from a starter kit or sample application). Each site has its own copy of these assemblies in its
Bin directory. Even though the object code for the assemblies is identical, they're physically
separate assemblies, so each assembly has to be read separately during cold site startup and
kept separately in memory.
The new interning functionality solves this inefficiency and reduces both RAM requirements
and load time. Interning lets Windows keep a single copy of each assembly in the file system,
and individual assemblies in the site Bin folders are replaced with symbolic links to the single
copy. If an individual site needs a distinct version of the assembly, the symbolic link is
replaced by the new version of the assembly, and only that site is affected.
Sharing assemblies using symbolic links requires a new tool named aspnet_intern.exe, which
lets you create and manage the store of interned assemblies. It is provided as a part of the
Visual Studio 11 Developer Preview SDK. (However, it will work on a system that has only
the .NET Framework 4 installed, assuming you have installed the latest update.)
To make sure all eligible assemblies have been interned, you run aspnet_intern.exe
periodically (for example, once a week as a scheduled task). A typical use is as follows:
aspnet_intern -mode exec -sourcedir
"C:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files" -
interndir C:\ASPNETCommonAssemblies
To see all options, run the tool with no arguments.
Using multi-Core JIT compilation for faster startup
Requirement: .NET Framework 4.5
For a cold site startup, not only do assemblies have to be read from disk, but the site must be
JIT-compiled. For a complex site, this can add significant delays. A new general-purpose
technique in the .NET Framework 4.5 reduces these delays by spreading JIT-compilation
across available processor cores. It does this as much and as early as possible by using
information gathered during previous launches of the site. This functionality implemented by
the System.Runtime.ProfileOptimization.StartProfile method.
JIT-compiling using multiple cores is enabled by default in ASP.NET, so you do not need to do
anything to take advantage of this feature. If you want to disable this feature, make the
following setting in the Web.config file:
<configuration>
<!-- ... -->
<system.web>
<compilation profileGuidedOptimizations="None" />
<!-- ... -->
Tuning garbage collection to optimize for memory
Requirement: .NET Framework 4.5
Once a site is running, its use of the garbage-collector (GC) heap can be a significant factor in
its memory consumption. Like any garbage collector, the .NET Framework GC makes tradeoffs
between CPU time (frequency and significance of collections) and memory consumption
(extra space that is used for new, freed, or free-able objects). For previous releases, we have
provided guidance on how to configure the GC to achieve the right balance (for example, see
ASP.NET 2.0/3.5 Shared Hosting Configuration).
For the .NET Framework 4.5, instead of multiple standalone settings, a workload-defined
configuration setting is available that enables all of the previously recommended GC settings
as well as new tuning that delivers additional performance for the per-site working set.
To enable GC memory tuning, add the following setting to the Windows\Microsoft.NET\
Framework\v4.0.30319\aspnet.config file:
<configuration>
<!-- ... -->
<runtime>
<performanceScenario value="HighDensityWebHosting" />
<!-- ... -->
(If you're familiar with the previous guidance for changes to aspnet.config, note that this
setting replaces the old settings — for example, there is no need to set gcServer,
gcConcurrent, etc. You do not have to remove the old settings.)
Prefetching for web applications
Requirement: .NET Framework 4.5 running on Windows 8
For several releases, Windows has included a technology known as the prefetcher that reduces
the disk-read cost of application startup. Because cold startup is a problem predominantly for
client applications, this technology has not been included in Windows Server, which includes
only components that are essential to a server. Prefetching is now available in the latest
version of Windows Server, where it can optimize the launch of individual websites.
For Windows Server, the prefetcher is not enabled by default. To enable and configure the
prefetcher for high-density web hosting, run the following set of commands at the command
line:
sc config sysmain start=auto
reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session
Manager\Memory Management\PrefetchParameters" /v EnablePrefetcher /t
REG_DWORD /d 2 /f
reg add "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\
Prefetcher" /v MaxPrefetchFiles /t REG_DWORD /d 8192 /f
net start sysmain
Then, to integrate the prefetcher with ASP.NET applications, add the following to the
Web.config file:
<configuration>
<!-- ... -->
<system.web>
<compilation enablePrefetchOptimization="true" />
<!-- ... -->
ASP.NET Web Forms
Strongly Typed Data Controls
In ASP.NET 4.5, Web Forms includes some improvements for working with data. The first
improvement is strongly typed data controls. For Web Forms controls in previous versions of
ASP.NET, you display a data-bound value using Eval and a data-binding expression:
<ul>
<asp:Repeater runat="server" ID="customers">
<ItemTemplate>
<li>
First Name: <%# Eval("FirstName")%><br />
Last Name: <%# Eval("LastName")%><br />
</li>
</ItemTemplate>
</asp:Repeater>
</ul>
For two-way data binding, you use Bind:
<asp:FormView runat="server" ID="editCustomer">
<EditItemTemplate>
<div>
<asp:Label runat="server"
AssociatedControlID="firstName">
First Name:</asp:Label>
<asp:TextBox ID="firstName" runat="server"
Text='<%#Bind("FirstName") %>' />
</div>
<div>
<asp:Label runat="server"
AssociatedControlID="lastName">
First Name:</asp:Label>
<asp:TextBox ID="lastName" runat="server"
Text='<%#
Bind("LastName") %>' />
</div>
<asp:Button runat="server" CommandName="Update"/>
</EditItemTemplate>
</asp:FormView>
At run time, these calls use reflection to read the value of the specified member and then
display the result in the markup. This approach makes it easy to data bind against arbitrary,
unshaped data.
However, data-binding expressions like this don't support features like IntelliSense for
member names, navigation (like Go To Definition), or compile-time checking for these names.
To address this issue, ASP.NET 4.5 adds the ability to declare the data type of the data that a
control is bound to. You do this using the new ItemType property. When you set this property,
two new typed variables are available in the scope of data-binding expressions: Item and
BindItem. Because the variables are strongly typed, you get the full benefits of the Visual
Studio development experience.
For two-way data-binding expressions, use the BindItem variable:
<asp:FormView runat="server" ID="editCustomer">
<EditItemTemplate>
<div>
<asp:Label runat="server"
AssociatedControlID="firstName">
First Name:</asp:Label>
<asp:TextBox ID="firstName" runat="server"
Text='<%#BindItem.FirstName %>' />
</div>
<div>
<asp:Label runat="server"
AssociatedControlID="lastName">
First Name:</asp:Label>
<asp:TextBox ID="lastName" runat="server"
Text='<%#BindItem.LastName %>' />
</div>
<asp:Button runat="server" CommandName="Update"/>
</EditItemTemplate>
</asp:FormView>
Most controls in the ASP.NET Web Forms framework that support data binding have been
updated to support the ItemType property.
Model Binding
Model binding extends data binding in ASP.NET Web Forms controls to work with code-
focused data access. It incorporates concepts from the ObjectDataSource control and from
model binding in ASP.NET MVC.
Selecting data
To configure a data control to use model binding to select data, you set the control's
SelectMethod property to the name of a method in the page's code. The data control calls the
method at the appropriate time in the page life cycle and automatically binds the returned
data. There's no need to explicitly call the DataBind method.
In the following example, the GridView control is configured to use a method named
GetCategories:
<asp:GridView ID="categoriesGrid"
runat="server"
ItemType="WebApplication1.Model.Category"
SelectMethod="GetCategories" AutoGenerateColumns="false">
<Columns>
<asp:BoundField DataField="CategoryID" HeaderText="ID" />
<asp:BoundField DataField="CategoryName" HeaderText="Name" />
<asp:BoundField DataField="Description" HeaderText="Description"
/>
<asp:TemplateField HeaderText="# of Products">
<ItemTemplate><%# Item.Products.Count %></ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
You create the GetCategories method in the page's code. For a simple select operation, the
method needs no parameters and should return an IEnumerable or IQueryable object. If the
new ItemType property is set (which enables strongly typed data-binding expressions, as
explained under Strongly Typed Data Controls earlier), the generic versions of these interfaces
should be returned — IEnumerable<T> or IQueryable<T>, with the T parameter matching the
type of the ItemType property (for example, IQueryable<Category>).
The following example shows the code for a GetCategories method. This example uses the
Entity Framework Code First model with the Northwind sample database. The code makes
sure that the query returns details of the related products for each category by way of the
Include method. (This ensures that the TemplateField element in the markup displays the
count of products in each category without requiring an n+1 select.)
public IQueryable<Category>
GetCategories()
{
var db = new Northwind();
return db.Categories.Include(c => c.Products);
}
When the page runs, the GridView control calls the GetCategories method automatically and
renders the returned data using the configured fields:
Because the select method returns an IQueryable object, the GridView control can further
manipulate the query before executing it. For example, the GridView control can add query
expressions for sorting and paging to the returned IQueryable object before it is executed, so
that those operations are performed by the underlying LINQ provider. In this case, Entity
Framework will ensure those operations are performed in the database.
The following example shows the GridView control modified to allow sorting and paging:
<asp:GridView ID="categoriesGrid"
runat="server"
AutoGenerateColumns="false"
AllowSorting="true" AllowPaging="true" PageSize="5"
ItemType="WebApplication1.Model.Category" DataKeyNames="CategoryID"
SelectMethod="GetCategories"
UpdateMethod="UpdateCategory">
<Columns>
<asp:BoundField DataField="CategoryID" HeaderText="ID"
SortExpression="CategoryID" />
<asp:BoundField DataField="CategoryName" HeaderText="Name"
SortExpression="CategoryName" />
<asp:BoundField DataField="Description" HeaderText="Description"
/>
<asp:TemplateField HeaderText="# of Products">
<ItemTemplate><%# Item.Products.Count %></ItemTemplate>
</asp:TemplateField>
</Columns>
<EmptyDataTemplate>No categories found with a product count of
<%# minProductsCount.SelectedValue %></EmptyDataTemplate>
</asp:GridView>
Now when the page runs, the control can make sure that only the current page of data is
displayed and that it’s ordered by the selected column:
To filter the returned data, parameters have to be added to the select method. These
parameters will be populated by the model binding at run time, and you can use them to alter
the query before returning the data.
For example, assume that you want to let users filter products by entering a keyword in the
query string. You can add a parameter to the method and update the code to use the
parameter value:
public IQueryable<Product>
GetProducts(string keyword)
{
IQueryable<Product> query = _db.Products;
if (!String.IsNullOrWhiteSpace(keyword))
{
query = query.Where(p => p.ProductName.Contains(keyword));
}
return query;
}
This code includes a Where expression if a value is provided for keyword and then returns the
query results.
Value providers
The previous example was not specific about where the value for the keyword parameter was
coming from. To indicate this information, you can use a parameter attribute. For this
example, you can use the QueryStringAttribute class that’s in the System.Web.ModelBinding
namespace:
public IQueryable<Product>
GetProducts([QueryString]string keyword)
{
IQueryable<Product> query = _db.Products;
if (!String.IsNullOrWhiteSpace(keyword))
{
query = query.Where(p => p.ProductName.Contains(keyword));
}
return query;
}
This instructs model binding to try to bind a value from the query string to the keyword
parameter at run time. (This might involve performing type conversion, although it doesn't in
this case.) If a value cannot be provided and the type is non-nullable, an exception is thrown.
The sources of values for these methods are referred to as value providers, and the
parameter attributes that indicate which value provider to use are referred to as value
provider attributes. Web Forms will include value providers and corresponding attributes for
all of the typical sources of user input in a Web Forms application, such as the query string,
cookies, form values, controls, view state, session state, and profile properties. You can also
write custom value providers.
By default, the parameter name is used as the key to find a value in the value provider
collection. In the example, the code will look for a query-string value named keyword (for
example, ~/default.aspx?keyword=chef). You can specify a custom key by passing it as an
argument to the parameter attribute. For example, to use the value of the query-string
variable named q, you could do this:
public IQueryable<Product>
GetProducts([QueryString("q")]string keyword)
{
IQueryable<Product> query = _db.Products;
if (!String.IsNullOrWhiteSpace(keyword))
{
query = query.Where(p => p.ProductName.Contains(keyword));
}
return query;
}
If this method is in the page's code, users can filter the results by passing a keyword using
the query string:
Model binding accomplishes many tasks that you would otherwise have to code by hand:
reading the value, checking for a null value, attempting to convert it to the appropriate type,
checking whether the conversion was successful, and finally, using the value in the query.
Model binding results in far less code and in the ability to reuse the functionality throughout
your application.
Filtering by values from a control
Suppose you want to extend the example to let the user choose a filter value from a drop-
down list. Add the following drop-down list to the markup and configure it to get its data from
another method using the SelectMethod property:
<asp:Label runat="server" AssociatedControlID="categories"
Text="Select a category to show products for: " />
<asp:DropDownList runat="server" ID="categories"
SelectMethod="GetCategories" AppendDataBoundItems="true"
DataTextField="CategoryName" DataValueField="CategoryID"
AutoPostBack="true">
<asp:ListItem Value="" Text="- all -" />
</asp:DropDownList>
Typically you would also add an EmptyDataTemplate element to the GridView control so that
the control will display a message if no matching products are found:
<asp:GridView ID="productsGrid"
runat="server" DataKeyNames="ProductID"
AllowPaging="true" AllowSorting="true" AutoGenerateColumns="false"
SelectMethod="GetProducts" >
<Columns>
<asp:BoundField DataField="ProductID" HeaderText="ID" />
<asp:BoundField DataField="ProductName" HeaderText="Name"
SortExpression="ProductName" />
<asp:BoundField DataField="UnitPrice" HeaderText="Unit Price"
SortExpression="UnitPrice" />
<asp:BoundField DataField="UnitsInStock" HeaderText="# in Stock"
SortExpression="UnitsInStock" />
</Columns>
<EmptyDataTemplate>
No products matching the filter criteria were
found</EmptyDataTemplate>
</asp:GridView>
In the page code, add the new select method for the drop-down list:
public IQueryable<Category>
GetCategories()
{
return _db.Categories;
}
Finally, update the GetProducts select method to take a new parameter that contains the ID
of the selected category from the drop-down list:
public IQueryable<Product>
GetProducts(
[QueryString("q")] string keyword,
[Control("categories")] int? categoryId)
{
IQueryable<Product> query = _db.Products;
if (!String.IsNullOrWhiteSpace(keyword))
{
query = query.Where(p => p.ProductName.Contains(keyword));
}
if (categoryId.HasValue && categoryId > 0)
{
query = query.Where(p => p.CategoryID == categoryId);
}
return query;
}
Now when the page runs, users can select a category from the drop-down list, and the
GridView control is automatically re-bound to show the filtered data. This is possible because
model binding tracks the values of parameters for select methods and detects whether any
parameter value has changed after a postback. If so, model binding forces the associated
data control to re-bind to the data.
HTML Encoded Data-Binding Expressions
You can now HTML-encode the result of data-binding expressions. Add a colon (:) to the end
of the <%# prefix that marks the data-binding expression:
<asp:TemplateField HeaderText="Name">
<ItemTemplate><%#: Item.Products.Name %></ItemTemplate>
</asp:TemplateField>
Unobtrusive Validation
You can now configure the built-in validator controls to use unobtrusive JavaScript for client-
side validation logic. This significantly reduces the amount of JavaScript rendered inline in the
page markup and reduces the overall page size. You can configure unobtrusive JavaScript for
validator controls in any of these ways:
Globally by adding the following setting to the <appSettings> element in the Web.config
file:
<add name="ValidationSettings:UnobtrusiveValidationMode" value="WebForms"
/>
Globally by setting the static
System.Web.UI.ValidationSettings.UnobtrusiveValidationMode property to
UnobtrusiveValidationMode.WebForms (typically in the Application_Start method in the
Global.asax file).
Individually for a page by setting the new UnobtrusiveValidationMode property of the
Page class to UnobtrusiveValidationMode.WebForms.
HTML5 Updates
Some improvements have been made to Web Forms server controls to take advantage of new
features of HTML5:
The TextMode property of the TextBox control has been updated to support the new
HTML5 input types like email, datetime, and so on.
The FileUpload control now supports multiple file uploads from browsers that support this
HTML5 feature.
Validator controls now support validating HTML5 input elements.
New HTML5 elements that have attributes that represent a URL now support
runat="server". As a result, you can use ASP.NET conventions in URL paths, like the ~
operator to represent the application root (for example, <video runat="server"
src="~/myVideo.wmv" />).
The UpdatePanel control has been fixed to support posting HTML5 input fields.
ASP.NET MVC 4
ASP.NET MVC 4 Beta is now included with Visual Studio 11 Beta. ASP.NET MVC is a framework
for developing highly testable and maintainable Web applications by leveraging the Model-
View-Controller (MVC) pattern. ASP.NET MVC 4 makes it easy to build applications for the
mobile Web and includes ASP.NET Web API, which helps you build HTTP services that can
reach any device. For more information, see the ASP.NET MVC 4 Release Notes.
ASP.NET Web Pages 2
New features include the following:
New and updated site templates.
Adding server-side and client-side validation using the Validation helper.
The ability to register scripts using an assets manager.
Enabling logins from Facebook and other sites using OAuth and OpenID.
Adding maps using the Maps helper.
Running Web Pages applications side-by-side.
Rendering pages for mobile devices.
For more information about these features and full-page code examples, see The Top Features in
Web Pages 2 Beta.
Visual Web Developer 11 Beta
This section provides information about improvements for web development in Visual Web
Developer 11 Beta and Visual Studio 2012 Release Candidate.
Project Sharing Between Visual Studio 2010 and Visual Studio 2012 Release Candidate (Project Compatibility)
Until Visual Studio 2012 Release Candidate, opening an existing project in a newer version of
Visual Studio launched the Conversion Wizard. This forced an upgrade of the content (assets)
of a project and solution to new formats that were not backward compatible. Therefore, after
the conversion you could not open the project in the older version of Visual Studio.
Many customers have told us that this was not the right approach. In Visual Studio 11 Beta,
we now support sharing projects and solutions with Visual Studio 2010 SP1. This means that if
you open a 2010 project in Visual Studio 2012 Release Candidate, you will still be able to
open the project in Visual Studio 2010 SP1.
Note: A few types of projects cannot be shared between Visual Studio 2010 SP1 and Visual
Studio 2012 Release Candidate. These include some older projects (such as ASP.NET MVC 2
projects) or projects for special purposes (such as Setup projects).
When you open a Visual Studio 2010 SP1 Web project for the first time in Visual Studio 11
Beta, the following properties are added to the project file:
FileUpgradeFlags
UpgradeBackupLocation
OldToolsVersion
VisualStudioVersion
VSToolsPath
FileUpgradeFlags, UpgradeBackupLocation, and OldToolsVersion are used by the process that
upgrades the project file. They have no impact on working with the project in Visual Studio
2010.
VisualStudioVersion is a new property used by MSBuild 4.5 that indicates the version of Visual
Studio for the current project. Because this property didn’t exist in MSBuild 4.0 (the version of
MSBuild that Visual Studio 2010 SP1 uses), we inject a default value into the project file.
The VSToolsPath property is used to determine the correct .targets file to import from the
path represented by the MSBuildExtensionsPath32 setting.
There are also some changes related to Import elements. These changes are required in order
to support compatibility between both versions of Visual Studio.
Note: If a project is being shared between Visual Studio 2010 SP1 and Visual Studio 11 Beta
on two different computers, and if the project includes a local database in the App_Data
folder, you must make sure that the version of SQL Server used by the database is installed
on both computers.
Configuration Changes in ASP.NET 4.5 Website Templates
The following changes have been made to the default Web.config file for site that are created
using website templates in Visual Studio 2012 Release Candidate:
In the <httpRuntime> element, the encoderType attribute is now set by default to use
the AntiXSS types that were added to ASP.NET. For details, see AntiXSS Library.
Also in the <httpRuntime> element, the requestValidationMode attribute is set to
"4.5". This means that by default, request validation is configured to use deferred ("lazy")
validation. For details, see New ASP.NET Request Validation Features.
The <modules> element of the <system.webServer> section does not contain a
runAllManagedModulesForAllRequests attribute. (Its default value is false.) This
means that if you are using a version of IIS 7 that has not been updated to SP1, you
might have issues with routing in a new site. For more information, see Native Support in IIS
7 for ASP.NET Routing.
These changes do not affect existing applications. However, they might represent a difference
in behavior between existing websites and new websites that you create for ASP.NET 4.5
using the new templates.
Native Support in IIS 7 for ASP.NET Routing
This is not a change to ASP.NET as such, but a change in templates for new website projects
that can affect you if you are working a version of IIS 7 that has not had the SP1 update
applied.
In ASP.NET, you can add the following configuration setting to applications in order to support
routing:
<configuration>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
<!-- more -->
</modules>
</system.webServer>
</configuration>
When runAllManagedModulesForAllRequests is true, a URL like
http://mysite/myapp/home goes to ASP.NET, even though there is no .aspx, .mvc, or
similar extension on the URL.
An update that was made to IIS 7 makes the runAllManagedModulesForAllRequests
setting unnecessary and supports ASP.NET routing natively. (For information about the
update, see the Microsoft Support article An update is available that enables certain IIS 7.0 or IIS 7.5
handlers to handle requests whose URLs do not end with a period.)
If your website is running on IIS 7 and if IIS has been updated, you do not need to set
runAllManagedModulesForAllRequests to true. In fact, setting it to true is not
recommended, because it adds unnecessary processing overhead to request. When this
setting is true, all requests, including those for .htm, .jpg, and other static files, also go
through the ASP.NET request pipeline.
If you create a new ASP.NET 4.5 website using the templates that are provided in Visual
Studio 2012 RC, the configuration for the website does not include the
runAllManagedModulesForAllRequests setting. This means that by default the setting is
false.
If you then run the website on Windows 7 without SP1 installed, IIS 7 will not include the
required update. As a consequence, routing will not work and you will see errors. If you have a
problem where routing does not work, you can do either the following:
Update Windows 7 to SP1, which will add the update to IIS 7.
Install the update that's described in the Microsoft Support article listed previously.
Set runAllManagedModulesForAllRequests to true in that website's Web.config file.
Note that this will add some overhead to requests.
HTML Editor
Smart Tasks
In Design view, complex properties of server controls often have associated dialog boxes and
wizards to make it easy to set them. For example, you can use a special dialog box to add a
data source to a Repeater control or add columns to a GridView control.
However, this type of UI help for complex properties has not been available in Source view.
Therefore, Visual Studio 11 introduces Smart Tasks for Source view. Smart Tasks are context-
aware shortcuts for commonly used features in the C# and Visual Basic editors.
For ASP.NET Web Forms controls, Smart Tasks appear on server tags as a small glyph when
the insertion point is inside the element:
The Smart Task expands when you click the glyph or press CTRL+. (dot), just as in the code
editors. It then displays shortcuts that are similar to the Smart Tasks in Design view.
For example, the Smart Task in the previous illustration shows the GridView Tasks options. If
you choose Edit Columns, the following dialog box is displayed:
Filling in the dialog box sets the same properties you can set in Design view. When you click
OK, the markup for the control is updated with the new settings:
WAI-ARIA support
Writing accessible websites is becoming increasingly important. The WAI-ARIA accessibility
standard defines how developers should write accessible websites. This standard is now fully
supported in Visual Studio.
For example, the role attribute now has full IntelliSense:
The WAI-ARIA standard also introduces attributes that are prefixed with aria- that let you add
semantics to an HTML5 document. Visual Studio also fully supports these aria- attributes:
New HTML5 snippets
To make it faster and easier to write commonly used HTML5 markup, Visual Studio includes a
number of snippets. An example is the video snippet:
To invoke the snippet, press Tab twice when the element is selected in IntelliSense:
This produces a snippet that you can customize.
Extract to user control
In large web pages, it can be a good idea to move individual pieces into user controls. This
form of refactoring can help increase the readability of the page and can simplify the page
structure.
To make this easier, when you edit Web Forms pages in Source view, you can now select text
in a page, right-click it, and then choose Extract to User Control:
IntelliSense for code nuggets in attributes
Visual Studio has always provided IntelliSense for server-side code nuggets in any page or
control. Now Visual Studio includes IntelliSense for code nuggets in HTML attributes as well.
This makes it easier to create data-binding expressions:
Automatic renaming of matching tag when you rename an opening or closing tag
If you rename an HTML element (for example, you change a div tag to be a header tag), the
corresponding opening or closing tag also changes in real time.
This helps avoid the error where you forget to change a closing tag or change the wrong one.
Event handler generation
Visual Studio now includes features in Source view to help you write event handlers and bind
them manually. If you are editing an event name in Source view, IntelliSense displays
<Create New Event>, which will create an event handler in the page's code that has the right
signature:
By default, the event handler will use the control's ID for the name of the event-handling
method:
The resulting event handler will look like this (in this case, in C#):
Smart indent
When you press Enter while inside an empty HTML element, the editor will put the insertion
point in the right place:
If you press Enter in this location, the closing tag is moved down and indented to match the
opening tag. The insertion point is also indented:
Auto-reduce statement completion
The IntelliSense list in Visual Studio now filters based on what you type so that it displays only
relevant options:
IntelliSense also filters based on the title case of the individual words in the IntelliSense list.
For example, if you type "dl", both dl and asp:DataList are displayed:
This feature makes it faster to get statement completion for known elements.
JavaScript Editor
The JavaScript editor in Visual Studio 2012 Release Candidate is completely new and it greatly
improves the experience of working with JavaScript in Visual Studio.
Code outlining
Outlining regions are now automatically created for all functions, allowing you to collapse
parts of the file that aren’t pertinent to your current focus.
Brace matching
When you put the insertion point on an opening or closing brace, the editor highlights the
matching one.
Go to Definition
The Go to Definition command lets you jump to the source for a function or variable.
ECMAScript5 support
The editor supports the new syntax and APIs in ECMAScript5, the latest version of the
standard that describes the JavaScript language.
DOM IntelliSense
IntelliSense for DOM APIs has been improved, with support for many new HTML5 APIs
including querySelector, DOM Storage, cross-document messaging, and canvas. DOM
IntelliSense is now driven by a single simple JavaScript file, rather than by a native type
library definition. This makes it easy to extend or replace.
VSDOC signature overloads
Detailed IntelliSense comments can now be declared for separate overloads of JavaScript
functions by using the new <signature> element, as shown in this example:
function GetOrSet(key, value) {
/// <signature>
/// <summary>Gets the value</summary>
/// <param name="key" type="String">The key to get the value
for</param>
/// <returns type="String" />
/// </signature>
/// <signature>
/// <summary>Sets the value</summary>
/// <param name="key" type="String">The key to set the value
for</param>
/// <param name="value" type="String">The value to set</param>
/// <returns type="MyLib" />
/// </signature>
if (value) {
values[key] = value;
return this;
} else {
return values[key];
}
}
Implicit references
You can now add JavaScript files to a central list that will be implicitly included in the list of
files that any given JavaScript file or block references, meaning you’ll get IntelliSense for its
contents. For example, you can add jQuery files to the central list of files, and you’ll get
IntelliSense for jQuery functions in any JavaScript block of file, whether you’ve referenced it
explicitly (using /// <reference />) or not.
CSS Editor
Auto-reduce statement completion
The IntelliSense list for CSS now filters based on the CSS properties and values supported by
the selected schema.
IntelliSense also supports title case searches:
Hierarchical indentation
The CSS editor uses indentation to display hierarchical rules, which gives you an overview of
how the cascading rules are logically organized. In the following example, the #list a selector
is a cascading child of list and is therefore indented.
The following example shows more complex inheritance:
The indentation of a rule is determined by its parent rules. Hierarchical indentation is enabled
by default, but you can disable it the Options dialog box (Tools, Options from the menu bar):
CSS hacks support
Analysis of hundreds of real-world CSS files shows that CSS hacks are very common, and now
Visual Studio supports the most widely used ones. This support includes IntelliSense and
validation of the star (*) and underscore (_) property hacks:
Typical selector hacks are also supported so that hierarchical indentation is maintained even
when they are applied. A typical selector hack used to target Internet Explorer 7 is to prepend
a selector with *:first-child + html. Using that rule will maintain the hierarchical indentation:
Vendor specific schemas (-moz-, -webkit)
CSS3 introduces many properties that have been implemented by different browsers at
different times. This previously forced developers to code for specific browsers by using
vendor-specific syntax. These browser-specific properties are now included in IntelliSense.
Commenting and uncommenting support
You can now comment and uncomment CSS rules using the same shortcuts that you use in
the code editor (Ctrl+K,C to comment and Ctrl+K,U to uncomment).
Color picker
In previous versions of Visual Studio, IntelliSense for color-related attributes consisted of a
drop-down list of named color values. That list has been replaced by a full-featured color
picker.
When you enter a color value, the color picker is displayed automatically and presents a list of
previously used colors followed by a default color palette. You can select a color using the
mouse or the keyboard.
The list can be expanded into a complete color picker. The picker lets you control the alpha
channel by automatically converting any color into RGBA when you move the opacity slider:
Snippets
Snippets in the CSS editor make it easier and faster to create cross-browser styles. Many
CSS3 properties that require browser-specific settings have now been rolled into snippets.
CSS snippets support advanced scenarios (like CSS3 media queries) by typing the at-symbol
(@), which shows the IntelliSense list.
When you select @media value and press Tab, the CSS editor inserts the following snippet:
As with snippets for code, you can create your own CSS snippets.
Custom regions
Named code regions, which are already available in the code editor, are now available for CSS
editing. This lets you easily group related style blocks.
When a region is collapsed it displays the name of the region:
Page Inspector
Page Inspector is a tool that renders a web page (HTML, Web Forms, ASP.NET MVC, or Web
Pages) in the Visual Studio IDE and lets you examine both the source code and the resulting
output. For ASP.NET pages, Page Inspector lets you determine which server-side code has
produced the HTML markup that is rendered to the browser.
For more information about Page Inspector, please see the following tutorials:
Using Page Inspector in ASP.NET MVC
Using Page Inspector in ASP.NET Web Forms
Publishing
Publish profiles
In Visual Studio 2010, publishing information for Web application projects is not stored in
version control and is not designed for sharing with others. In Visual Studio 2012 Release
Candidate, the format of the publish profile has been changed. It has been made a team
artifact, and it is now easy to leverage from builds based on MSBuild. Build configuration
information is in the Publish dialog box so that you can easily switch build configurations
before publishing.
Publish profiles are stored in the PublishProfiles folder. The location of the folder depends on
what programming language you are using:
C#: Properties\PublishProfiles
Visual Basic: My Project\PublishProfiles
Each profile is an MSBuild file. During publishing, this file is imported into the project's
MSBuild file. In Visual Studio 2010, if you want to make changes to the publish or package
process, you have to put your customizations in a file named ProjectName.wpp.targets. This
is still supported, but you can now put your customizations in the publish profile itself. That
way, the customizations will be used only for that profile.
You can now also leverage publish profiles from MSBuild. To do so, use the following
command when you build the project:
msbuild.exe project.csproj /t:WebPublish /p:PublishProfile=ProfileName
The project.csproj value is the path of the project, and ProfileName is the name of the profile
to publish. Alternatively, instead of passing the profile name for the PublishProfile property,
you can pass in the full path to the publish profile.
ASP.NET precompilation and merge
For Web application projects, Visual Studio 2012 Release Candidate adds an option on the
Package/Publish Web properties page that lets you precompile and merge your site's content
when you publish or package the project. To see these options, right-click the project in
Solution Explorer, choose Properties, and then choose the Package/Publish Web property
page. The following illustration shows the Precompile this application before publishing
option.
When this option is selected, Visual Studio precompiles the application whenever you publish
or package the web application. If you want to control how the site is precompiled or how
assemblies are merged, click the Advanced button to configure those options.
IIS Express
The default web server for testing web projects in Visual Studio is now IIS Express. The Visual
Studio Development Server is still an option for local web server during development, but IIS
Express is now the recommended server. The experience of using IIS Express in Visual Studio
11 Beta is very similar to using it in Visual Studio 2010 SP1.
Disclaimer
This is a preliminary document and may be changed substantially prior to final commercial
release of the software described herein.
The information contained in this document represents the current view of Microsoft
Corporation on the issues discussed as of the date of publication. Because Microsoft must
respond to changing market conditions, it should not be interpreted to be a commitment on
the part of Microsoft, and Microsoft cannot guarantee the accuracy of any information
presented after the date of publication.
This White Paper is for informational purposes only. MICROSOFT MAKES NO WARRANTIES,
EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS DOCUMENT.
Complying with all applicable copyright laws is the responsibility of the user. Without limiting
the rights under copyright, no part of this document may be reproduced, stored in or
introduced into a retrieval system, or transmitted in any form or by any means (electronic,
mechanical, photocopying, recording, or otherwise), or for any purpose, without the express
written permission of Microsoft Corporation.
Microsoft may have patents, patent applications, trademarks, copyrights, or other intellectual
property rights covering subject matter in this document. Except as expressly provided in any
written license agreement from Microsoft, the furnishing of this document does not give you
any license to these patents, trademarks, copyrights, or other intellectual property.
Unless otherwise noted, the example companies, organizations, products, domain names, e-
mail addresses, logos, people, places and events depicted herein are fictitious, and no
association with any real company, organization, product, domain name, email address, logo,
person, place or event is intended or should be inferred.
© 2012 Microsoft Corporation. All rights reserved.
Microsoft and Windows are either registered trademarks or trademarks of Microsoft
Corporation in the United States and/or other countries.
The names of actual companies and products mentioned herein may be the trademarks of
their respective owners.
By Microsoft ASP.NET Team, ASP.NET is a free web framework for building great Web sites
and Web applications using HTML, CSS and JavaScript.
Comments (24) RSS Feed
You must be logged in to leave a comment.Show Comments
Table of Contents
Latest
ASP.NET and Web Tools 2012.2 Roadmap
ASP.NET and Web Tools 2012.2 Release Notes
Custom MVC Template
Facebook Application Template Tutorial (C#)
New Web Optimization Pre-Release Package on NuGet
OData support in ASP.NET Web API
ASP.NET Web API Tracing
Introducing the ASP.NET Web API Help Page
Windows Azure Authentication
ASP.NET Web API Samples
ASP.NET and Web Tools 2012.2 RC
ASP.NET MVC Facebook Birthday App
Visual Studio
Visual Studio 2012 and .NET Framework 4.5 is RELEASED
Visual Studio 2012 and .NET Framework 4.5 Released to the Web!
Visual Studio 2012 HTML Editing Features
Visual Studio 2012 CSS Editor
Visual Studio 2012 JavaScript Editor
Visual Studio 2012 Page Inspector
Visual Studio 2012 Web Publishing Improvements
Visual Studio Express 2012
Visual Studio Ultimate 2012
HTML Editor / Smart Tasks
MSDN: Visual Studio 2012
ASP.NET
ASP.NET 4.5, ASP.NET MVC 4, ASP.NET Web Pages 2, and Visual Studio 2012 for web developers
Get the scoop on the ASP.NET 4.5, ASP.NET MVC 4, ASP.NET Web Pages 2, and Visual Studio 11 Developer
Previews
What's New in ASP.NET 4.5 and Visual Studio 2012
What's New in ASP.NET 4.5 Lab
New Tools and New Content - ASP.NET, Visual Studio 11 Web and .NET 4.5 Developer Preview (with
commentary)
Bundling and Optimization
Async and Await
OAuth in the Default ASP.NET 4.5 Templates
Strongly Typed Data Controls
OAuth/OpenID Support for WebForms, MVC and WebPages
ASP.NET and Web Tools 2012.2
ASP.NET MVC
ASP.NET MVC
ASP.NET MVC
ASP.NET MVC 4 Mobile Features
ASP.NET MVC 4 for Visual Studio 2010 SP1
ASP.NET MVC Facebook Birthday App
Hands On Labs
ASP.NET Web Pages
ASP.NET Web Pages
Top Features in ASP.NET Web Pages 2
ASP.NET Web API
ASP.NET Web API
OData support in ASP.NET Web API (Preview)
ASP.NET Web API Tracing (Preview)
Introducing the ASP.NET Web API Help Page (Preview)
ASP.NET Web API Preview Samples
ASP.NET Web API Released and a Preview of What’s Next
Hands On Labs
ASP.NET Web Forms
ASP.NET Web Forms
Introduction and Overview
ASP.NET 4.5 Web Forms Model Binding
ASP.NET 4.5 Web Forms Strong Typed Data Controls
Model Binding #1: Selecting Data
Model Binding #2: Filtering Data
Hands On Labs
SignalR
SignalR and Web Sockets
OWIN and Katana
An Overview of Project Katana
This site is managed for Microsoft by Neudesic, LLC. | © 2013 Microsoft. All rights reserved.
Privacy Statement|
Terms of Use|
Site Feedback|
Advertise With Us|
CMS by Umbraco Follow Us On:
Twitter|
Facebook Microsoft Feedback on ASP.NET|
File Bugs<a
href="http://www.omniture.com" title="Web Analytics"><img
src="http://msstonojsaspnet.112.2O7.net/b/ss/msstonojsaspnet/1/H.20.2--NS/0" height="1"
width="1" border="0" alt="" /></a>
ArticleContentPic 2012-02-29 Whitepaper 30
top related