AJAX Quickstarts   |   Silverlight Quickstarts   |   Dynamic Data Controls Quickstarts   |   Services Quickstarts   |   Dynamic Languages Quickstarts   |   ASP.NET AJAX Home   |      |  I want my samples in...     

ASP.NET and Dynamic Languages: Quickstart Tutorial

ASP.NET Futures (July 2007): Introduction to Dynamic Languages for ASP.NET

In the ASP.NET Futures release, the ASP.NET Dynamic Language Runtime (DLR) provides a layer for integrating dynamic languages with the common language runtime. This documentation covers:

  • ASP.NET features supported by dynamic languages.

  • How code is handled in dynamic-language pages.

With Microsoft IronPython and Managed JScript for ASP.NET, developers can use popular dynamic languages for the .NET Framework to create compelling Web applications. IronPython and Managed JScript for ASP.NET are free extensions to ASP.NET that are targeted at:

  • ASP.NET developers who want to enjoy the simplicity and flexibility of a dynamic language.
  • Python developers looking to harness the power of ASP.NET and its rapid application development (RAD) environment.

Python’s clean object-oriented design, dynamic nature, richness of expression, ease of use, and concise syntax has won over many users in the last several years. IronPython is an implementation of the Python programming language running on the .NET Framework. It is well integrated with the rest of the .NET Framework and makes all .NET libraries easily available to Python programmers, while maintaining full compatibility with the Python language. To learn more about IronPython and to download the complete source code, please visit www.codeplex.com/ironpython.

Managed JScript is a preliminary implementation of JScript (the Microsoft implementation of ECMAScript) as a dynamic language. Implementations of Ruby and Visual Basic are under development. Future releases will expose hosting interfaces and the API for integrating other languages.

Note   Managed JScript is a separate language implementation from JScript.NET. JScript.NET is a version of JScript for managed code, but it is not a true dynamic language.

In the ASP.NET Futures (May 2007) release, support for dynamic languages in ASP.NET was expanded from the earlier support for IronPython for ASP.NET. Support for dynamic languages in ASP.NET is built on the Dynamic Language Runtime (DLR), a new platform currently under development at Microsoft. The DLR simplifies hosting dynamic languages on the common language runtime.

The addition of support for a wide variety of dynamic languages gives ASP.NET users a new set of tools and new flexibility for building Web applications. The following walkthroughs in this section illustrate some of the functionality of dynamic languages in ASP.NET.

In addition, dynamic languages work well with dynamic data controls for ASP.NET, a set of server controls that simplify the creation of data-driven Web applications. For more information, see Introduction to Dynamic Data Controls for ASP.NET and Walkthrough: Using Dynamic Data Controls with ASP.NET.

ASP.NET Features Supported by Dynamic Languages

If you already develop .NET pages, using dynamic language pages will not require a great deal of new learning. Most standard ASP.NET features are supported, including the following:

  • Pages (.aspx files), user controls (.ascx files), and master pages (.master files).
  • Server controls; that is, elements with the runat="server" attribute.
  • Code that is included either inline or in separate code files. There are some differences from the standard ASP.NET compilation model, which are discussed later.
  • Code snippets; that is, <% ... %>, <%= ... %>, and <%# ... %>.

Application File

Dynamic languages for ASP.NET support a file similar to the Global.asax file. The file is named Global.ext, where ext is the language-specific extension. For example, the extension for IronPython files is .py, so the file name is Global.py.

Unlike the Global.asax file, which contains a directive (<%@ %> element) and a script block with a runat="server" attribute, the Global.ext file contains only code. For example, a simple global application file might contain code like the following:

		
def Application_BeginRequest(app):
    app.Response.Write('Hello application!')
IronPython

App_Script Directory

A dynamic language application contains an App_Script folder that is similar to the App_Code directory, except that it contains dynamic-language script files instead of static language code files. The purpose is the same, however; files in this directory contain classes that can be used by code anywhere in the application.

Generic HTTP Handlers

A dynamic language application can contain an HTTP handler that is the equivalent of an .ashx file in a standard ASP.NET application, although there are some differences. Dynamic language handlers are implemented as .aspx files. As with the Global.ext file, handlers in dynamic language applications contain only code. For example, a simple dynamic language handler named HelloWorldHandler.aspx might contain the following:

		
<%@ Page Language="IronPython" %>
<Script runat="server">

Response.ContentType = "text/plain"
Response.Write("Hello World")

</Script>
IronPython

HTTP Handler Example in IronPython
Run Sample View Source
HTTP Handler Example in Managed JScript
Run Sample View Source

Features Not Supported

The dynamic languages for ASP.NET feature do not currently support an equivalent of Web services (.asmx files). The Web service architecture works only with standard .NET Framework types, which can be difficult to create with dynamic languages. In addition, Web service class methods must be decorated with special metadata attributes such as WebMethodAttribute, and many dynamic languages have no syntax for applying attributes.

