基本上我正在尝试使用 ViewState 在回发之间保留对象。此外,我试图将这些对象封装在私有类的属性中。
这样做的目的是重构以前使用静态字段来持久化对象的现有代码,这显然会导致问题。
所以这是一个非常简单的 Web 表单 HTML 示例:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="WebApplication3.WebForm1" %>
<!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:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<br />
<asp:Button ID="Button1" runat="server" Text="Button" />
</div>
</form>
</body>
</html>
这是一个非常简单的初始代码隐藏示例(不是我自己编写的):
using System;
using System.Web.UI;
namespace WebApplication3
{
public partial class WebForm1 : Page
{
private static string[,] _my2DArray;
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
_my2DArray = new string[3,3];
for (var i = 0; i < 3; i++)
{
for (var j = 0; j < 3; j++)
{
_my2DArray[i, j] = Guid.NewGuid().ToString();
}
}
}
TextBox1.Text = _my2DArray[1, 1];
}
}
}
这实现了在回发之间持久化对象的目标,但会导致问题,因为它也会在其他所有事物之间持久化对象。
我的想法是将它重构为这样的东西,因为有很多使用这个对象的代码隐藏,并且在实际应用程序中还有更多的对象。我想在更改尽可能少的代码的同时解决问题(resharper 可以轻松地将字段移出到单独的类中,并将它们转换为属性。然后我修改了属性代码以使用 Viewstate 而不是私有支持场地):
using System;
using System.Web.UI;
namespace WebApplication3
{
public partial class WebForm1 : Page
{
internal class MyClass
{
private readonly WebForm1 _webForm1;
internal MyClass(WebForm1 webForm1)
{
_webForm1 = webForm1;
}
internal string[,] My2DArray
{
set { _webForm1.ViewState["_my2DArray"] = value; }
get { return (string[,])_webForm1.ViewState["_my2DArray"]; }
}
}
private MyClass _myClass;
protected void Page_Load(object sender, EventArgs e)
{
_myClass = new MyClass(this);
if (!IsPostBack)
{
_myClass.My2DArray = new string[3,3];
for (var i = 0; i < 3; i++)
{
for (var j = 0; j < 3; j++)
{
_myClass.My2DArray[i, j] = Guid.NewGuid().ToString();
}
}
}
TextBox1.Text = _myClass.My2DArray[1, 1];
}
}
}
这几乎奏效了。除了 2D 数组之外,还有字符串 int 和 booleans,它们都可以使用此方法按预期工作。但是当我将二维数组加入混合时,我得到以下错误:
此页面的状态信息无效,可能已损坏。
源错误:
[没有相关的源代码行]
堆栈跟踪:
[EndOfStreamException: Unable to read beyond the end of the stream.]
System.IO.BinaryReader.ReadByte() +9616466
System.Web.UI.ObjectStateFormatter.DeserializeValue(SerializerBinaryReader reader) +44
System.Web.UI.ObjectStateFormatter.DeserializeValue(SerializerBinaryReader reader) +380
System.Web.UI.ObjectStateFormatter.Deserialize(Stream inputStream) +141
[ArgumentException: The serialized data is invalid.]
System.Web.UI.ObjectStateFormatter.Deserialize(Stream inputStream) +205
System.Web.UI.ObjectStateFormatter.Deserialize(String inputString) +337
System.Web.UI.ObjectStateFormatter.System.Web.UI.IStateFormatter.Deserialize(String serializedState) +4
System.Web.UI.Util.DeserializeWithAssert(IStateFormatter formatter, String serializedState) +37
System.Web.UI.HiddenFieldPageStatePersister.Load() +147
[ViewStateException: Invalid viewstate.
Client IP: 127.0.0.1
Port:
Referer: http://localhost:27314/WebForm1.aspx
Path: /WebForm1.aspx
User-Agent: Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.62 Safari/537.36
ViewState: /wEPDwULLTE0MDM4MzYxMjMPFgIeBkZvb2JhcmRkem7xFcvXyGXVXNDDKHSutQ9j/EhfbWTpihkzXIlH66A=]
[HttpException (0x80004005): The state information is invalid for this page and might be corrupted.]
System.Web.UI.ViewStateException.ThrowError(Exception inner, String persistedState, String errorPageMessage, Boolean macValidationError) +198
System.Web.UI.ViewStateException.ThrowViewStateError(Exception inner, String persistedState) +14
System.Web.UI.HiddenFieldPageStatePersister.Load() +251
System.Web.UI.Page.LoadPageStateFromPersistenceMedium() +106
System.Web.UI.Page.LoadAllState() +43
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +8431
System.Web.UI.Page.ProcessRequest(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +253
System.Web.UI.Page.ProcessRequest() +78
System.Web.UI.Page.ProcessRequestWithNoAssert(HttpContext context) +21
System.Web.UI.Page.ProcessRequest(HttpContext context) +49
ASP.webform1_aspx.ProcessRequest(HttpContext context) in c:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files\root\37286ff3\6dc3cf92\App_Web_t5caigbu.0.cs:0
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +100
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +75
我难住了。如果您在 VS 中创建一个新的 Webforms 解决方案并将上面的 HTML + 代码复制到它们各自的文件中,那么您将拥有我所拥有的。
我正在使用 Visual Studio 2010 并以 .Net 4 为目标。
当我使用此方法在具有 2D 数组的回发之间保留对象但没有其他类型的对象时,为什么会出现此错误的任何想法?
干杯