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

StackOverflow https://stackoverflow.com/questions/186657

  •  06-07-2019
  •  | 
  •  

Вопрос

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

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

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

Это было полезно?

Решение

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

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

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

Другие советы

  

Если вы отключите 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>

Вот некоторый код, который расширяет концепцию @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 с 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 отключен, когда он наследуется. Добавьте следующую строку в файл настроек браузера.

<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 просто включил его в коде. Вот и все.

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

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

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

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

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

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

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

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

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

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

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

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

Редактировать:

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
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top