【问题标题】:Server.transfer not working correctlyServer.transfer 无法正常工作
【发布时间】:2013-10-22 17:15:13
【问题描述】:

我有 2 个 aspx 页面。 CreateEstimate1.aspx 和 CreateEstimate2.aspx。如果我直接导​​航到 CreateEstimate2.aspx,一切正常,完全没有问题。但是如果我在 CreateEstimate1.aspx 上然后有一个 server.transfer("CreateEstimate2.aspx") 我得到最奇怪的错误。

我有一个内置在 Page_init 中的 radgrid,如果我直接进入该页面,它就可以正常工作。但是,一旦我使用 server.transfer 或 response.redirect 从 CreateEstimate1.aspx 转移到 CreateEstimate2.aspx,我就会收到以下错误:

“无法将“System.Int32”类型的对象转换为“System.Data.DataTable”类型。”

CreateEstimate2.aspx

public partial class Admin_CreateEstimate2 : System.Web.UI.Page
{
    invoicer inv = new invoicer();


    protected void Page_Init(object sender, EventArgs e)
    {

        string ctrlname = this.Page.Request.Params.Get("__EVENTTARGET");

        if (Session["Tables"] == null)
        {
            Session.Add("Tables", 1);
            DataTable dt = inv.GetTable();

            Session.Add(Session["Tables"].ToString(), dt);
            inv.DefineGridStructure(1, PlaceHolder2, true);
        }
        if (IsPostBack)
        {
            ctrlname = ctrlname.Split('$').Last();

            int next = Convert.ToInt32(inv.GetSession());
            PlaceHolder2.Controls.Clear();
            inv.loopGrids(PlaceHolder2);

            if (ctrlname == "Button1")
            {
                next = next + 1;
                Session.Add("Tables", next);
                Response.Write("Button getSession: " + inv.GetSession());
                DataTable dt = inv.GetTable();
                Session.Add(Session["Tables"].ToString(), dt);
                inv.DefineGridStructure(next, PlaceHolder2, true);
            }

        }
    }



    protected void Button1_Click(object sender, EventArgs e)
    {

    }

    protected void Button2_Click(object sender, EventArgs e)
    {
        inv.PreviewAll(PlaceHolder2);
    }
}

invoicer.cs

public class invoicer
{
    public class MyTemplate : ITemplate
    {
        private string colname;
        protected Label lControl;

        public MyTemplate(string cName)
        {
            colname = cName;
        }
        public void InstantiateIn(System.Web.UI.Control container)
        {
            lControl = new Label();
            lControl.ID = "Label-DurationType";
            lControl.DataBinding += new EventHandler(lControl_DataBinding);
            container.Controls.Add(lControl);
        }

        public void lControl_DataBinding(object sender, EventArgs e)
        {
            Label l = (Label)sender;
            GridDataItem container = (GridDataItem)l.NamingContainer;
            l.Text = ((DataRowView)container.DataItem)[colname].ToString() + "<br />";
        }
    }


    public class MyEditTemplate : IBindableTemplate
    {
        public void InstantiateIn(Control container)
        {
            GridEditableItem item = ((GridEditableItem)(container.NamingContainer));
            DropDownList drop = new DropDownList();
            drop.ID = "DurationType-DDL";
            drop.DataSource = (DataTable)GetTableForDropDown();
            drop.DataTextField = "DurationType";
            drop.DataValueField = "DurationType";
            container.Controls.Add(drop);
        }

        public System.Collections.Specialized.IOrderedDictionary ExtractValues(System.Web.UI.Control container)
        {
            OrderedDictionary od = new OrderedDictionary();
            od.Add("DurationType", ((DropDownList)(((GridDataItem)(container)).FindControl("DurationType-DDL"))).DataValueField);
            return od;
        }
    }

    void grid_NeedDataSource(object sender, GridNeedDataSourceEventArgs e)
    {
        RadGrid grid = (RadGrid)sender;
        string id = grid.ID;
        DataTable current = (DataTable)HttpContext.Current.Session[int.Parse(id.Split(new string[] { "RadGrid" }, StringSplitOptions.RemoveEmptyEntries)[0])];
        grid.DataSource = current;
    }



