Включить ViewState для нескольких элементов управления и отключить для других / страницы - PullRequest
13 голосов
/ 09 октября 2008

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

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

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

Ответы [ 8 ]

22 голосов
/ 09 октября 2008

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

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

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

6 голосов
/ 06 ноября 2010

Если вы отключите ViewState страницы, тогда у вас нет возможности включить ViewState для конкретных компонентов. Это потому, что ViewState является сериализованным рекурсивно, поэтому, если, если страница не позволяя 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 голосов
/ 19 июня 2012

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

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

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

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

Все кредиты зарезервированы для ответа Шреддера на этом сообщении

2 голосов
/ 07 мая 2012

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

Таким образом, вы можете иметь более детальный контроль над состоянием просмотра для каждого отдельного элемента управления в приложении. И там, где вам нужен контроль, чтобы viewstate просто включил его в коде. Вот и все.

2 голосов
/ 09 октября 2008

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

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

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

0 голосов
/ 04 декабря 2009

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

0 голосов
/ 04 декабря 2009

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

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

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

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

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

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
0 голосов
/ 10 февраля 2009

Вы также можете наследовать от 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 каждого элемента управления на этой странице.

...