简体   繁体   English

如何序列化ViewState对象

[英]How to serialize a ViewState objects

I have some functions that query a database and puts the result into a gridview. 我有一些查询数据库的函数,并将结果放入gridview。 It also sets a ViewState variable that contains the results of the query. 它还设置一个包含查询结果的ViewState变量。 When I postback, I have a load function that loads the gridview from the last results if any. 当我回发时,我有一个加载函数,从最后的结果(如果有的话)加载gridview。

The Problem I am having is that I am getting an error that basically says that the viewstate object needs to be serialized. 我遇到的问题是我收到的错误基本上表明viewstate对象需要序列化。 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]].' 错误:Sys.WebForms.PageRequestManagerServerErrorException:序列化值'System.Collections.Generic.List 1[<>f__AnonymousType17 2 [System.Int32,System.String]]'的类型为'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] . 如果你真的想将它存储在View State中,那么你可能希望有一个可以标记为[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 . 问题是,您无法使用ViewState传递匿名对象。 One solution would be to create strongly typed models and use them instead the anonymous objects. 一种解决方案是创建强类型模型,并使用它们代替匿名对象。 Create a Player class: 创建一个Player类:

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. 对所有动态结果(更改它们以使用具体类)和绑定resp执行此操作。 serialization resp. 序列化 passing via ViewState should work properly. 通过ViewState传递应该正常工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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