为少数控件启用ViewState,为其他/页面禁用

当我为页面禁用ViewState时。 它不允许任何其他控件使用ViewState ..即使我为该特定控件设置EnableViewState =“true”..

是否可以在为页面本身禁用ViewState时为控件启用ViewState?

如果不是如何禁用页面上的控件的viewstate除了少数没有明确指定EnableViewState =“false”..键入相同的这么多控件忙碌..

如果关闭翻转页面的ViewState,则无法为特定组件启用ViewState。 这是因为ViewState是递归序列化的,因此当Page不允许ViewState时,它不会为任何子控件序列化ViewState。

在回答你的问题时,如果你不想在单个控件上明确地关闭ViewState,但想要保持一些控件ViewState,最好的方法是编写一个小的实用程序方法,为所有控件关闭ViewState(使用递归)或其他)。 然后为要为其启用ViewState的控件启用ViewState。

或者,如果控件是其他容器控件(例如Panel)中的组,则可以采用中间地板且不太有力的方式。 您可以通过禁用Panel的ViewState来禁用Panel内所有控件的ViewState。

如果关闭翻转页面的ViewState,则无法为特定组件启用ViewState。 这是因为ViewState是递归序列化的,因此如果Page不允许ViewState,它将不会为其任何子控件序列化View.it的子控件。

随着ASP.NET 4的出现,我们有了一个名为ViewStateMode的新属性,即使对页面禁用了视图状态,也可以使用该属性为单个控件启用视图状态。

要使用这个新属性,您可以创建一个将ViewStateMode设置为Disabled的基页类,或者创建一个执行相同操作的PageAdapter。 web.config中没有viewStateMode属性。

这是页面适配器的代码:

using System.Web.UI; using System.Web.UI.Adapters; namespace Playground.Web.UI.Adapters { public class PageAdapter: System.Web.UI.Adapters.PageAdapter { protected override void OnLoad(EventArgs e) { ViewStateMode = ViewStateMode.Disabled; base.OnLoad(e); } } } 

这是浏览器文件的代码:

      

这里有一些代码扩展了@Samuel Kim的概念,即在某些控件上禁用ViewState(顺便说一下,它使用的是.NET 3.5):

 List allowedControls = new List { "Control1", "Control3" }; IEnumerable controlsWithoutViewState = Page.Controls.Where(c => !allowedControls.Contains(c.ID)); foreach(Control c controlsWithoutViewState){ if(c is WebControl) ((WebControl)c).EnableViewState = false; } 

我唯一不能100%确定(并且我没有运行我的VM)的是,是否需要转换Page.Controls,如果是这样的话,请改为:

 IEnumerable controlsWithoutViewState = Page.Controls.Cast().Where(c => !allowedControls.Contains(c.ID)); 

以上只是一个快速概念的做法,它没有考虑嵌套控件,你可能想要1和1没有ViewState,但是要做一个重复函数来处理它并不困难。

使用.NET 4.0,您还可以定义控制适配器

 namespace BB.Common.UI.Adapters { [AspNetHostingPermission(System.Security.Permissions.SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Minimal)] public class DisableViewStateControl : System.Web.UI.Adapters.ControlAdapter { protected override void OnInit(EventArgs e) { if (Control.ViewStateMode == ViewStateMode.Inherit) Control.ViewStateMode = ViewStateMode.Disabled; base.OnInit(e); } } } 

在上面的代码中,ViewState模式在inheritance时被禁用。 在浏览器设置文件中添加以下行。

              

通过这种方式,您可以在整个应用程序中为每个控件提供更多粒度的cotnrol over viewstate。 您需要控制才能让viewstate在代码中启用它。 而已。

最简单的解决方案是:

 <%@ Page Language="C#" EnableViewState="true" ViewStateMode="Disabled" %> 

以及要启用viewstate的任何位置:

  

所有信用保留给Shredder在这篇文章中的回答

您也可以从BasePageinheritance。 在BasePage上禁用ViewState。

 ///  /// All pages inherit this page ///  public class BasePage : System.Web.UI.Page { protected override void OnLoad(EventArgs e) { base.OnLoad(e); } public bool ViewStateEnabled { get { return Page.EnableViewState; } set { Page.EnableViewState = value; } } public BasePage() { // Disable ViewState By Default ViewStateEnabled = false; } } 

在希望ViewState Enabled的每个页面中,您在Page_Load中执行以下操作:

 public partial class Products_Default : BasePage { protected void Page_Load(object sender, EventArgs e) { this.ViewStateEnabled = true; } } 

这应该只为该页面启用ViewState(假设它在MasterPage中为ON)。 注意:您需要在该页面上单独设置每个控件的ViewState。

您还可以对内置控件进行子类化,并在子类中将EnableViewState属性设置为false。

我很想知道塞缪尔的方法是否奏效。 如果您尝试,请发布您的结果。

我不是说撒母耳错了,我只是好奇。

我很好奇的原因是因为viewstate是递归序列化的(如Samuel所提到的),如果你有一个控件启用了viewstate,那是一个禁用了viewstate的控件的子控件,那么子控件将没有viewstate因为递归序列化会完全在父级别跳过它。 如果您构建了自己包含大量子控件的自己的用户控件,那么这将特别令人不安。

另一个解决方案是使用Samuel的实用方法方法,但不是禁用所有内容,只需禁用它,如Label,Literal等没有孩子的控件……或者如果他们确实有孩子,如果孩子有viewstate禁用则没问题。

您自然希望避免因上述原因而禁用面板和占位符的视图状态。

编辑:

 Public Shared Sub DisableViewState(ByVal cntrl As Control) If TypeOf cntrl Is Label Then cntrl.EnableViewState = False ElseIf TypeOf cntrl Is Literal Then cntrl.EnableViewState = False ElseIf TypeOf cntrl Is Button Then cntrl.EnableViewState = False Else If cntrl.Controls IsNot Nothing Then For Each subControl As Control In cntrl.Controls DisableViewState(subControl) Next End If End If End Sub