In the .NET Framework version 2.0, dynamic languages require full trust to emit Microsoft intermediate language (MSIL) for compilation at run time.

How Code Is Handled in Dynamic Language Pages

One difference between managed code and dynamic languages is the compilation model. Dynamic languages do not use CodeDOM, the core of the code-generation model for standard ASP.NET pages. The standard code-handling model requires inheriting from a base class and overriding members with specific type signatures. This can be problematic for dynamic languages.

In contrast to the standard compilation model, in which all user code in a page becomes part of a generated source file, each piece of dynamic language code in a page is treated as an individual entity. The implications of this are best seen by considering the various types of user code.

Code in <script> Elements

In standard ASP.NET pages, all user code in <script> elements that have the runat="server" attribute becomes part of the generated class. In contrast, in dynamic language pages, no new class is generated. Instead, ASP.NET directly instantiates the class specified by the inherits attribute. In this respect, the term "inherits" is inaccurate for dynamic language pages, because no inheritance occurs.

Instead of becoming part of a class, the code in a <script> element becomes a kind of companion code for the ScriptPage class. For example, the Page_Load method shown in the following example is not part of any class.

		
<script runat="server">
def Page_Load(sender, args):
    Response.Write("<p>Page_Load!</p>")
</script>
IronPython

Instead, members of the ScriptPage class, such as Response in this example, are injected by ASP.NET so that they are directly available to your code. The effect is that the members appear to be part of the class.

In dynamic language terminology, the code in the script block lives in a module. Usually there is one module associated with each HTTP request.

Code-behind Files

Everything that applies to code in <script> elements applies also to code in separate files. In the standard model, the code file contains a partial class declaration, which the compiler merges with the generated class. With dynamic languages, however, there is no class declaration in the code file. Instead, methods appear directly in the file, outside of any containing construct. Therefore, as with normal ASP.NET pages, the question of where to put your dynamic language code is purely a matter of personal preference

Code Snippets

Snippet expressions and statements (that is, <%= ... %> and <% ... %>) also execute in the context of the module created for the code belonging to the page. As a result, these snippets have access to methods and variables defined inline, in <script> elements, or in separate code files. For example, if you define a Multiply method in a <script> block, you can write <%= Multiply(6,7) %> in your page.

Code snippets also have access to the members of the Page class. For example, you can write <%= Title %> to display the title of the page.

Data-Binding Expressions

Data-binding expressions are a type of code snippet, but they are worth discussing separately because they work more naturally with dynamic languages.

In standard ASP.NET code, you might have a GridView control with a templated column containing the data-binding expression <%# Eval("City") %>. The Eval method is used to get the value the column named City for the current row in the data source.

With dynamic languages, the snippet is simply <%# City %>. City is a code expression in the dynamic language instead of a literal string that must be interpreted by using the Eval method. This means you can write expressions containing arbitrary code. For example, with IronPython you can write <%# City.lower() %> to display the value of the column in lower case.

This straightforward and powerful syntax is possible because dynamic languages support late-bound evaluation. The meaning of City is not known at parse time, but the dynamic language engine is able to bind it to the correct object at run time.

Dynamic Injector Mechanism

The compilation model for dynamic languages enables you to use simple syntax into which additional code is injected at run time. For example, you might have code that reads a value from the query string. The URL for the page might look like this:

http://someserver/somepage.aspx?MyValue=17

In a C# page, you can use the following code to obtain the value:

String myValue = Request.QueryString["MyValue"];

The dynamic injector mechanism allows you to write much simpler code in dynamic languages, as shown in the following examples:

		
myVar = Request.MyValue
IronPython

The support code for dynamic languages enables the registration of an object referred to as an injector. By registering as an injector, the object agrees to handle code that matches a certain pattern. For example, if the dynamic language engine is unable to resolve the expression SomeObj.SomeName, where SomeObj is an HttpRequest object and SomeName is not a real property of the HttpRequest object, the engine calls the injector that has been registered to handle that pattern. The injector handles the expression by calling SomeObj.QueryString["SomeString"]. The net effect is exactly the same, but the syntax is much cleaner.

The injector mechanism has many potential uses. For example, wherever you would write SomeControl.FindControl("SomeChildControl") in C#, you can write SomeControl.SomeChildControl in a dynamic language application. The mechanism is extensible and can be applied to any collection that is indexed by strings.

Compilation of Dynamic Code

Dynamic language engines parse code at run time, compile it on the fly, and execute the compiled code. They are not interpreters. Compiled code is reused wherever possible, for better performance.

See Also

The New Dynamic Language Extensibility Model for ASP.NET (Word version, .pdf version)


This topic is Microsoft ASP.NET Futures pre-release documentation and is unsupported by Microsoft. Blank topics are included as placeholders and existing content is subject to change in future releases.