为什么我无法访问usercontrol中的页面视图状态?

Roh*_*nsi 25 asp.net

我在Page的viewstate中存储了一个对象.现在,当我在usercontrol上访问相同的viewsate对象时,它显示为null.我甚至尝试在usercontrol和page中创建具有相同名称的相同viewstate.Both拥有不同的值.

我知道viewstate是受保护的属性.这个东西如何在上面的场景中实现,或者是否有任何其他原因导致这种行为.

编辑:

Usercontrol在页面标记中.我没有动态加载它.

我有一个页面EditFacilityworkType.aspx.在页面上,我有一个usercontrol FacilityWorkTypeDetails.aspx(FacilityWorkTypeDetails1).在这个usercontrol里面我有一个用户控件Workflow.aspx(Workflow1)

Page的Page_Load()我正在页面的page_load()上检索workflowdetails.

 FacilityWorktype facilityWorkType = facilityDetails.GetFacilityWorktypeDetail(SessionHelper.FacilityWorkTypeID);
 ViewState["WorkFlow"] = facilityWorkType.FacilityWorkTypeWorkFlow
Run Code Online (Sandbox Code Playgroud)

在usercontrol FacilityWorkTypeDetails.aspx中.我有一个房产

 public FacilityWorktype FacilityWorkTypeDetails
{
    get
    {
        #region Fill FacilityWorktype
        return GetEntityFromControl();
        #endregion
    }
    set
    {
        PopulateControls(value);
    }
}
Run Code Online (Sandbox Code Playgroud)

现在我在页面的页面加载中设置此属性

FacilityWorkTypeDetails1.FacilityWorkTypeDetails = facilityWorkType;
Run Code Online (Sandbox Code Playgroud)

在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);
    }
}
Run Code Online (Sandbox Code Playgroud)

现在是FacilityWorkTypeDetails1的PopulateControls(),我正在设置workflow1的属性

private void PopulateControls(FacilityWorktype value){

    Workflow1.WorkFlowDetails = value.FacilityWorkTypeWorkFlow;
}
Run Code Online (Sandbox Code Playgroud)

现在当我从中检索值时

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

 }
Run Code Online (Sandbox Code Playgroud)

所以现在在这个函数里面,workFlow为null.我想问一下,当我在页面中设置viewstate时,为什么它为null.

pea*_*lou 38

Scherand在这里非常正确.我想补充他带来的东西.

从System.Web.UI.Control派生的每个控件都具有ViewState属性.Under-the-hood酒店是StateBag系列.Control的每个实例都有自己的StateState StateBag,正如Scherand所提到的,ViewState对于控件来说是唯一的.当页面被渲染时,页面的整个控制树被迭代,所有ViewState集合被合并为树状结构,并且最终结构被序列化为字符串并呈现给页面.

因为ViewState属性被标记为受保护,所以如果不使用反射,则无法从用户控件访问Page的ViewState.

但是,说实话,您应该放弃使用ViewState作为数据存储介质.以下是一些原因:

  1. ViewState被呈现并输出到客户端浏览器.维护集合中的数据对象会使页面的输出膨胀.
  2. 除非您在ViewState上启用了加密,否则呈现给客户端浏览器的编码字符串可以手动解码,只需任何人都可以访问数据对象的内容.这是一个相当重要的安全漏洞.

听起来您只想在页面和用户控件之间共享数据.在控件之间共享数据的最佳方法是使用"Items"集合(这是HttpContext类的属性).该集合是一个Hashtable,可以从您的页面和用户控件访问,如下所示:

Context.Items["Workflow"] = workflowInstance;
Run Code Online (Sandbox Code Playgroud)

使用这种技术的最好的部分是它不会产生任何额外的开销或膨胀Page输出.Items集合存在于单个HTTP请求的上下文中.这意味着当您的请求完成并且您的Page的输出已呈现给客户端浏览器时,Items集合将从服务器内存中清除.它是ASP.NET中临时数据存储的理想媒介.

现在,如果您希望数据对象不仅可以访问当前请求,那么最好将对象存储在Session中.


sch*_*and 5

我仍然不在这里查看所有内容(请参阅上面的评论)。但是我很确定你会误会ViewState

ViewState是每个控件的,而不是每个请求或会话等的。

在您的示例中,考虑一些其他控件(例如,标准ASP.NET控件),由于某些原因,这些控件决定将带有“名称”的内容WorkFlow放入视图状态。如果您尝试执行的操作可行,则此对象将覆盖您的对象(或者相反,您的对象将被另一对象覆盖)。

还是我错过了什么?

也许真正读懂了ViewState可以帮助您了解什么是viewstate /它是如何工作的(是的,我真的很喜欢这篇文章,这就是为什么我继续发布该链接)。