Доступ к глобальной переменной страницы в помощнике

@{
    int i = 0;
}

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

i недоступен в помощнике. Как получить к нему доступ?

Ответ 1

Вы можете просто добавить его как участника к своей странице, используя объявление @functions:

@functions
{
    private int i;
}

Ответ 2

Вы можете передать его как параметр в помощник:

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

а затем:

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

или вы можете просто использовать шаблоны редактора, которые будут заботиться обо всем и избавиться от этих помощников. Например:

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

Ответ 3

Вы можете добиться этого, изменив базовый класс для своего вида. Этот сценарий применяется к ситуации, когда хелпер объявляется в поле зрения.

Создайте базовый класс, который наследует WebViewPage и вводит общее поле или свойство:

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

    public override void Execute()
    { }
}

Использование базового класса директивы change @inherits. И теперь поле/свойство доступно как из "контекста страницы", так и для помощника:

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

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

Если вы хотите иметь вещь, близкую к термину "свойство/поле страницы", но не хотите создавать базовый класс, а помощники хранятся в папке App_Code, тогда вы можете попробовать WebPageBase.Page.

MSDN. Предоставляет доступ к данным, доступным по свойствам, который совместно используется страниц, страниц макета и частичных страниц.

Код в этом случае будет:

@{
    Page.i = 0;
}

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

Недостатком является то, что свойство Page имеет тип dynamic и, следовательно, не поддерживает intellisense. В качестве альтернативы Page существует другое свойство - WebPageBase.PageData.

MSDN. Предоставляет доступ к данным на странице, доступный по типу, страниц макета и частичных страниц.

В этом случае может быть создан класс-контейнер ключей строк /ints для "переменных страницы". И код будет выглядеть так:

// 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" />
}

Это, по крайней мере, обеспечивает ограничения для данных общей страницы, но не контролирует тип значения.