2008-10-09 7 views
13

Cuando desactivo ViewState para la página. No permite que ningún otro control use ViewState ... incluso si configuro EnableViewState = "true" para ese control en particular ...Habilitar ViewState para algunos controles y deshabilitar para otros/página

¿es posible habilitar ViewState para un control cuando ViewState está deshabilitado para la página misma?

si no cómo se puede desactivar estado de vista de los controles en la página excepción de unos pocos, sin especificar EnableViewState = "false" explícitamente .. escribir el mismo en tantos controles es agitado ..

Respuesta

22

Si establece el turno de la página ViewState fuera, entonces no hay forma de que habilite ViewState para componentes específicos. Esto se debe a que ViewState se serializa de forma recursiva, por lo tanto, si la página no permite ViewState, no serializará ViewState para ninguno de sus controles secundarios.

En respuesta a su pregunta, si no desea desactivar ViewState explícitamente en controles individuales, pero quiere mantener algunos controles en ViewState, la mejor manera sería escribir un pequeño método de utilidad que desactive ViewState para todos controles (usando recursión o de otro tipo). Luego habilite ViewState para los controles que le gustaría habilitar ViewState.

Alternativamente, es posible que haya una posición intermedia y menos contundente si los controles son grupos dentro de otros controles de contenedor (como el Panel). Puede deshabilitar ViewState para todos los controles dentro de un Panel deshabilitando ViewState del Panel.

+0

¿El mismo concepto de trabajo en una Placeholder? Eso solucionaría el problema de generar etiquetas HTML excesivas. –

+0

El marcador de posición solo es beneficioso en los contenidos de texto.Si tiene un control de calendario y no quiere tener ViewState, no quiere usar Placeholder y escribir el calendario HTML. –

+0

Es ciertamente y una opción, pero al desactivar viewstate para el contenedor, se desactivaría viewstate para todos los controles secundarios, incluidos los lables. – Zuhaib

2

Aquí hay un código que se expande el concepto de tener una manera de desactivar ViewState en todos pero ciertos controles (por cierto, se utiliza .NET 3.5) de @Samuel Kim:

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; 
} 

La única cosa que no soy 100% seguro en (y yo no tengo mi máquina virtual en ejecución) es si Page.Controls necesita ser echado o no, si lo que sólo tienen en su lugar:

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

lo anterior es sólo un concepto rápido de lo hacer, no tiene en cuenta los controles anidados donde puede querer 1 con y 1 sin ViewState, pero es w No sería difícil hacer una función recusiva para manejarlo.

+1

omitiendo el 'en' en el foreach –

0

También podría heredar desde una página base. En la BasePage, deshabilite 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; 
    } 
} 

En cada página que desea ViewState habilitada, haga lo siguiente en Load:

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

Esto debería permitir ViewState sólo para esa página (asumiendo que es ON en el MasterPage). Nota: Necesitará establecer individualmente el ViewState de cada control en esa página.

0

Tengo curiosidad por ver si el enfoque de Samuel funciona. Si lo intenta, publique su resultado.

No estoy diciendo que Samuel esté equivocado, solo sería curioso.

La razón por la que tengo curiosidad es porque viewstate se serializa recursivamente (como mencionó Samuel) si tenía un control con viewstate habilitado que era un elemento secundario de un control con viewstate deshabilitado, entonces el control secundario no tendría viewstate porque la serialización recursiva saltaría por completo en el nivel principal. Esto sería específicamente problemático si ha construido sus propios controles de usuario que naturalmente contendrían muchos controles secundarios.

Otra solución sería utilizar el enfoque del método de utilidad de Samuel, pero en lugar de deshabilitar todo, simplemente deshabilítelo para controles como Label, Literal, etc. que no tienen hijos ... o si tienen hijos, está bien si los niños have viewstate deshabilitado.

Naturalmente, querrá evitar deshabilitar la vista del estado de los paneles y marcadores de posición por el motivo que indiqué anteriormente.

Editar:

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 
0

También puede subclase los controles integrados, y en la subclase establecer la propiedad EnableViewState a falso.

6

Si establece vuelta de página ViewState fuera, entonces no hay manera para que pueda habilitar ViewState para componentes específicos. Esto se debe a que ViewState se serializa de forma recursiva, por lo que si la página es que no permite ViewState, no se serializar ViewState para cualquiera de es controles secundarios de child controls.it.

Con el advenimiento de ASP.NET 4 tenemos una nueva propiedad llamada ViewStateMode que se puede utilizar para activar el estado de vista de un control individual, incluso si el estado de vista está deshabilitada para la página.

Para hacer uso de esta nueva propiedad, puede crear una clase de página base que establezca ViewStateMode en Disabled o cree un PageAdapter que haga lo mismo. No hay propiedad viewStateMode en web.config.

Aquí está el código para el adaptador de la página:

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); 
     } 
    } 
} 

Y aquí está el código para el archivo del navegador:

<browser refID="default"> 
    <controladapters> 
     <adapter controlType="System.Web.UI.Page" adapterType="Playground.Web.UI.Adapters.PageAdapter" /> 
    </controladapters> 
</browser> 
2

Con .NET 4.0 también se pueden definir los adaptadores de control

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); 
     } 
    } 
} 

En el código anterior, el modo ViewState está deshabilitado cuando se hereda. Agregue la siguiente línea en el archivo de configuración del navegador.

<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> 

De esta manera se puede tener cotnrol más granular sobre el estado de vista para cada control único throughuout la aplicación. Y donde necesita control para tener viewstate simplemente habilítelo en el código. Eso es.

2

La solución más simple es:

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

y donde desea habilitar estado de vista:

<asp:yourcontrol EnableViewState="true" ViewStateMode="Enabled"> 

Todos los créditos reservados a la respuesta de Shredder en este post

+0

EnableViewState =" true "no es * realmente * necesario ya que es predeterminado. ViewStateMode se evalúa de la siguiente manera. si está "Deshabilitado", la propiedad EnableViewState se ignora para ese control. El código anterior básicamente ignora ViewState para la página y usa el valor existente para el control. Es una distinción importante si alguna vez necesita alternar programáticamente esos comportamientos – KevinDeus

+0

Esto solo funciona en .NET4 y superior – dgarbacz

Cuestiones relacionadas