Microsoft KB Archive/315903

= How to manage multilanguage Web Forms solutions in Visual Studio .NET or Visual Studio 2005 =

Article ID: 315903

Article Last Modified on 6/1/2007

-

APPLIES TO


 * Microsoft Visual Basic .NET 2002 Standard Edition
 * Microsoft Visual Basic .NET 2003 Standard Edition
 * Microsoft Visual C# .NET 2002 Standard Edition
 * Microsoft Visual C# .NET 2003 Standard Edition
 * Microsoft Visual Basic 2005

-



This article was previously published under Q315903



IN THIS TASK
SUMMARY Requirements Create a Multilanguage ASP.NET Web Application Complete Code Listing
 * Menu.xml
 * Menu.xslt
 * WebForm1.aspx
 * Class1.cs Non-Inheritance Example
 * WebForm1.vb Inheriting System.Web.UI.Page
 * Class1.cs Inheritance Example
 * WebForm1.vb Inheriting ClassLibrary1

Verify That It Works Steps to Demonstrate Multilanguage Inheritance Troubleshooting REFERENCES



SUMMARY
This article demonstrates how to use an XML data-island and the .NET Xml Web server control to create a small, multilanguage Web Application project that displays Extensible Markup Language (XML) data. The main application is built in Visual Basic .NET or Visual Basic 2005. The application uses a Visual C# Class Library component to illustrate multilanguage references and implementation inheritance.

back to the top

Requirements
The following list outlines the recommended hardware, software, network infrastructure, and service packs that you need:
 * Microsoft Windows 2000 Professional, Microsoft Windows 2000 Server, Microsoft Windows XP Professional, or Microsoft Windows XP Server with the Microsoft .NET Framework and Microsoft Visual Studio .NET installed

This article assumes that you are familiar with the following topics:
 * Implementation inheritance
 * XML and Extensible Stylesheet Language Transformation (XSLT)
 * Microsoft .NET Web server controls

back to the top

Create a Multilanguage ASP.NET Web Application
In the following steps, you create a small ASP.NET Web Application project that allows a customer to select lunch menu items based on calorie count. To do this, the sample uses the Xml Web server control, a simple XML document that contains the menu data, and an XSL stylesheet to transform the XML data. The XsltArgumentList class from the System.Xml.Xsl namespace allows you to use parameters in the transformation.  Create a Visual Basic Windows Application project as follows:  Start Microsoft Visual Studio .NET or Microsoft Visual Studio 2005, and then click New Project. Under Project Types, click Visual Basic Projects. Under Templates, click ASP.NET Web Application. Rename the project Menu, and then click OK.

Note In Visual Studio 2005, click Visual Basic under Project Types.  Make sure that the Solution Explorer window is visible. If it is not, press the CTRL+ALT+L key combination. You now have the shell of a Visual Basic .NET or Visual Basic 2005 Web Application project within a solution named Menu. To make this a multilanguage solution, you must add a Visual C# Class Library.

In the Solution Explorer window, right-click Menu, point to Add, and then click New Project. Under Project Types, click Visual C# Projects. Under Templates, click Class Library. Keep the default name, ClassLibrary1. Click OK to add this Class Library to the solution.

Note In Visual Studio 2005, click Visual C# under Project Types.  Class1.cs appears in the Editor window. Add the following namespace declaration to the top of this window: using System.Xml.Xsl; </li>  Under public Class1, add the following code: public XsltArgumentList CreateArgumentList( string ParamName, string NamespaceURI, string ParamValue) { XsltArgumentList tal = new XsltArgumentList; tal.AddParam(ParamName, NamespaceURI, ParamValue); return tal; }                   </li> You now have a Visual C# class that takes XSLT parameter information and that returns an instance of the XsltArgumentList class. You can now build the Visual Basic application that will consume this component.

WebForm1.aspx should already be open in Design View. If not, double-click WebForm1.aspx in the Solution Explorer window. Click the Design tab below the Editor window to switch to Design View.</li> Press the F4 key to access the property page. Change the pageLayout property to FlowLayout .</li> On the Web Form, type Maximum Calories: .</li> Add a TextBox control, a Button control, and an Xml control to the form as follows:  Press the CTRL+ALT+X key combination to open the toolbox.</li> In the toolbox, click Web Forms.</li> Drag a TextBox control and a Button control from the toolbox, and drop these controls onto the Web Form.</li> Press F4 to access the property page for the Button control.</li> Change the Text property to Filter Menu .</li> Position the cursor after the button, and then press ENTER to position the cursor for the Xml control.</li> Drag an Xml Web server control from the toolbox, and drop this control onto the Web Form.</li> Press F4 to access the property page of the Xml control.</li> Change the DocumentSource property to Menu.xml, and then change the TransformSource property to Menu.xslt .</li></ol> </li> <li>Double-click Filter Menu to create a Click event handler in the code-behind class of the Web Form. Before you add code to the handler, you must add a reference to the Visual C# Class Library as follows: <ol style="list-style-type: lower-alpha;"> <li>In the Solution Explorer window, under ClassLibrary1, right-click References, and then click Add Reference.</li> <li>On the Projects tab, double-click ClassLibrary1. Notice that ClassLibrary1 appears in the Selected Components list box.</li> <li>Click OK. Notice that ClassLibrary1 appears under References in the Web Application.</li></ol> </li> <li> Add the following code to the Click event handler: Dim myArgList As New ClassLibrary1.Class1 Xml1.TransformArgumentList = myArgList.CreateArgumentList(&quot;calories&quot;, &quot;&quot;, TextBox1.Text) Xml1.Visible = True The argument list that the Visual C# component returns allows you to pass the value of the TextBox control as a parameter to the stylesheet. This stylesheet uses XSLT commands to filter out all lunch menu items that exceed the calorie count that the customer types. The following line of code from the stylesheet illustrates how the parameter is received and used: <xsl:for-each select=&quot;lunch-menu/food[calories <= $calories]&quot;> </li> <li>Use the code from the Menu.xml and the Menu.xslt sections to create the Menu.xml and Menu.xslt files. In the Solution Explorer window, right-click the Menu project, and then add the .xml and .xslt files.</li></ol>

back to the top

Menu.xml
<?xml version='1.0'?> <lunch-menu> Cheese Pizza $6.95    Individual deep-dish pizza with lots of mozzarella cheese 800    Pepperoni Pizza $7.95    Individual deep-dish cheese pizza with thick-cut pepperoni slices 950    The &quot;Everything&quot; Pizza $9.95    Individual deep-dish pizza with all our toppings. House specialty! 800     Hungarian Ghoulash $4.50    Large serving in a sourdough bread bowl. A_local delight! 600    Maisey's Pork Sandwich $6.95    A fresh pork fillet, deep-fried to perfection. Served with fries. 950 </lunch-menu> back to the top

Menu.xslt
<?xml version=&quot;1.0&quot;?> <xsl:stylesheet version=&quot;1.0&quot; xmlns:xsl=&quot;http://www.w3.org/1999/XSL/Transform&quot;> <xsl:param name=&quot;calories&quot;>1500</xsl:param> <xsl:template match=&quot;/&quot;> <HTML> <BODY STYLE=&quot;font-family:Arial, helvetica, sans-serif; font-size:12pt; background-color:#EEEEEE&quot;> <xsl:for-each select=&quot;lunch-menu/food[calories <= $calories]&quot;> <DIV STYLE=&quot;background-color:blue; color:white; padding:4px&quot;> <SPAN STYLE=&quot;font-weight:bold; color:white&quot;><xsl:value-of select=&quot;name&quot;/></SPAN> - <xsl:value-of select=&quot;price&quot;/> </DIV> <DIV STYLE=&quot;margin-left:20px; margin-bottom:1em; font-size:10pt&quot;> <xsl:value-of select=&quot;description&quot;/> <SPAN STYLE=&quot;font-style:italic&quot;> (<xsl:value-of select=&quot;calories&quot;/> calories per serving) </SPAN> </DIV> </xsl:for-each> </BODY> </HTML> </xsl:template> </xsl:stylesheet> back to the top