    protected void grid_ItemDataBound(object sender, Telerik.Web.UI.GridItemEventArgs e)
    {
        if (e.Item is GridEditableItem && e.Item.IsInEditMode)
        {
            GridEditableItem editItem = (GridEditableItem)e.Item;
            DropDownList ddl = (DropDownList)editItem.FindControl("DurationType-DDL");
            ddl.DataSource = (DataTable)GetTableForDropDown();
            ddl.DataTextField = "DurationType";
            ddl.DataValueField = "DurationType";
            ddl.SelectedIndex = editItem.ItemIndex;
            ddl.SelectedValue = DataBinder.Eval(editItem.DataItem, "DurationType").ToString(); // To get the selected value         
        }
    }


    public void DefineGridStructure(int i, PlaceHolder ph, Boolean bl)
    {

        RadGrid grid = new RadGrid();
        grid.ID = "RadGrid" + i.ToString();
        grid.Visible = bl;
        //grid.Height = Unit.Pixel(200);
        //grid.Height = Unit.Percentage(100);
        grid.Width = Unit.Pixel(775);
        grid.NeedDataSource += new GridNeedDataSourceEventHandler(grid_NeedDataSource);
        grid.AutoGenerateEditColumn = true;
        grid.AutoGenerateDeleteColumn = true;
        grid.AllowAutomaticInserts = false;
        //grid.Width = Unit.Percentage(100);
        grid.PageSize = 15;
        grid.AllowPaging = true;
        grid.AllowFilteringByColumn = false;
        grid.PagerStyle.Mode = GridPagerMode.NextPrevAndNumeric;
        grid.AutoGenerateColumns = false;
        //grid.MasterTableView.Width = Unit.Percentage(100);
        grid.MasterTableView.Width = Unit.Pixel(775);
        grid.MasterTableView.CommandItemDisplay = GridCommandItemDisplay.TopAndBottom;
        grid.AllowAutomaticDeletes = false;
        grid.AllowAutomaticUpdates = false;
        grid.ItemDataBound += new GridItemEventHandler(grid_ItemDataBound);
        grid.InsertCommand += grid_InsertCommand;
        grid.DeleteCommand += grid_DeleteCommand;
        grid.UpdateCommand += grid_UpdateCommand;
        grid.MasterTableView.DataKeyNames = new string[] { "RowNumber" };
        GridBoundColumn boundColumn = new GridBoundColumn();
        boundColumn.DataField = "RowNumber";
        boundColumn.HeaderText = "RowNumber";
        boundColumn.ItemStyle.Width = Unit.Pixel(5);
        boundColumn.ReadOnly = true;
        boundColumn.ItemStyle.CssClass = "maximize";
        grid.MasterTableView.Columns.Add(boundColumn);
        boundColumn = new GridBoundColumn();
        boundColumn.DataField = "Size";
        boundColumn.HeaderText = "Size";
        boundColumn.ItemStyle.Width = Unit.Pixel(5);
        boundColumn.ItemStyle.CssClass = "maximize";
        grid.MasterTableView.Columns.Add(boundColumn);
        boundColumn = new GridBoundColumn();
        boundColumn.DataField = "Description";
        boundColumn.HeaderText = "Description";
        boundColumn.ItemStyle.Width = Unit.Pixel(20);
        boundColumn.ItemStyle.CssClass = "maximize";
        grid.MasterTableView.Columns.Add(boundColumn);
        boundColumn = new GridBoundColumn();
        boundColumn.DataField = "Quantity";
        boundColumn.HeaderText = "Quantity";
        boundColumn.ItemStyle.Width = Unit.Pixel(5);
        boundColumn.ItemStyle.CssClass = "maximize";
        grid.MasterTableView.Columns.Add(boundColumn);
        boundColumn = new GridBoundColumn();
        boundColumn.DataField = "Unit";
        boundColumn.HeaderText = "Unit";
        boundColumn.ItemStyle.Width = Unit.Pixel(5);
        boundColumn.ItemStyle.CssClass = "maximize";
        grid.MasterTableView.Columns.Add(boundColumn);


        GridAutoCompleteColumn aboundColumn = new GridAutoCompleteColumn();
        aboundColumn.DataField = "Duration";
        aboundColumn.HeaderText = "Duration";
        aboundColumn.DataTextField = "Duration";
        aboundColumn.DataValueField = "Duration";
        //aboundColumn.AllowCustomEntry = false;
        //aboundColumn.SelectionMode = RadAutoCompleteSelectionMode.Single;
        boundColumn.ItemStyle.Width = Unit.Pixel(5);
        boundColumn.ItemStyle.CssClass = "maximize";
        grid.MasterTableView.Columns.Add(aboundColumn);



        GridTemplateColumn objGridTemplateColumn = new GridTemplateColumn();
        objGridTemplateColumn.HeaderText = "DurationType";
        objGridTemplateColumn.DataField = "DurationType";
        objGridTemplateColumn.ItemTemplate = new MyTemplate("DurationType");
        objGridTemplateColumn.EditItemTemplate = new MyEditTemplate();
        objGridTemplateColumn.ItemStyle.CssClass = "maximize";
        grid.MasterTableView.Columns.Add(objGridTemplateColumn);

        boundColumn = new GridBoundColumn();
        boundColumn.DataField = "Amount";
        boundColumn.HeaderText = "Amount";
        grid.MasterTableView.Columns.Add(boundColumn);
        boundColumn.ItemStyle.Width = Unit.Pixel(10);
        boundColumn.ItemStyle.CssClass = "maximize";
        grid.MasterTableView.EditMode = GridEditMode.InPlace;


        grid.ItemCreated += grid_ItemCreated;

        LinkButton lb = new LinkButton();

        if (bl == false)
        {

            lb.ID = "Show-Grid-" + i.ToString();
            lb.Text = "Show Area " + i.ToString();
            lb.Click += new EventHandler(ShowGrid);
        }
        else
        {

            lb.ID = "Show-Grid-" + i.ToString();
            lb.Text = "Hide Area " + i.ToString();
            lb.Click += new EventHandler(ShowGrid);
        }
        LinkButton lbd = new LinkButton();
        lbd.ID = "Delete-Grid-" + i.ToString();
        lbd.Text = "Delete Area " + i.ToString();
        lbd.Click += (sender, e) => DeleteGrid(sender, e, ph);

        Label lbl = new Label();
        lbl.ID = "Split-" + i.ToString();
        lbl.Text = "     |     ";

        Label lbb = new Label();
        lbb.ID = "Break-" + i.ToString();
        lbb.Text = "<br>";

        ph.Controls.Add(lb);
        ph.Controls.Add(lbl);
        ph.Controls.Add(lbd);

        ph.Controls.Add(grid);
        ph.Controls.Add(lbb);
    }


