Viewstate является нулевым при обратной передаче - PullRequest
8 голосов
/ 02 декабря 2011

Да, у меня здесь происходит что-то очень необычное ...

Страница ASP.NET 4 со следующим свойством:

protected QuickShopBag QuickShopBagInstance
{
    get { return (QuickShopBag)ViewState["QuickShopBag"]; }
    set { ViewState["QuickShopBag"] = value; }
}

В течение начального Page_Load() in (!Page.IsPostBack) заполняется QuickShopBagInstance и ViewState сохраняется.

Однако, когда вы выполняете обратную передачу на странице, ViewState пуст при обращении из события обратной передачи Button_OnClick() !!!

Я проверил Request.Form и, конечно же, значение _Viewstate там и заполнено. Я также пропустил это значение через анализатор, и он содержит ожидаемые данные, на странице есть ViewStateEnabled="true" и новый .NET 4 ViewStateMode="Enabled".

Я перешел к переопределению метода LoadViewState, чтобы проверить, не запускается ли он.

protected override void LoadViewState(object savedState)
{
    base.LoadViewState(savedState);
}

Я действительно заблудился относительно того, в чем может быть проблема. Есть идеи?

Ответы [ 4 ]

9 голосов
/ 04 декабря 2011

Прежде всего, я ошибся, рассматриваемый код был не в Page_Load, а в Page_Init, хотя я не читал ничего, что говорит, что вы не можете назначить ViewState в Init.

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

<form id="form1" runat="server">
<div>
    <asp:ListView id="QuickshopListView" runat="server">
        <LayoutTemplate>
            <asp:PlaceHolder ID="itemPlaceHolder" runat="server" />
        </LayoutTemplate>
        <ItemTemplate>
            <asp:TextBox ID="txtItem" runat="server" Text='<%# Container.DataItem %>' />
            <asp:Button ID="btnDelete" runat="server" Text="Delete" OnClick="btnDelete_Click" />
            <br />
        </ItemTemplate>
    </asp:ListView>
    <asp:Button ID="btnAdd" runat="server" Text="Add" OnClick="btnAdd_Click" />
</div>
</form>

public partial class Quickshop : System.Web.UI.Page
{
    protected QuickShopBag QuickShopBagInstance
    {
        get { return (QuickShopBag)ViewState["QuickShopBag"]; }
        set { ViewState["QuickShopBag"] = value; }
    }

    protected void Page_Init(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
        {
            if (QuickShopBagInstance == null)
                QuickShopBagInstance = new QuickShopBag();

            if (!String.IsNullOrEmpty(Request.QueryString.ToString()))
            {
                string[] items = Server.UrlDecode(Request.QueryString.ToString()).Split(',');
                if (items.Length > 0)
                {
                    foreach (string item in items)
                    {
                        QuickShopBagInstance.QuickShopItems.Add(item);
                    }
                }
            }
        }
    }

    protected void Page_LoadComplete(object sender, EventArgs e)
    {
        QuickshopListView.DataSource = QuickShopBagInstance.QuickShopItems;
        QuickshopListView.DataBind();
    }

    protected void btnAdd_Click(object sender, EventArgs e)
    {
        if (QuickShopBagInstance == null)
            QuickShopBagInstance = new QuickShopBag();

        QuickShopBagInstance.QuickShopItems.Add("add1");
        QuickShopBagInstance.QuickShopItems.Add("add2");
        QuickShopBagInstance.QuickShopItems.Add("add3");
    }

    protected void btnDelete_Click(object sender, EventArgs e)
    {
        Button DeleteButton = (Button)sender;
        ListViewDataItem item = (ListViewDataItem)DeleteButton.NamingContainer;
        QuickShopBagInstance.QuickShopItems.RemoveAt(item.DisplayIndex);
    }
}

[Serializable]
public class QuickShopBag
{
    public List<string> QuickShopItems { get; set; }

    public QuickShopBag()
    {
        this.QuickShopItems = new List<string>();
    }
}

Если вы попросите сказать "/quickshop.aspx?add1,add2,add3", ListView будет правильно заполнен даннымиоднако из qs, когда дело доходит до нажатия кнопки удаления, выдается исключение NullReferenceException, поскольку ViewState не сохранил объект QuickShopBag.

Но если вы нажмете кнопку «Добавить», которая, как вы видите, добавляетс теми же значениями для QuickShopBagInstance (и ViewState), ListView заполняется правильно, и когда вы нажимаете кнопку Удалить, он отлично работает, поскольку ViewState сохраняется.

Теперь, если вы измените чтение бита строки запроса наPage_InitComplete, в отличие от Page_Init, работает отлично.Итак, вывод ...

ВЫ НЕ МОЖЕТЕ ДОБАВИТЬСЯ В СОЗДАНИЕ ДО ПУТИ Init_Complete !!!!!!!!

Как глупо с моей стороны, ну, кто бы это ни написал!1014 *

1 голос
/ 02 декабря 2011

Похоже, вы исключили большинство предложений, поэтому я создал базовую страницу, содержащую только ту информацию, которую вы указали выше:

class

namespace SO_Questions
{
    [Serializable()]
    public class QuickShopBag
    {
        public string MyProperty { get; set; }
    }
}

codeза

namespace SO_Questions
{
    public partial class TestPage : System.Web.UI.Page
    {
        protected QuickShopBag QuickShopBagInstance
        {
            get { return (QuickShopBag)ViewState["QuickShopBag"]; }
            set { ViewState["QuickShopBag"] = value; }
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!Page.IsPostBack)
            {
                this.QuickShopBagInstance = new QuickShopBag() { MyProperty = "Test String" };
            }
            Message.Text = "Value is: " + this.QuickShopBagInstance.MyProperty.ToString();
        }

        protected override void LoadViewState(object savedState)
        {
            base.LoadViewState(savedState);
        }

        protected void btnSubmit_Click(object sender, EventArgs e)
        {
            btnSubmit.Text += QuickShopBagInstance.MyProperty;
        }
    }
}

разметка:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="TestPage.aspx.cs" Inherits="SO_Questions.TestPage" ViewStateMode="Enabled" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server"><title></title></head>
<body>
    <form id="form1" runat="server"><div>
        <asp:Label ID="Message" runat="server"></asp:Label>
        <asp:Button runat="server" ID="btnSubmit" Text="Submit" OnClick="btnSubmit_Click" />
    </div></form>
</body></html>

Как и ожидалось, все работает правильно;применяется переопределенный метод LoadViewState (и viewstate правильно содержит 2 элемента), и текст кнопки обновляется.

Логичным объяснением было бы то, что где-то еще происходит что-то еще, или вы не смогли предоставить дополнительную важную информацию.

0 голосов
/ 30 октября 2018

Просто короткая заметка.Если вы устанавливаете значение ViewState для page_load, убедитесь, что вы делаете это в

if (!IsPostBack)
{

ViewState["MyValue"] = MyValue // set dynamically with appropriate code

}

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

Или, я думаю, вы не могли бы использовать! IsPostBack, если хотите, чтобы ваш код запускался при каждой обратной передаче.Но если у вас возникли проблемы с установкой значения NULL при обратной передаче, внимательно изучите вышесказанное.

0 голосов
/ 02 декабря 2011

Что-то, что споткнуло меня в прошлом,

  1. Установка чего-либо в ViewState на странице
  2. Затем пытается получить его в пользовательском элементе управления. Не могу найти - куда он делся?

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

Может ли это быть что-то вроде этого?

Эта SO ссылка дает лучшее объяснение, что я только что сделал

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...