Variables

Declaring local variables

The var element is a quick and easy way to declare local variables. The default behavior is to create a local of automatic type "var" which is initialized inline.

For example, the following:

<var styles="new [] {'odd', 'even'}" i="0"/>

Produces the following:

var styles = new [] {"odd", "even"};
var i = 0;

The var element has an optional type attribute which can be used to provide an explicit type used instead of the automatic type syntax "var".

<var foo="null" bar="null" type="string"/>

Will declare variables of type string instead of var.

string foo = null;
string bar = null;

Finally if the var element is not declared as a self-closing tag the scope of the variables will be limited. For example:

<div>
  <var styles="new [] {'even', 'odd'}" i="0">
    <p>${i} is ${styles[i%2]}</p>
  </var>
  <set i="5"/> <!-- compiler error - variable i is out of scope -->
</div>

will result in:

Output.Write("<div>");
{
var styles=new[] {"even", "odd"};
var i = 0;
Output.Write("<p>");
Output.Write(i);
Output.Write(" is ");
Output.Write(styles[i%2]);
Output.Write("</p>");
}
Output.Write("</div>");
i = 5;

In this case the local variables are only available inside the element. This can be convenient to scope explicitly.

Declaring global variables

Local variables have a limited scope. They're declared in the generated class right in line in the methods that are generating output. Globals on the other hand can be declared at any location in the view, master, or partial template files and the value can be used and assigned at any point.

<h2>${Title}</h2>
<global Title="'My Default Title'"/>

Global variables are actually implemented as field members of the view class. So the above example would contain object Title="My Default Title"; which is available to from any method. You may also use provide a type attribute to avoid using the default field type object. Multiple variables may be defined in the same element.

<global type="string" Foo="'Hello'" Bar="'World'" />

Setting local and global values

The ${expression} and <%=expression%> syntax is only useful for producing a value to send to output. For local and global variable assignment the set element may be used.

Using global for title

<html>
  <head>
    <global type='string' Title='"Site Name"'/>
    <title>${Title}</title>
  </head>
  <body>
    <div><use content="view"/></div>
  </body>
</html>

View that sets the title

<set Title='product.Name + " - " + Title'/>
<!-- or -->
<set Title='string.Format("{0} - {1}", product.Name, Title)'/>

Using view data

A ViewData property is available as an object dictionary on the base class so syntax like ${ViewData["blah"]} is valid. There is an easier option however which adds a strongly typed property accessor for a view data member.

<viewdata 
  Caption="string" 
  Products="System.Collections.Generic.IList[[MyApp.Models.Product]]"/>
<div>
  <h3>${Caption}</h3>
  <div  each="var product in Products">
    <h4>${product.Name}</h4>
    <div>${product.Description}</div>
  </div>
</div>

The viewdata element may occur anywhere in the view or master file actually. The net result is the same which is to add something like the following to the generated class.

string Caption 
{get {return (string)ViewData["Caption"];}}
 
System.Collections.Generic.IList<MyApp.Models.Product> Products 
{get {return (System.Collections.Generic.IList<MyApp.Models.Product>)ViewData["Products"];}}

In this case the [[ and ]] are replaced with < and > because of the difficulty xml-centric editors have with certain characters appearing in attributes.

Using view data with a typed model

The viewdata element may have a model attribute in the view or master file.

<viewdata model="MyApp.Models.Catalog"/>
<p>(${ViewData.Model.CatalogID}) ${ViewData.Model.Name} </p>

The net effect is to have the model attribute used as the TModel parameter for the ViewDataDictionary.

The model attribute can be used in conjunction with the other viewdata variable declaration. For example if your master template uses a typecast named viewdata argument to access a member variable, like <viewdata Title="string"/>, your views can still use a specific <viewdata model="typename"/> if the type has a string Title property.

<viewdata Title="string"/>
<title>${Html.Encode(Title ?? "My Sample MVC Application")}</title>

The above example enables you to add a string Title property to any class used as a TModel, or as an automatic class new {Title = "hello"}, or as a dictionary entry in an untyped view data dictionary.