简体   繁体   中英

How to serialize a ViewState objects

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.List 1[[<>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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM