Access global page variable in helper

2019-03-17 03:06发布

问题:

@{
    int i = 0;
}

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

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

回答1:

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

@functions
{
    private int i;
}


回答2:

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)


回答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.