当我禁用页面的ViewState时。它不允许任何其他控件使用ViewState ..即使我为该特定控件设置EnableViewState =“true”..
是否可以在为页面本身禁用ViewState时为控件启用ViewState?
如果不能如何禁用页面上控件的viewstate除了少数而没有明确指定EnableViewState =“false”...在很多控件中输入相同的东西是忙碌..
答案 0 :(得分:22)
如果关闭翻页的ViewState,则无法为特定组件启用ViewState。这是因为ViewState是递归序列化的,因此当Page不允许ViewState时,它不会为任何子控件序列化ViewState。
在回答您的问题时,如果您不想在单个控件上明确关闭ViewState,但想要保持一些控件ViewState,最好的方法是编写一个小的实用程序方法,为所有控件关闭ViewState (使用递归或其他方式)。然后为要为其启用ViewState的控件启用ViewState。
或者,如果控件是其他容器控件(例如Panel)中的组,则可以采用中间地板且不太有力的方式。您可以通过禁用Panel的ViewState来禁用Panel内所有控件的ViewState。
答案 1 :(得分:6)
如果您关闭翻页的ViewState, 然后你无法启用 特定组件的ViewState。 这是因为ViewState是序列化的 递归,所以如果Page是 不允许ViewState,它不会 为任何一个序列化ViewState 它是子控件。它的子控件。
随着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);
}
}
}
这是浏览器文件的代码:
<browser refID="default">
<controladapters>
<adapter controlType="System.Web.UI.Page" adapterType="Playground.Web.UI.Adapters.PageAdapter" />
</controladapters>
</browser>
答案 2 :(得分:2)
这里有一些代码扩展了@Samuel Kim的概念,即在某些控件上禁用ViewState(顺便说一句,它使用.NET 3.5):
List<string> allowedControls = new List<string> { "Control1", "Control3" };
IEnumerable<Control> 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<Control> controlsWithoutViewState = Page.Controls.Cast<Control>().Where(c => !allowedControls.Contains(c.ID));
以上只是一个快速概念的做法,它没有考虑嵌套控件,你可能想要1和1没有ViewState,但是要做一个重复函数来处理它并不困难
答案 3 :(得分:2)
使用.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模式在继承时被禁用。在浏览器设置文件中添加以下行。
<browsers>
<browser refID="Default" >
<controlAdapters>
<adapter
controlType="System.Web.UI.WebControls.Label"
adapterType="Fiserv.Common.UI.Adapters.DisableViewStateControl" />
<adapter
controlType="System.Web.UI.WebControls.HyperLink"
adapterType="Fiserv.Common.UI.Adapters.DisableViewStateControl" />
<adapter
controlType="System.Web.UI.WebControls.ImageButton"
adapterType="Fiserv.Common.UI.Adapters.DisableViewStateControl" />
<adapter
controlType="System.Web.UI.WebControls.Button"
adapterType="Fiserv.Common.UI.Adapters.DisableViewStateControl" />
<adapter
controlType="System.Web.UI.WebControls.TextBox"
adapterType="Fiserv.Common.UI.Adapters.DisableViewStateControl" />
<adapter
controlType="System.Web.UI.WebControls.CheckBox"
adapterType="Fiserv.Common.UI.Adapters.DisableViewStateControl" />
<adapter
controlType="System.Web.UI.WebControls.HiddenField"
adapterType="Fiserv.Common.UI.Adapters.DisableViewStateControl" />
</controlAdapters>
</browser>
</browsers>
通过这种方式,您可以在整个应用程序中为每个控件提供更多粒度的cotnrol over viewstate。而且你需要控制才能让viewstate在代码中启用它。就是这样。
答案 4 :(得分:2)
最简单的解决方案是:
<%@ Page Language="C#" EnableViewState="true" ViewStateMode="Disabled" %>
以及您要启用viewstate的任何位置:
<asp:yourcontrol EnableViewState="true" ViewStateMode="Enabled">
Shredder对此post
的回答保留所有信用答案 5 :(得分:0)
您也可以从BasePage继承。在BasePage上禁用ViewState。
/// <summary>
/// All pages inherit this page
/// </summary>
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的每个页面中,您在Page_Load中执行以下操作:
public partial class Products_Default : BasePage {
protected void Page_Load(object sender, EventArgs e) {
this.ViewStateEnabled = true;
}
}
这应该只为该页面启用ViewState(假设它在MasterPage中为ON)。注意:您需要在该页面上单独设置每个控件的ViewState。
答案 6 :(得分:0)
我很想知道塞缪尔的方法是否奏效。如果您尝试,请发布您的结果。
我不是说撒母耳错了,我只是好奇。
我很好奇的原因是因为viewstate是递归序列化的(如Samuel所提到的)如果你有一个控件启用了viewstate,那是一个禁用了viewstate的控件的子控件,那么子控件就没有viewstate因为递归序列化将完全在父级别跳过它。如果您构建了自己的用户控件,自然会包含很多子控件,那么这将特别令人不安。
另一个解决方案是使用Samuel的实用方法方法,但不是禁用所有内容,只需禁用它,如Label,Literal等没有孩子的控件......或者如果他们确实有孩子,那么孩子们可以viewstate disabled。
您自然希望避免因上述原因而禁用Panels和Placeholders的视图状态。
编辑:
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
答案 7 :(得分:0)
您也可以对内置控件进行子类化,并在子类中将EnableViewState属性设置为false。