WebForm1.aspx
<%@ Page Language=&quot;vb&quot; AutoEventWireup=&quot;false&quot; Codebehind=&quot;WebForm1.aspx.vb&quot; Inherits=&quot;menu.WebForm1&quot;%> <!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0 Transitional//EN&quot;> <HTML> <HEAD> WebForm1 <meta name=&quot;GENERATOR&quot; content=&quot;Microsoft Visual Studio.NET 7.0&quot;> <meta name=&quot;CODE_LANGUAGE&quot; content=&quot;Visual Basic 7.0&quot;> <meta name=vs_defaultClientScript content=&quot;JavaScript&quot;> <meta name=vs_targetSchema content=&quot;http://schemas.microsoft.com/intellisense/ie5&quot;> </HEAD>

<form id=&quot;Form1&quot; method=&quot;post&quot; runat=&quot;server&quot;> <P>Maximum Calories: <asp:TextBox id=&quot;TextBox1&quot; runat=&quot;server&quot;></asp:TextBox> <asp:Button id=&quot;Button1&quot; runat=&quot;server&quot; Text=&quot;Filter menu&quot;></asp:Button></P> <P> <asp:Xml id=&quot;Xml1&quot; runat=&quot;server&quot; DocumentSource=&quot;menu.xml&quot; TransformSource=&quot;menu.xslt&quot;></asp:Xml></P>

</HTML> back to the top

Class1.cs Non-Inheritance Example
using System; using System.Xml.Xsl;

namespace ClassLibrary1 {   ///     /// Summary description for Class1. ///    public class Class1 {       public XsltArgumentList CreateArgumentList(        string ParamName, string NamespaceURI, string ParamValue) {           XsltArgumentList tal = new XsltArgumentList; tal.AddParam(ParamName, NamespaceURI, ParamValue); return tal; }   } } back to the top

WebForm1.vb Inheriting System.Web.UI.Page
Imports System.Xml.Xsl

Public Class WebForm1 Inherits System.Web.UI.Page Protected WithEvents TextBox1 As System.Web.UI.WebControls.TextBox Protected WithEvents Button1 As System.Web.UI.WebControls.Button Protected WithEvents Xml1 As System.Web.UI.WebControls.Xml


 * 1) Region &quot; Web Form Designer Generated Code &quot;

'The Web Form Designer requires this call. <System.Diagnostics.DebuggerStepThrough> Private Sub InitializeComponent

End Sub

Private Sub Page_Init(ByVal sender As System.Object, _   ByVal e As System.EventArgs) Handles MyBase.Init 'CODEGEN: The Web Form Designer requires this method call. 'Do not use the Code editor to modify it. InitializeComponent End Sub


 * 1) End Region

Private Sub Page_Load(ByVal sender As System.Object, _   ByVal e As System.EventArgs) Handles MyBase.Load 'Insert user code to initialize the page here. End Sub

Private Sub Button1_Click(ByVal sender As System.Object, _   ByVal e As System.EventArgs) Handles Button1.Click Dim tal As New XsltArgumentList tal.AddParam(&quot;calories&quot;, &quot;&quot;, TextBox1.Text) Xml1.TransformArgumentList = tal Xml1.Visible = True End Sub End Class back to the top

Class1.cs Inheritance Example
using System; using System.Xml.Xsl;

namespace ClassLibrary1 {   ///     /// Summary description for Class1. ///    public class Class1 : System.Web.UI.Page {       public XsltArgumentList CreateArgumentList(        string ParamName, string NamespaceURI, string ParamValue) {           XsltArgumentList tal = new XsltArgumentList; tal.AddParam(ParamName, NamespaceURI, ParamValue); return tal; }   } } back to the top

WebForm1.vb Inheriting ClassLibrary1
Imports System.Xml.Xsl

Public Class WebForm1 Inherits ClassLibrary1.Class1 Protected WithEvents TextBox1 As System.Web.UI.WebControls.TextBox Protected WithEvents Button1 As System.Web.UI.WebControls.Button Protected WithEvents Xml1 As System.Web.UI.WebControls.Xml