    private void grid_ItemCreated(object sender, GridItemEventArgs e)
    {

        if (e.Item is GridEditableItem && e.Item.IsInEditMode)
        {
            GridEditableItem editableItem = e.Item as GridEditableItem;
            TableCell cell = editableItem["Duration"];
            if (cell.Controls.Count > 0 && cell.Controls[0] is RadAutoCompleteBox)
            {
                ((RadAutoCompleteBox)(cell.Controls[0])).TextSettings.SelectionMode = RadAutoCompleteSelectionMode.Single;
                ((RadAutoCompleteBox)(cell.Controls[0])).AllowCustomEntry = false;
                ((RadAutoCompleteBox)(cell.Controls[0])).DataSource = GetTableForAuto();
            }
        }

    }
    }

need_griddatasource 的修改代码仅用于测试

void grid_NeedDataSource(object sender, GridNeedDataSourceEventArgs e)
    {
        RadGrid grid = (RadGrid)sender;
        string id = grid.ID;

        for (int i = 0; i < HttpContext.Current.Session.Count; i++)
        {
            var crntSession = HttpContext.Current.Session.Keys[i];
            HttpContext.Current.Response.Write(string.Concat(crntSession, "=", HttpContext.Current.Session[crntSession]) + " Type of session is: " + HttpContext.Current.Session[crntSession].GetType() + "<br />");
        }

        HttpContext.Current.Response.Write("Last line current session is: " + HttpContext.Current.Session[1].GetType() + "<br />");

        if (HttpContext.Current.Session[1] == null)
        {
            HttpContext.Current.Response.Write("Session is null" + "<br />");
        }
        else
        {
            HttpContext.Current.Response.Write("Session is not null" + "<br />");
        }

        //DataTable current = (DataTable)HttpContext.Current.Session[1];
        //HttpContext.Current.Response.Write(current.Rows.Count);
        //DataTable current = (DataTable)HttpContext.Current.Session[int.Parse(id.Split(new string[] { "RadGrid" }, StringSplitOptions.RemoveEmptyEntries)[0])];
        //grid.DataSource = current;
    }

