0

我有 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’类型。”

创建Estimate2.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);
    }
}

发票人.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

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

4

1 回答 1

3

您正在访问索引 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<int, DataTable>Session["DataSource"]通过键访问每个表。我相信您可以找到一个唯一值用作键。

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

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

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

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

于 2013-10-22T20:47:09.347 回答