我有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'。”
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);
}
}
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();
}
}
}
}
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;
}
以下是显示的结果:
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
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
我不知道这是什么区别以及为什么会这样发生
答案 0 :(得分: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将为null,而不是在强制转换时抛出异常。