Access global page variable in helper

asp.net Mvc-3Razor

asp.net Mvc-3 Problem Overview


@{
    int i = 0;
}

@helper Text() {
    <input type="text" name="Ans[@i].Text" />
}

i is not accessible in helper. How to access it?

asp.net Mvc-3 Solutions


Solution 1 - asp.net Mvc-3

You can simply add it as member to you page by using @functions declaration:

@functions
{
    private int i;
}

Solution 2 - asp.net Mvc-3

You could pass it as parameter to the helper:

@helper Text(int i) {
    <input type="text" name="Ans[@i].Text" />
}

and then:

@{
    int i = 0;
}
@SomeHelper.Text(i)

or you could simply use editor templates which will take care of everything and get rid of those helpers. For example:

@Html.EditorFor(x => x.Ans)

Solution 3 - asp.net Mvc-3

You can achieve this by changing base class for your view. This scenario applies to situation where helper is declared in view.

Create a base class that inherits from WebViewPage and introduce shared field or property:

public class MyBasePage<T> : WebViewPage<T>
{
	public int i;

	public override void Execute()
	{ }
}

Using @inherits directive change base class. And now field/property is acessible both from "page context" and helper:

@inherits NamespaceOfYourBaseClass.MyBasePage<YourModel>
@{
    i = 0;
}

@helper Text() {
    <input type="text" name="Ans[@i].Text" />
}

If you want to have a thing that is close to term "page property/field" but dont want to create a base class or helpers are stored within App_Code folder then you can try WebPageBase.Page property.

> MSDN: Provides property-like access to page data that is shared between > pages, layout pages, and partial pages.

The code in this case would be:

@{
    Page.i = 0;
}

@helper Text() {
    <input type="text" name="Ans[@Page.i].Text" />
}

The drawback is that Page property is of type dynamic and thus does not support intellisense. As an alternative to Page there is another property - WebPageBase.PageData.

> MSDN: Provides array-like access to page data that is shared between pages, > layout pages, and partial pages.

In this case a class-container of strings/ints keys for "page variables" could be created. And the code would be like:

// class visible to views and helpers
class MyViewFields {
  public const string i = "MyViewFields.i"; // or maybe generate guid for key so there would be not doubts about its uniqueness.. but how would you debug this? :)
}

// in MyView.cshtml
@{
    PageData[MyViewFields.i] = 0
}

@helper Text() {
    <input type="text" name="Ans[@PageData[MyViewFields.i]].Text" />
}

This at least provides constraints for shared page data but still no control over value type.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSergey MetlovView Question on Stackoverflow
Solution 1 - asp.net Mvc-3EvgenytView Answer on Stackoverflow
Solution 2 - asp.net Mvc-3Darin DimitrovView Answer on Stackoverflow
Solution 3 - asp.net Mvc-3Alexander ManekovskiyView Answer on Stackoverflow