Почему не может я получать доступ к состоянию отображения страницы в usercontrol?

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

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

Править:

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

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

Page_Load () Страницы я получаю workflowdetails на page_load () страницы.

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

В usercontrol 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, я устанавливаю свойство workflow1

частный пустой PopulateControls (значение FacilityWorktype) {

    Workflow1.WorkFlowDetails = value.FacilityWorkTypeWorkFlow;
}

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

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

 }

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

25
задан Rohit Raghuvansi 11 June 2010 в 08:54
поделиться

3 ответа

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

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

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

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

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

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

Context.Items["Workflow"] = workflowInstance;

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

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

38
ответ дан 28 November 2019 в 21:03
поделиться

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

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

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

Или мне что-то не хватает?

Может быть, чтение ДЕЙСТВИТЕЛЬНО понимание ViewState может помочь вам понять, что такое состояние просмотра / как оно работает (да, мне очень нравится эта статья, поэтому я продолжаю публиковать ее ссылка).

5
ответ дан 28 November 2019 в 21:03
поделиться

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

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

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

1
ответ дан 28 November 2019 в 21:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: