I have some functions that query a database and puts the result into a gridview. It also sets a ViewState variable that contains the results of the query. When I postback, I have a load function that loads the gridview from the last results if any.
The Problem I am having is that I am getting an error that basically says that the viewstate object needs to be serialized. From what I have I am not sure how to do this.
Error: Sys.WebForms.PageRequestManagerServerErrorException: Error serializing value 'System.Collections.Generic.List
1[<>f__AnonymousType17
2[System.Int32,System.String]]' of type 'System.Collections.Generic.List1[[<>f__AnonymousType17
2[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], App_Web_rjb524gi, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]].'
My code so far:
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();
}
If you really want to store it in View State then you will probably want to have a type that can be marked as [Serializable]
. It looks like the anonymous type is not. So instead of using:
var search
use
List<Player> search = Query
And the class.
[Serializable]
public class Player
{
public int PlayerId {get;set;}
public string PlayerName {get;set;}
}
However, It looks like you are querying the db each time, so even if you did store in viewstate you wouldnt be gaining anything.
The problem is, that you can't pass anonymous objects using the ViewState
. One solution would be to create strongly typed models and use them instead the anonymous objects. Create a Player
class:
public class Player
{
public Int32 PlayerId { get; set; }
public String PlayerName { get; set; }
}
and use it like this:
var search = (from s in context.Players
where s.PlayerName.Contains(txtSearch.Text.Trim())
select new Player
{
PlayerId = s.PlayerId,
PlayerName = s.PlayerName
}).ToList();
instead of:
var search = (from s in context.Players
where s.PlayerName.Contains(txtSearch.Text.Trim())
select new
{
s.PlayerId,
s.PlayerName
}).ToList();
Do this for all your dynamic results (change them to use concrete classes) and the binding resp. serialization resp. passing via ViewState
should work properly.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.