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.
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.
- Walkthrough: Using Dynamic Languages with ASP.NET
- Walkthrough: Using Shared Code with Dynamic Languages for ASP.NET
- Walkthrough: Debugging with Dynamic Languages for ASP.NET
- Walkthrough: Databinding with Dynamic Languages for ASP.NET
- Walkthrough: Creating a User Control with Dynamic Languages for ASP.NET
With Microsoft IronPython for ASP.NET, developers can use popular dynamic languages for the .NET Framework to create compelling Web applications. IronPython 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.
Implementations of Ruby and Visual Basic are under development. Future releases will expose hosting interfaces and the API for integrating other languages.
In thisrelease, 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.
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:
IronPython
def Application_BeginRequest(app):
app.Response.Write('Hello application!') 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:
IronPython
<%@ Page Language="IronPython" %>
<Script runat="server">
Response.ContentType = "text/plain"
Response.Write("Hello World")
</Script> 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 this release, there is very limited design time support, no intellisense support, and no support for writing ASP.NET MVC controllers using a dynamic language. These are all limitations we plan to address in future releases.
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.
IronPython
<script runat="server">
def Page_Load(sender, args):
Response.Write("<p>Page_Load!</p>")
</script> 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:
IronPython
myVar = Request.MyValue
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.
Posted in: .NET Framework| Tags: HTTP Dynamic Language Support Introduction Dynamic Data IronPython Overview Generic HTTP Handler App_Script Dynamic CodeCreating a User Control with Dynamic Languages for ASP.NET
Introduction
You can use dynamic languages in ASP.NET to create user controls that encapsulate the functionality of multiple server controls in a unit. In this walkthrough, you will create an ASP.NET user control that acts as a picker control. The picker control has two lists, with a set of choices in one list (the source). Users can select items in the SourceList list, and then add the items to the TargetList list.
Note In this release, you cannot use dynamic languages to create custom server controls.
Tasks illustrated in this walkthrough include the following:
- Creating a user control and adding ASP.NET server controls to the user control, with event handlers written in dynamic languages.
- Adding a user control to a host page.
- Adding properties and methods to the user control with dynamic languages.
- Coding properties in dynamic languages so that they can be set declaratively.
- Adding dynamic language code to the host page to handle the user control.
Prerequisites
In order to complete this walkthrough, you will need:
- Microsoft Visual Studio 2005 or Visual Web Developer Express Edition.
- The ASP.NET Futures release (May 2007 or later) installed on your computer. The .msi installer file includes a Visual Studio Content Installer (.vsi) for creating a blank ASP.NET Futures Web application in Visual Studio.
This walkthrough assumes that you have a general understanding of working with ASP.NET in Visual Studio. For an introduction to ASP.NET in Visual Studio, see Walkthrough: Creating a Basic Page in Visual Web Developer.
Creating the Web Site
ASP.NET Dynamic Language Support: Using Dynamic Languages with ASP.NET
This walkthrough provides you with an introduction to dynamic languages for ASP.NET. It guides you through creating a simple page in Microsoft Visual Studio, adding controls, and adding event handlers using dynamic languages.
Tasks illustrated in this walkthrough include:
- Adding controls to the default page.
- Adding event handlers in a separate code file, using dynamic languages.
- Adding a second page with event-handling code in the page.
Prerequisites
In order to complete this walkthrough, you will need:
- Microsoft Visual Studio 2008 or Visual Web Developer 2008 Express Edition.
- A copy of the website included in the ASP.NET Dynamic Language Support download. There is currently no project template, so it is necessary to copy the website in order to start with a blank ASP.NET Dynamic Language website.
This walkthrough assumes that you have a general understanding of working in Visual Web Developer. For an introduction, see Walkthrough: Creating a Basic Page in Visual Web Developer.
Creating a Web Site
In this part of the walkthrough, you will create a Web site with a dynamic language as the default language.
To create a Web site with a default ASP.NET Web page
- Copy the files from the ASP.NET Dynamic Language Support project into an empty directory.
- In Visual Studio (or Visual Web Developer), in the File menu, click Open Web Site. The Open Web Site dialog box is displayed.
- Select the directory in which you copied the files in step 1. Make sure that FileSystem is selected in the left panel of the dialog.
Note: You can use statically compiled languages in the same Web application by creating pages and components in different programming languages.
- Click Open. Visual Studio opens the folder as a website and displays the files in the Solution Explorer.
Adding Controls to the Default Page
In this part of the walkthrough, you will add server controls to the page.
To add controls to the page
- Switch to Design view.
- In the Toolbox, from the Standard group, drag three controls onto the page: a TextBox control, a Button control, and a Label control.
- Put the insertion point above the TextBox control, and then type Enter your name: to create a caption for the text box.
Programming the Button Control
For this walkthrough, you will write code that reads the name that the user enters into the text box and then displays the name in the Label control.
To add a button event handler
- Right-click the page and click View Code to show the separate code file. For example, if you are using IronPython, the file is Default.aspx.py.
The file contains a stub event handler for the Load event of the page.
Note: In IronPython, pass is a placeholder that does nothing.
- Replace the stub event handler with the following code to set the label text when the page is initialized:
IronPython
def Page_Load(sender, e): if not IsPostBack: Label1.Text = "...Your name here..."
- Add the following code to create an event handler for the button's
Clickevent:IronPython
def Button1_Click(sender, e): Label1.Text = Textbox1.Text
In this release, event handlers must be coded and bound manually. You cannot create them by double-clicking a control in Design view or by selecting an event in the Properties window.
Because dynamic languages do not have typed parameters and variables, you do not need to know the type of the event argument object.
Note: In this release, IntelliSense support for dynamically typed variables is limited. You can press CTRL+SPACE to get a list of code elements that are currently in scope.
- Switch to Default.aspx and go to Source view, and then bind the event handler by adding an
OnClickattribute to the Button control markup, as shown in the following example:<form id="form1" runat="server"> <div> Enter your name:<br /> <asp:TextBox ID="TextBox1" runat="server"> </asp:TextBox> <asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click"/><br /> <br /> <asp:Label ID="Label1" runat="server" Text="Label"> </asp:Label> <br /> </div> </form>
- Press CTRL+F5 to run the page in the browser using the ASP.NET Development Server.
- Enter a name into the text box and click the button. The name you entered is displayed in the Label control. If the name does not appear, check the spelling of the event handler in the
OnClickattribute. - In the browser, optionally view the source of the page you are running.
- Close the browser.
Programming the Button Control
For this walkthrough, you will add dynamic language code in a script block.
To add a default button event handler
- Switch to Source view.
- Add the following code to initialize the label and to create an event handler for the button's Click event.
IronPython
<script runat="server"> def Page_Load(sender, e): if not IsPostBack: Label1.Text = "...Your name here..." def Button1_Click(sender, e): Label1.Text = Textbox1.Text </script>
- In the Button control, bind the event handler by adding the
OnClickattribute, as you did previously in this walkthrough. The following example shows the markup.<asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click"/><br />
- Press CTRL+F5 to run the page in the browser using the ASP.NET Development Server.
ASP.NET Dynamic Language Support
Introduction
Dynamic Languages are a class of high-level programming languages that do not rely on static typing. Many decisions that are made at compile time by a statically typed language are instead made at run time by a dynamic language. For example, many dynamic languages use dynamic typing, where an object’s type is determined at run time instead of at compile time. These languages make a trade-off between compile-time type-checking in favor of increased flexibility at run time.There are many good static languages, such as C#, and many good dynamic languages, such as IronPython. The choice of what type of language to use comes down to personal preference and to the nature of the project you’re working on.
Giving ASP.NET users the choice of languages was part of the design since our first version of ASP.NET, and this Dynamic Language Support is just another step in that direction. Unlike other Web platforms that support only one language, the ASP.NET team wants to enable users to choose the language that fits them best.
This Release
This release is compatible with IronPython 2.6 Beta 1. Currently it does not include Language Services Support and project templates. To create a new IronPython ASP.NET WebForms project, simply copy the “examples\hello-webforms” to a new directory and rename the directory to your liking. A redistributed copy of IronPython 2.6 Beta 1 can be found in the “bin” directory; all files except Microsoft.Web.Scripting.dll, the IronPython ASP.NET integration, are from the IronPython 2.6 Beta 1 release.Included in this release are two WebForms examples that are written in IronPython: “hello-webforms” and “album-handler”, which can be found in the “examples” directory. “hello-webforms” is a simple web application that shows PostBack handling, and “album-handler” is a larger web application that creates a photo album from a directory of images and generates thumbnails for them on the fly.
Current Limitations
There are some tooling limitations with this release:- Limited support for designers
- No IntelliSense support.
- No support for ASP.NET MVC. This is planned in the future by extending the IronRuby ASP.NET MVC support: http://github.com/jschementi/ironrubymvc.