以下是显示的结果:

当来自 CreasteEstimate1.aspx

CustomerInfo=Table1 Type of session is: System.Data.DataTable
Tables=1 Type of session is: System.Int32
1= Type of session is: System.Data.DataTable
Last line current session is: System.Int32
Session is not null

当来自 CreateEstimate2.aspx

Tables=1 Type of session is: System.Int32
1= Type of session is: System.Data.DataTable
Last line current session is: System.Data.DataTable
Session is not null

我不知道有什么区别以及为什么会这样

【问题讨论】:

  • 为什么要使用带有Session 的索引?你为什么不给你的会话变量一个友好的名字:Session["myTable"]?在不知道您如何使用 Session 的情况下,您是否可以删除其中的一个元素,以便您的索引适用于错误的变量?
  • 我知道将它用作数字很奇怪,但原因是我有一堆可以创建的数据表,如果它们是数字的话,我可以更容易地循环它们。我敢肯定有更好的方法来做到这一点,但这就是我能走到现在的原因
  • 听到你将一堆数据表推入Session,这让我有点紧张,你的内存是有限的。如果您需要在没有整数的情况下遍历会话中的对象:for(var i = 0;i &lt; HttpContext.Current.Session.Keys.Count;i++)
  • 当我说一堆时,我的意思是最多 5 个数据表,每个数据表都在自己的会话中

标签: c# asp.net telerik radgrid


【解决方案1】:

您正在访问索引 1 处的会话变量,并假设它是 DataTable 类型。但很可能是 Int32,不能转换为 DataTable。

查看您的会话转储:

当来自 CreasteEstimate1.aspx

Session[0] => CustomerInfo=Table1 Type of session is: System.Data.DataTable
Session[1] => Tables=1 Type of session is: System.Int32
Session[2] => 1= Type of session is: System.Data.DataTable

来自 CreateEstimate2.aspx 时

Session[0] => Tables=1 Type of session is: System.Int32
Session[1] => 1= Type of session is: System.Data.DataTable

如您所见,Session[1] 并不总是包含 System.Data.DataTable。

您可以改为将数据表存储在Session["DataSource"] 中。如果您有多个数据表,请将Dictionary&lt;int, DataTable&gt; 存储在Session["DataSource"] 中,然后通过键访问每个表。我相信您可以找到一个唯一值用作键。

将变量转换为可空类型的更安全的方法是

var myVar=Session["MyVar"] as DataTable;

if(myVar !=null)
{
    //Do something with it
}

其背后的原因是,如果由于某种原因您的 Session["MyVar"] 不是 DataTable 类型,则 myVar 将为空,而不是在强制转换时抛出异常。

【讨论】:

  • 我 100% 同意你的观点,我将继续使用我非常喜欢的字典理念。谢谢!!!但是当我直接访问它时,我仍然不明白相同的代码是如何工作的,但是当我使用 server.transfer 或 response.redirect 到同一页面时,我得到了那个错误
  • 您可以检查您的请求并查看会话中存储的内容,尤其是索引 1 中存储的内容。最有可能的是,直接来自和通过服务器传输的请求不同。会话可能会增加额外的价值,并且您的预期数据集不再位于索引 1
  • 如何检查?为什么会有所不同?
  • 快速 Google 搜索返回此:msdn.microsoft.com/en-us/library/… 您可以增强代码以列出变量类型。至于为什么,不看代码无法回答。
  • 我仍然找不到发生这种情况的任何原因,这让我发疯了,为什么会发生这种情况真是太奇怪了
猜你喜欢
  • 2016-12-01
  • 1970-01-01
  • 2016-09-01
  • 2012-07-11
  • 2018-04-08
  • 2017-04-20
  • 2018-10-02
  • 2016-09-04
  • 2010-10-06
相关资源
最近更新 更多