C# 如何序列化ViewState对象
我有一些查询数据库并将结果放入gridview的函数。它还设置一个ViewState变量,该变量包含查询结果。当我回发时,我有一个加载函数,从最后的结果加载gridview(如果有的话) 我遇到的问题是,我得到一个错误,基本上是说viewstate对象需要序列化。从我所拥有的,我不知道如何做到这一点 错误:Sys.WebForms.PageRequestManagerServerErrorException:错误 序列化值 'System.Collections.Generic.List1[f_uAnonymousType172[System.Int32,System.String]' 类型 'System.Collections.Generic.List1[[f_uuAnonymousType172[[System.Int32, mscorlib,版本=4.0.0.0,区域性=中性, PublicKeyToken=b77a5c561934e089],[System.String,mscorlib, 版本=4.0.0.0,区域性=中性,PublicKeyToken=b77a5c561934e089], App_Web_rjb524gi,版本=0.0.0.0,文化=中性, PublicKeyToken=null].' 到目前为止,我的代码是:C# 如何序列化ViewState对象,c#,linq,entity-framework,gridview,viewstate,C#,Linq,Entity Framework,Gridview,Viewstate,我有一些查询数据库并将结果放入gridview的函数。它还设置一个ViewState变量,该变量包含查询结果。当我回发时,我有一个加载函数,从最后的结果加载gridview(如果有的话) 我遇到的问题是,我得到一个错误,基本上是说viewstate对象需要序列化。从我所拥有的,我不知道如何做到这一点 错误:Sys.WebForms.PageRequestManagerServerErrorException:错误 序列化值 'System.Collections.Generic.List1[f_
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Runtime.Serialization;
public partial class PlayersManagement : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
LoadData();
}
}
public void LoadData()
{
if (ViewState["CurrentGridView"] != null || ViewState["CurrentGridView"] == "")
{
GridViewPlayers.DataSource = ViewState["CurrentGridView"];
GridViewPlayers.DataBind();
}
else
{
DBModel.DBEntities context = new DBModel.DBEntities();
var players= (from f in context.Players
where f.isDeleted == false
select new
{
f.PlayerId,
f.PlayerName
}).ToList();
GridViewPlayers.DataSource = players;
GridViewPlayers.DataBind();
}
ViewState["Sort"] = 0;
}
/**
* This method is for advance search functionality
*
*/
protected void btnSearch_Click(object sender, EventArgs e)
{
// If the search textbox is not empty
if (txtSearch.Text.Trim() != "")
{
// Call to Entity Model Framework
DBModel.DBEntities context = new DBModel.DBEntities();
//Querying the Players table
var search = (from s in context.Players
where s.PlayerName.Contains(txtSearch.Text.Trim())
select new
{
s.PlayerId,
s.PlayerName
}).ToList();
if (search.Count != 0)
{
noResults.Visible = false;
GridViewPlayers.DataSource = search;//Connecting query to the datasource Gridview
ViewState["CurrentGridView"] = search; // <---- Error cause here
GridViewPlayers.DataBind(); //Binding Gridview
}
else
{
noResults.Visible = true;
noResults.Text = "This '" + txtSearch.Text + "' Query Returned No Results";
txtSearch.Text = "";
}
}
}
protected void Gridview_Sort(object sender, GridViewSortEventArgs e)
{
//Label2.Text = e.SortExpression + " " + ConvertSortDirectionToSql(e.SortDirection);
DBModel.DBEntities context = new DBModel.DBEntities();
var players = (from b in context.Players
where b.isDeleted == false
select b);
DataTable gridviewTable = players.CopyToDataTable();
gridviewTable.DefaultView.Sort = e.SortExpression + " " + ConvertSortDirectionToSql(e.SortDirection);
GridViewPlayers.DataSource = gridviewTable;
ViewState["CurrentGridView"] = gridviewTable; <--- Also causes error
GridViewPlayers.DataBind();
}
private string ConvertSortDirectionToSql(SortDirection sortDirection)
{
string newSortDirection = String.Empty;
int sort = (ViewState["Sort"] == null) ? 0 : (int)ViewState["Sort"];
switch (sort)
{
case 0:
newSortDirection = "ASC";
ViewState["Sort"] = 1;
break;
case 1:
newSortDirection = "DESC";
ViewState["Sort"] = 0;
break;
}
return newSortDirection;
}
protected void GridViewPlayers_RowEditing(object sender, GridViewEditEventArgs e)
{
GridViewPlayers.EditIndex = e.NewEditIndex;
LoadData();
}
protected void GridViewPlayers_CancelEditRow(object sender, GridViewCancelEditEventArgs e)
{
GridViewPlayers.EditIndex = -1;
LoadData();
}
如果您真的想将其存储在视图状态,那么您可能需要一个可以标记为[Serializable]的类型。看起来匿名类型不是。因此,与其使用:
var search
使用
但是,看起来每次都在查询数据库,因此即使存储在viewstate中,也不会获得任何结果 问题是,无法使用ViewState传递匿名对象。一种解决方案是创建强类型模型,并使用它们代替匿名对象。创建一个玩家类: 然后像这样使用它:
var search = (from s in context.Players
where s.PlayerName.Contains(txtSearch.Text.Trim())
select new Player
{
PlayerId = s.PlayerId,
PlayerName = s.PlayerName
}).ToList();
而不是:
var search = (from s in context.Players
where s.PlayerName.Contains(txtSearch.Text.Trim())
select new
{
s.PlayerId,
s.PlayerName
}).ToList();
对所有动态结果执行此操作将它们更改为使用具体类和绑定响应。序列化响应。通过ViewState传递应该可以正常工作。GridViewPlayer.DataSource=ViewState[CurrentGridView];无法正确反序列化该类。一种选择是添加一个类Player{public int PlayerId;public string PlayerName;}并强制转换结果,例如GridViewPlayers.DataSource=List ViewState[CurrentGridView];会话似乎可以工作,但我不希望会话对象在应用程序周围浮动,而是希望在页面更改时终止它。这会更好吗?所以我认为使用EF实体框架的目的是让开发人员不必创建模型类。如果您的实体已经创建了Player类,那么请尝试将ViewState['something']强制转换为Player[]和/或ListYes,这是EF为帮助开发人员而完成的任务之一,但是您没有使用EF创建的类。相反,您正在创建一个。如果您已经有一个从EF创建的玩家类,那么使用它而不是选择new{。。。。
public class Player
{
public Int32 PlayerId { get; set; }
public String PlayerName { get; set; }
}
var search = (from s in context.Players
where s.PlayerName.Contains(txtSearch.Text.Trim())
select new Player
{
PlayerId = s.PlayerId,
PlayerName = s.PlayerName
}).ToList();
var search = (from s in context.Players
where s.PlayerName.Contains(txtSearch.Text.Trim())
select new
{
s.PlayerId,
s.PlayerName
}).ToList();