 * 1) Region &quot; Web Form Designer Generated Code &quot;

'The Web Form Designer requires this call. <System.Diagnostics.DebuggerStepThrough> Private Sub InitializeComponent

End Sub

Private Sub Page_Init(ByVal sender As System.Object, _   ByVal e As System.EventArgs) Handles MyBase.Init 'CODEGEN: The Web Form Designer requires this method call. 'Do not use the Code editor to modify it. InitializeComponent End Sub


 * 1) End Region

Private Sub Page_Load(ByVal sender As System.Object, _   ByVal e As System.EventArgs) Handles MyBase.Load 'Insert user code to initialize the page here. End Sub

Private Sub Button1_Click(ByVal sender As System.Object, _   ByVal e As System.EventArgs) Handles Button1.Click Xml1.TransformArgumentList = CreateArgumentList(&quot;calories&quot;, &quot;&quot;, TextBox1.Text) Xml1.Visible = True End Sub End Class back to the top

Verify That It Works

 * 1) Press the F5 key to run the application in debug mode.
 * 2) The entire menu appears by default. Take note of the calorie counts for each item.
 * 3) In the text box, type a number of calories, and then click Filter Menu. Notice that only those menu items that are less than or equal to this calorie amount appear.
 * 4) Press the SHIFT+F5 key combination to stop debugging and to return to Visual Studio.

back to the top

Steps to Demonstrate Multilanguage Inheritance
To illustrate multilanguage inheritance, you must modify the Web Application project. Instead of creating an instance of the Class Library component, the application inherits from the Visual Basic .NET Web Form code-behind class.

The code-behind class currently inherits the System.Web.UI.Page class. Because Microsoft .NET does not support multiple inheritance, you must move Page class inheritance to the Visual C# class. <ol> <li>Add a reference to the System.Web namespace in the Class Library before you modify the Visual C# code.</li> <li>In the Solution Explorer window, under ClassLibrary1, right-click References, and then click Add Reference.</li> <li>On the .NET tab, double-click System.Web.dll. Notice that System.Web.dll appears in the Selected Components list box.</li> <li>Click OK. Notice that System.Web appears under References in your Class Library.</li> <li> Modify the Class1 declaration to inherit the Page class: public class Class1 : System.Web.UI.Page </li> <li> The Visual Basic .NET or Visual Basic 2005 code-behind class is now ready to inherit Class1. Because Class1 inherits the Page class, the code-behind class also inherits the Page class through its inheritance of Class1.

In the Editor window, click WebForm1.aspx.vb. Under the class declaration, replace System.Web.UI.Page with ClassLibrary1.Class. The updated code should appear as follows: Inherits ClassLibrary1.Class1 </li> <li> Comment out the first line in the Click event handler as follows: 'Dim myArgList As New ClassLibrary1.Class1 </li> <li> Modify the second line in the Click event handler by calling CreateArgumentList without an object reference: Xml1.TransformArgumentList = CreateArgumentList(&quot;calories&quot;, &quot;&quot;, TextBox1.Text) </li> <li>Repeat the steps in the Verify That It Works section.</li></ol>

back to the top

Troubleshooting
<ul> <li>When you work with two languages, it is easy to confuse syntax. Visual C# syntax does not allow a wide margin of error. Furthermore, Visual C# .NET error messages are not always as prompt or as intuitive as Visual Basic .NET error messages. To troubleshoot these difficulties, refer to the &quot;Language Equivalents&quot; section of the Microsoft .NET Framework Software Development Kit (SDK):

Language Equivalents

http://msdn2.microsoft.com/en-us/library/czz35az4(vs.71).aspx

</li> <li>If you want to use implementation inheritance, study object-oriented principles of design, and consider application architecture in advance. A common mistake is to put code in a main application that you need to inherit in a Class Library. In this scenario, you cannot inherit the main application in a Class Library because of circular dependencies. For example, try to add a reference to the Menu project in the ClassLibrary1 project. You receive the following error message:

A reference to 'Menu' could not be added. Adding this project as a reference would cause a circular dependency.

</li></ul>

back to the top