Включить ViewState для нескольких элементов управления и отключить для других/страницу

Когда я отключу ViewState для страницы. Он не позволяет любому другому элементу управления использовать ViewState.. даже если я установил EnableViewState = "true" для этого конкретного элемента управления.

Можно ли включить ViewState для элемента управления, если ViewState отключен для самой страницы?

если нет, то как отключить viewstate для элементов управления на странице, за исключением нескольких, не указав EnableViewState = "false" явно. Набрав то же самое во множество элементов управления, это беспокойно.

Ответы

Ответ 1

Если вы установите TurnState ViewState выключен, тогда нет возможности включить ViewState для определенных компонентов. Это связано с тем, что ViewState сериализуется рекурсивно, поэтому, если страница не разрешает ViewState, она не будет сериализовать ViewState для любого из дочерних элементов управления.

В ответ на ваш вопрос, если вы не хотите явно отключать ViewState на отдельных элементах управления, но хотите, чтобы некоторые элементы управления ViewState знали, лучший способ - написать небольшой метод утилиты, который отключит ViewState для всех элементов управления (используя рекурсию или иначе). Затем включите ViewState для элементов управления, для которых вы хотите включить ViewState для.

В качестве альтернативы, возможен средний и менее сильный способ, если элементы управления находятся внутри других элементов управления контейнерами (например, Panel). Вы можете отключить ViewState для всех элементов управления внутри Panel, отключив ViewState Panel.

Ответ 2

Если вы отключили поворот страницы ViewState, то вы не сможете включить ViewState для определенных компонентов. Это связано с тем, что ViewState сериализуется рекурсивно, поэтому, если страница не позволяя ViewState, он не будет сериализуйте ViewState для любого из это дочерние элементы управления childs.it.

С появлением ASP.NET 4 у нас есть новое свойство ViewStateMode, которое может использоваться для включения состояния просмотра для отдельного пользователя даже если состояние просмотра отключено для страницы.

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

Вот код для адаптера страницы:

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>

Ответ 3

Вот некоторый код, который расширяется в концепции @Samuel Kim о том, как отключить ViewState для всех, кроме определенных элементов управления (btw, он использует .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% (и у меня нет моей работы в виртуальной среде), - это то, нужно ли бросить страницу .Controls или нет, если это так просто:

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

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

Ответ 4

С .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 над viewstate для каждого отдельного элемента управления через приложение. И там, где вам нужно управление, чтобы viewstate просто включил его в код. Что это.

Ответ 5

Самое простое решение:

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

и везде, где вы хотите включить viewstate:

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

Все кредиты, зарезервированные для ответа Shredder на этот пост

Ответ 6

Вы также можете унаследовать от 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). Примечание. Вам необходимо индивидуально настроить каждый элемент ViewState Control на этой странице.

Ответ 7

Мне любопытно посмотреть, подходит ли подход Сэмюэля. Если вы попробуете, отправьте свой результат.

Я не говорю, что Самуэль ошибается, мне просто интересно.

Причина, по которой мне любопытно, потому что, поскольку viewstate сериализуется рекурсивно (как упоминал Самуил), если бы у вас был один элемент управления с включенным viewstate, который был дочерним элементом элемента управления с отключенным viewstate, тогда у дочернего элемента управления не было бы viewstate, потому что рекурсивная сериализация пропустит его полностью на родительском уровне. Это особенно беспокоит, если вы создали свои собственные пользовательские элементы управления, которые, естественно, содержат множество дочерних элементов управления.

Другим решением было бы использовать подход метода использования Samuel, но вместо того, чтобы отключать все, просто отключите его для элементов управления, таких как Label, Literal и т.д., у которых нет детей... или если у них есть дети, это нормально, если у детей есть viewstate отключено.

Вы, естественно, хотели бы избежать отключения панели просмотра панелей и заполнителей по причине, о которой я говорил выше.

Edit:

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

Ответ 8

Вы также можете подклассифицировать встроенные элементы управления, а в вашем подклассе установить свойство EnableViewState равным false.