Почему я не могу получить доступ к состоянию просмотра страницы в usercontrol? - PullRequest
23 голосов
/ 11 июня 2010

Я сохранил объект в viewstate на странице. Теперь, когда я получаю доступ к тому же объекту viewsate в usercontrol, он отображается как null Я даже пытался создать одно и то же состояние представления с одинаковым именем в usercontrol и page.Both имеет другое значение.

Я понимаю, что viewstate является защищенным свойством. Как это реализовано в описанном выше сценарии или есть какая-то другая причина для такого поведения?

Edit:

UserControl есть в разметке страницы. Я не загружаю его динамически.

У меня есть страница EditFacilityworkType.aspx. На странице у меня есть пользовательский контроль FacilityWorkTypeDetails.aspx (FacilityWorkTypeDetails1). Внутри этого usercontrol у меня есть пользовательский элемент управления Workflow.aspx (Workflow1)

Page_Load () страницы Я получаю детали рабочего процесса на page_load () страницы.

 FacilityWorktype facilityWorkType = facilityDetails.GetFacilityWorktypeDetail(SessionHelper.FacilityWorkTypeID);
 ViewState["WorkFlow"] = facilityWorkType.FacilityWorkTypeWorkFlow

Внутри пользовательского контроля FacilityWorkTypeDetails.aspx. У меня есть собственность

 public FacilityWorktype FacilityWorkTypeDetails
{
    get
    {
        #region Fill FacilityWorktype
        return GetEntityFromControl();
        #endregion
    }
    set
    {
        PopulateControls(value);
    }
}

Теперь я устанавливаю это свойство при загрузке страницы

FacilityWorkTypeDetails1.FacilityWorkTypeDetails = facilityWorkType;

Внутри Workflow.aspx, у меня есть свойство

/// <summary>
/// Property to fill entity object from controls on this page
/// </summary>
public WorkFlow WorkFlowDetails
{
    get
    {
        return GetEntityFromControls();
    }
    set
    {            
        BindTranscriptionMethodDDL(ddlTranscMethod);
        PopulateControls(value);
    }
}

Теперь PopulateControls () из FacilityWorkTypeDetails1, я устанавливаю свойство рабочего процесса1

private void PopulateControls (значение FacilityWorktype) {

    Workflow1.WorkFlowDetails = value.FacilityWorkTypeWorkFlow;
}

Теперь, когда я получаю значения из

 private WorkFlow GetEntityFromControls()
 {
     WorkFlow workFlow = (ViewState["WorkFlow"] as WorkFlow) ?? new WorkFlow();  
     //workFlow  is null

 }

Так что теперь внутри этой функции workFlow равен нулю. Я хочу спросить, почему это ноль, когда я установил viewstate на странице.

Ответы [ 4 ]

37 голосов
/ 11 июня 2010

Схеранд здесь очень правильный. Я хотел бы добавить к тому, что он принес на стол.

Каждый элемент управления, производный от System.Web.UI.Control, имеет свойство ViewState. Под капотом собственность является коллекцией StateBag. Каждый экземпляр элемента управления имеет свой собственный StateBag для ViewState, поэтому, как упомянул Scherand, ViewState уникален для элемента управления. Когда страница визуализируется, все дерево элементов управления страницы перебирается, все коллекции ViewState объединяются в древовидную структуру, и эта конечная структура сериализуется в строку и отображается на странице.

Поскольку свойство ViewState помечено как защищенное, вы не можете получить доступ к ViewState страницы из пользовательского элемента управления без использования отражения.

Но, честно говоря, вы должны отказаться от использования ViewState в качестве носителя данных. Вот несколько причин, почему:

  1. ViewState обрабатывается и выводится в браузер клиента. Поддержание объектов данных в коллекции увеличивает объем вашей страницы.
  2. Если в ViewState не включено шифрование, закодированная строка, отображаемая в браузере клиента, может быть декодирована вручную, и любой может получить доступ к содержимому ваших объектов данных. Это довольно существенная уязвимость безопасности.

Похоже, все, что вы хотите сделать, - это обмениваться данными между вашей страницей и пользовательскими элементами управления. Лучший способ обмена данными между элементами управления - использовать коллекцию «Items» (которая является свойством класса HttpContext). Коллекция является Hashtable и может быть доступна с вашей страницы и элементов управления, например:

Context.Items["Workflow"] = workflowInstance;

Лучшая часть использования этой техники заключается в том, что она не влечет за собой никаких дополнительных издержек и не увеличивает объем страницы. Коллекция Items существует в контексте одного HTTP-запроса. Это означает, что когда ваш запрос выполнен и выходные данные вашей страницы были переданы в браузер клиента, коллекция Items удаляется из памяти сервера. Это идеальный носитель для временного хранения данных в ASP.NET.

Теперь, если вы хотите, чтобы ваши объекты данных оставались доступными не только для текущего запроса, вам лучше хранить объекты в сеансе.

4 голосов
/ 11 июня 2010

Я до сих пор не все здесь грок (см. Мои комментарии выше).Но я вполне уверен, что вы неправильно понимаете ViewState.

ViewState равен для элемента управления , а не для запроса или сеанса или чего-либо еще.

В вашем примере рассмотрим некоторыеэлемент управления (например, стандартный элемент управления ASP.NET), который по какой-то причине решил поместить что-то с «именем» WorkFlow в viewstate.Если то, что вы пытаетесь сделать, сработает, этот объект перезапишет ваш (или наоборот, ваш будет перезаписан другим).

Или я что-то упустил?

Возможно, чтение TRULY Понимание ViewState может помочь вам понять, что такое viewstate / как оно работает (да, мне действительно нравится эта статья, поэтому я продолжаю публиковать эту ссылку).

1 голос
/ 06 апреля 2011

состояние просмотра страницы отличается от состояния просмотра, к которому пользовательский контроль может получить доступ.Каждый элемент управления имеет свое собственное частное состояние просмотра.Таким образом, вы не можете получить прямой доступ к состоянию просмотра страницы из-за кода контроля пользователя.

вы можете предоставить значениям viewstate свойства или методы, а затем вызвать эти свойства / методы

1 голос
/ 11 июня 2010

При обратной передаче вы создали элемент управления?Если код не создал Ctrl, он не узнает об этом.

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

Viewstate - монстр, поэтому многие из нас собираются в MVC.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...