When does a page get rendered in ASP.NET? - asp.net

I'm writing am ASP.NET/C# project, it's a simple blog page with commnents.
Problem I'm having when button click you see comments load original blogload plus blogs and comments, trying to get it to load blog/comment selected only.
If I try not to load blog in page_load or have it only do if not postback nothing is displayed. Any help would be appreciated.
PS I know there are many blog engines out there but have specific reason.
protected void Page_Init(object sender, EventArgs e)
{
//ParseControls(GlobalVar.pathxsltver);
// BindInfo();
}
private void ParseControls(string myxslt)
{
//load the data
FileStream fs = new FileStream(Server.MapPath ( GlobalVar.compathver), FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
DataSet dset = new DataSet();
dset.ReadXml(fs);
fs.Close();
XPathDocument xdoc = new XPathDocument(Server.MapPath(GlobalVar.pathver ));
XmlDocument mydoc = new XmlDocument();
XPathNavigator navigator = xdoc.CreateNavigator();
XPathExpression expression = navigator.Compile("BlogItems/Blog");
expression.AddSort("ID", XmlSortOrder.Descending, XmlCaseOrder.UpperFirst, string.Empty, XmlDataType.Text);
XPathNodeIterator iterator = navigator.Select(expression);
int TheCnt = 0;
int cnt = GlobalVar.BlogCntDisplay;
string st = "<BlogItems>";
foreach (XPathNavigator item in iterator)
{
TheCnt++;
string sid = item.SelectSingleNode("ID").Value;
st = st + "<Blog id=\"" + sid + "\">" + item.InnerXml;
st = st + "<ComCnt>" + MyFunc.CountComments (sid,dset) + "</ComCnt></Blog>";
if (TheCnt == cnt) { break; }
}
st = st + "</BlogItems>";
mydoc.LoadXml(st);
XslCompiledTransform transform = new XslCompiledTransform();
XsltSettings settings = new XsltSettings(true,true);
transform.Load(Server.MapPath(myxslt),settings,null);
StringWriter sw = new StringWriter();
transform.Transform(mydoc, null, sw);
string result = sw.ToString();
//remove namespace
result = result.Replace("xmlns:asp=\"remove\"", "");
//parse control
Control ctrl = Page.ParseControl(result);
//find control to add event handler
//Boolean test = phBlog.FindControl("btnComment2").i;
phBlog.Controls.Add(ctrl);
XmlNodeList nList = mydoc.SelectNodes("//BlogItems/Blog/ID");
foreach (XmlNode objNode in nList)
{
Button btnComment = (Button) phBlog.FindControl("btnComment"+objNode.InnerText );
btnComment.CommandArgument = objNode.InnerText ;
btnComment.BorderWidth = 0 ;
btnComment.Command += new CommandEventHandler(Button1_Click);
}
}
protected void Page_Load(object sender, EventArgs e)
{
//if (!Page.IsPostBack )
//{ParseControls(GlobalVar.pathxsltver);}
ParseControls(GlobalVar.pathxsltver);
}
protected void Button1_Click(object sender, CommandEventArgs e)
{
Label1.Text = "Comm hit : " + e.CommandArgument.ToString();
ParseControls(GlobalVar.blogcommentsver );
}

You're question is kind of vague, but if I understand you correctly, you're wondering why the entire page refreshes when you just want to handle the button click?
Whenever you do any kind of postback, and that includes handling any events, the entire page is re-rendered. More than that, you're working with a brand new instance of your page class. The old one is dead and gone. That's just the way the web normally works.
If you only want to reload a part of the page, you need to use ajax. In ASP.Net land, that means placing your comments section inside an UpdatePanel control that can be refreshed.

Related

Unable to serialize the session state

i am tired wondering the issue for this problem. have read so many blogs and forums for this but i am not able to find out the problem.
I am using "SQLServer" mode to store session.
Everything is working fine. But whenever i use search function in my website, it throws the below error:
"Unable to serialize the session state. In 'StateServer' and 'SQLServer' mode, ASP.NET will serialize the session state objects, and as a result non-serializable objects or MarshalByRef objects are not permitted. The same restriction applies if similar serialization is done by the custom session state store in 'Custom' mode."
I am assuming that this is because of the paging code i have used on that page. That code is as below:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
string query = "select xxxxqueryxxxx";
SqlDataAdapter da = new SqlDataAdapter(query, con);
DataSet ds = new DataSet();
try
{
using (con)
{
con.Open();
da.Fill(ds);
}
}
catch
{
ds = null;
}
finally
{
if (ds != null)
{
CustomPaging page = new CustomPaging();
DataTable dt = ds.Tables[0];
page.PageSize = 10;
page.DataSource = dt;
page.CurrentPageIndex = 0;
no = 1;
Session["DT"] = dt;
Session["page"] = page;
bindData(page, dt);
//set these properties for multi columns in datalist
DataList2.RepeatColumns = 1;
DataList2.RepeatDirection = RepeatDirection.Horizontal;
}
}
}
}
void bindData(CustomPaging page, DataTable dt)
{
try
{
DataList2.DataSource = page.DoPaging;
DataList2.DataBind();
//DataList2.DataSource = SqlDataSource1;
//DataList2.DataBind();
lbtnPre.Enabled = !page.IsFirstPage; //Enable / Disable Navigation Button
// lbtnPre.CssClass = "disabledbtn";
lbtnNext.Enabled = !page.IsLastPage;
//lbtnNext.CssClass = "disabledbtn";
lblStatus.Text = NavigationIndicator(); //Build Navigation Indicator
//for creating page index
DataTable dt1 = new DataTable();
dt1.Columns.Add("PageIndex");
dt1.Columns.Add("PageText");
for (int i = 0; i < page.PageCount; i++)
{
DataRow dr = dt1.NewRow();
dr[0] = i;
dr[1] = i + 1;
dt1.Rows.Add(dr);
}
dlPaging.DataSource = dt1;
dlPaging.DataBind();
dlPaging.RepeatColumns = 10;
dlPaging.RepeatDirection = RepeatDirection.Horizontal;
}
catch (Exception)
{
}
finally
{
page = null;
}
}
string NavigationIndicator()
{
string str = string.Empty; //Page x Of Y
str = Convert.ToString(((CustomPaging)Session["page"]).CurrentPageIndex + 1) + " of " + ((CustomPaging)Session["PAGE"]).PageCount.ToString() + " Page(s) found";
return str;
}
protected void lbtnPre_Click(object sender, EventArgs e)
{
int pageIndex = ((CustomPaging)Session["page"]).CurrentPageIndex;
if (!((CustomPaging)Session["page"]).IsFirstPage)
//Decrements the pageIndex by 1 (Move to Previous page)
((CustomPaging)Session["page"]).CurrentPageIndex -= 1;
else
((CustomPaging)Session["page"]).CurrentPageIndex = pageIndex;
//Binds the DataList with new pageIndex
bindData(((CustomPaging)Session["page"]), ((DataTable)Session["DT"]));
}
protected void lbtnNext_Click(object sender, EventArgs e)
{
int pageIndex = ((CustomPaging)Session["page"]).CurrentPageIndex;
if (!((CustomPaging)Session["page"]).IsLastPage)
//Increments the pageIndex by 1 (Move to Next page)
((CustomPaging)Session["page"]).CurrentPageIndex += 1;
else
((CustomPaging)Session["page"]).CurrentPageIndex = pageIndex;
//Binds the DataList with new pageIndex
bindData(((CustomPaging)Session["page"]), ((DataTable)Session["DT"]));
}
protected void DataList2_SelectedIndexChanged(object sender, EventArgs e)
{
Response.Redirect("Default2.aspx?partnumber=" + DataList2.DataKeyField[DataList2.SelectedIndex].ToString());
}
protected void dlPaging_ItemCommand(object source, DataListCommandEventArgs e)
{
if (e.CommandName == "Select")
{
no = int.Parse(e.CommandArgument.ToString()) + 1;
((CustomPaging)Session["page"]).CurrentPageIndex = int.Parse(e.CommandArgument.ToString());
//Binds the DataList with new pageIndex
bindData(((CustomPaging)Session["page"]), ((DataTable)Session["DT"]));
}
}
protected void dlPaging_ItemDataBound(object sender, DataListItemEventArgs e)
{
LinkButton btn = (LinkButton)e.Item.FindControl("lnkbtnPaging");
if (btn.Text == no.ToString())
{
btn.ForeColor = System.Drawing.Color.Maroon;
btn.Font.Underline = false;
}
else
{
btn.ForeColor = System.Drawing.Color.DarkCyan;
btn.Font.Underline = false;
}
}
I just want to know what the problem is in the coding and "how to serialize the session"?
What shold i do to improve the coding?
Any help will be appreciated.
Thank You
I guess your custom paging control is not serializable. This must be the cause of the issue.
Anyway, storing a control in session is not a good idea. Just store the few serializable properties which enable to rebuild the control (PageSize and CurrentPageIndex), or pass them in query string for example.
You could also use ViewState if you can
About storing the DataTable in Session, this might be a really bad idea if you have a lot of data and many connected users.

Create Dynamic Textbox and Get values

I want to create dynamic text box when user click on Add more link button.
For this I am using this code. And I have to mention that I am using master page.
protected void lnkAddMore_Click(object sender, EventArgs e)
{
if (Request.Cookies["value"] != null)
{
i = Convert.ToInt32(Request.Cookies["value"].Value) + 1 ;
}
for (int k = 1; k <= i; k++)
{
LiteralControl literal = new LiteralControl();
literal.Text = "<br /><br />";
Label newLabel = new Label();
newLabel.Text = "Choice" + " " + k.ToString();
newLabel.ID = "lblChoice_" + k.ToString();
newLabel.Attributes.Add("runat", "Server");
this.panelLabel.Controls.Add(newLabel);
this.panelLabel.Controls.Add(literal);
LiteralControl literal1 = new LiteralControl();
literal1.Text = "<br /><br />";
TextBox nexText = new TextBox();
nexText.ID = "txtChoice_" + k.ToString();
nexText.Attributes.Add("TextMode", "MultiLine");
nexText.Attributes.Add("runat", "Server");
panelTextbox.Controls.Add(nexText);
this.panelTextbox.Controls.Add(literal1);
Response.Cookies["value"].Value = i.ToString();
Session["Panel"] = panelTextbox;
}
}
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
if (Session["Panel"] != null)
{
ContentPlaceHolder content=new ContentPlaceHolder();
content.Controls.Add(Session["Panel"] as Panel);
}
}
}
Now I am facing trouble how to retrieve the data of the these text boxes after the clicking on the submit button so that I can store the values of there text boxes to database.
What will be code written for the click event of btnSave
protected void btnSave_Click(object sender, EventArgs e)
{
if (Session["Panel"] != null)
{
ContentPlaceHolder content_new = new ContentPlaceHolder();
for (int i = 1; i <= count; i++)
{
strControlName = "txtChoice_" + i.ToString();
TextBox objTextBox = (TextBox)content_new.FindControl(strControlName);
strTextBoxValues[i] = objTextBox.Text;
string str3 = strTextBoxValues[2];
}
}
}
This code is showing error for objTextBox. The error is NullReferenceException.
How to write stored procedure for saving data of above code?
The main problem is handling the parameter declaration, how to declare dynamic parameter for passing values so that value is saved for dynamic textbox?
Thanks.
I have already answered it here.
Lost dynamically created text box values
You can try this.
private string GetValue(string ControlID)
{
string[] keys = Request.Form.AllKeys;
string value = string.Empty;
foreach (string key in keys)
{
if (key.IndexOf(ControlID) >= 0)
{
value = Request.Form[key].ToString();
break;
}
}
return value;
}
Then to get the value
string txtChoice1value = GetValue("txtChoice1");
First of all when you dynamically create a control it doesn't need to be set "runat = sever".
Problem is in this line `ContentPlaceHolder content_new = new ContentPlaceHolder();` you make a new ContentPlaceHolder, this mean it doesn't have any control to be found.
Check this page. How To Create TextBox Control Dynamically at Runtime
You need to find the reference of your already created ContentPlaceHolder like-
ContentPlaceHolder cnt =(ContentPlaceHolder)this.Master.FindControl("ContentPlaceHolder1");
and then add the dynamically created Control in that ContentPlaceHolder as-
cnt.Controls.Add(Session["Panel"] as Panel);
Why you creating a new ContentPlaceHolder each time even when you have mentioned that you are using masterPage, so there must exists a ContentPlaceHolder..
Controls wont persist on postback have a look at http://www.denisbauer.com/ASPNETControls/DynamicControlsPlaceholder.aspx

CRUD Operations with DetailsView and EntityDataSource in Custom Server Control

I am not a big fan of ASPX pages, drag-and-drop and so on. I'm building a portal with a single Default.aspx and every other thing is custom web part controls or server controls that other developers can build in compiled dll and users can upload to the portal themselves to add features to the portal. I've been battling with DetailsView crud operations with entitydatasource. I did a test.aspx page with drag and drop and everything worked fine but with 100% code behind, nothing is. No error is displayed but data are not being persisted to database. I tried catching the onUpdating event of the detailsview and yes the event was fired and I could enumerate the data submitted but why is it not persisted to database? Hope someone can help with this.
Here's my code (trying to create everything from codebehind and add them to placeholders on the page just for testing purpose before I move everything to web part):
public partial class Test : System.Web.UI.Page
{
private EntityDataSource eds = new EntityDataSource();
public DetailsView dtlview = new DetailsView();
protected void Page_Load(object sender, EventArgs e)
{
//Initialize Datasource
eds.ConnectionString = "name=DBEntities";
eds.DefaultContainerName = "DBEntities";
eds.EnableDelete = true;
eds.EnableFlattening = false;
eds.EnableInsert = true;
eds.EnableUpdate = true;
eds.EntitySetName = "EmailAccounts";
Controls.Add(eds);//I don't know if this is necessary
//Create DetailsView and configure for inserting on default
dtlview.DataSource = eds;
dtlview.AutoGenerateInsertButton = true;
dtlview.AutoGenerateDeleteButton = true;
dtlview.AutoGenerateEditButton = true;
dtlview.AutoGenerateRows = false;
dtlview.DefaultMode = DetailsViewMode.Insert;
dtlview.AllowPaging = true;
dtlview.DataKeyNames = new string[] { "ID" };
dtlview.AllowPaging = true;
//Create fields since autogeneraterows is false
BoundField bfID = new BoundField();
bfID.DataField = "ID";
bfID.HeaderText = "ID:";
BoundField bfUserID = new BoundField();
bfUserID.DataField = "UserID";
bfUserID.HeaderText = "User ID:";
BoundField bfDisplayName = new BoundField();
bfDisplayName.DataField = "DisplayName";
bfDisplayName.HeaderText = "Display Name:";
BoundField bfEmailAddress = new BoundField();
bfEmailAddress.DataField = "EmailAddress";
bfEmailAddress.HeaderText = "Email:";
BoundField bfPassword = new BoundField();
bfPassword.DataField = "Password";
bfPassword.HeaderText = "Password:";
BoundField bfOutgoingServer = new BoundField();
bfOutgoingServer.DataField = "OutgoingServer";
bfOutgoingServer.HeaderText = "Outgoing server:";
BoundField bfIncomingServer = new BoundField();
bfIncomingServer.DataField = "IncomingServer";
bfIncomingServer.HeaderText = "Incoming Server:";
CheckBoxField chkfIsDefault = new CheckBoxField();
chkfIsDefault.DataField = "IsDefault";
chkfIsDefault.HeaderText = "Is Default?";
dtlview.Fields.Add(bfID);
dtlview.Fields.Add(bfUserID);
dtlview.Fields.Add(bfDisplayName);
dtlview.Fields.Add(bfEmailAddress);
dtlview.Fields.Add(bfPassword);
dtlview.Fields.Add(bfOutgoingServer);
dtlview.Fields.Add(bfIncomingServer);
dtlview.Fields.Add(chkfIsDefault);
dtlview.DataBind();
//Events handling for detailsview
dtlview.ItemInserting += dtlview_ItemInserting;
dtlview.ItemInserted += dtlview_ItemInserted;
dtlview.ModeChanging += dtlview_ModeChanging;
//Add controls to place holder
PlaceHolder2.Controls.Add(dtlview);
}
protected void dtlview_ItemInserting(object sender, DetailsViewInsertEventArgs e)
{
e.Values["UserID"] = GetCurrentUserID();
}
protected void dtlview_ItemInserted(object sender, DetailsViewInsertedEventArgs e)
{
}
protected void dtlview_ModeChanging(object sender, DetailsViewModeEventArgs e)
{
dtlview.ChangeMode(e.NewMode);
if (e.NewMode != DetailsViewMode.Insert)
{
dtlview.DataSource = eds;
dtlview.DataBind();
}
}
}
I think what you have to do is add :
OnContextCreating="XXXXDatasource_OnContextCreating"
OnContextDisposing="XXXXDatasource_OnContextDisposing"
To your EntityDataSource.
Then in you code :
protected void XXXXDatasource_OnContextCreating(object sender, EntityDataSourceContextCreatingEventArgs e)
{
e.Context = DBEntities.Entities;
}
protected void XXXXDatasource_OnContextDisposing(object sender, EntityDataSourceContextDisposingEventArgs e)
{
e.Cancel = true;
}
That way, your ObjectContext is correctly set to the EntityDataSource used by your DetailsView.
At least that's what I read as best practice (also look up one object context per page request)

how to retain the value of global string variable even after page load in asp.net

I am having problems in retaining the string variable which I defined on the top of my scoop, everytime when page loads the string value becomes null. below is the snippet of the code:
public partial class Caravan_For_Sale : System.Web.UI.Page
{
string check;
PagedDataSource pds = new PagedDataSource(); //paging
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
BindGrid();
}
}
private void BindGrid()
{
DataTable dt = null;
switch (check)
{
case "0-1500":
break;
case "1500-2000":
dt = caravans.GetFilterbyPrice1();
break;
case "2000+":
break;
default:
dt = caravans.GetAllCaravans();
break;
}
// DataTable dt = caravans.GetAllCaravans();
pds.DataSource = dt.DefaultView;
pds.AllowPaging = true;
pds.PageSize = 3;//add the page index when item exceeds 12 //Convert.ToInt16(ddlPageSize.SelectedValue);
pds.CurrentPageIndex = CurrentPage;
DataList1.RepeatColumns = 3; // 4 items per line
DataList1.RepeatDirection = RepeatDirection.Horizontal;
DataList1.DataSource = pds;
DataList1.DataBind();
lnkbtnNext.Enabled = !pds.IsLastPage;
lnkbtnPrevious.Enabled = !pds.IsFirstPage;
doPaging();
}
protected void lnkPrice2_Click(object sender, EventArgs e)
{
LinkButton _sender = (LinkButton)sender;
check = _sender.CommandArgument;
// items["test"] = test;
DataTable dt = caravans.GetFilterbyPrice2();
if (dt.Rows.Count < 3)
{
lnkbtnNext.Enabled = false;
lnkbtnPrevious.Enabled = false;
}
CurrentPage = 0;
BindGrid();
}
protected void dlPaging_ItemCommand(object source, DataListCommandEventArgs e)
{
if (e.CommandName.Equals("lnkbtnPaging"))
{
CurrentPage = Convert.ToInt16(e.CommandArgument.ToString());
BindGrid();
}
}
The string check becomes null everytime when the dlPaging_ItemCommand becomes active(page loads). Any help or suggestions will be appreciated
As far as I know, you have two options:
1) Load it again.
Not sure if it's possible in your case. This is usually done when dealing with database queries.
2) Put it in the ViewState just like this:
ViewState["check"] = check;
And load it after with this:
string check = Convert.ToString(ViewState["check"]);
Your class is instantiated on every load so it will not have a global variable from page view to page view. You will need to store it somehow. Like in the querystring or a session. You can also use the viewstate.
For example
ViewState("Variable") = "Your string"
Viewstate is the way to go, as the other people have answered. Whatever you do, please don't stuff it in the session.

Fire server event from client

I am having trouble with the Asp.net page life cycle. I am trying to create a custom menu using HtmlTextWriter with an asp.net LinkButton to fire a server event. I can not get the server event to fire and I get the 'object reference not set to instance of object' when I click my linkbutton. Here is some code.
protected string CreateModuleMenu()
{
var modules = ModuleManager.GetModulesByDeveloperId(Developer.DeveloperID);
StringWriter sw = new StringWriter();
ClientScriptManager cs = Page.ClientScript;
using (HtmlTextWriter writer = new HtmlTextWriter(sw))
{
foreach (var module in modules)
{
writer.RenderBeginTag(HtmlTextWriterTag.Li);
writer.RenderBeginTag(HtmlTextWriterTag.Dl);
writer.RenderBeginTag(HtmlTextWriterTag.Dt);
writer.Write(module.Name);
var files = ModuleManager.GetModuleFilesByModuleId(module.ModuleID);
foreach (var file in files)
{
writer.RenderBeginTag(HtmlTextWriterTag.Dd);
LinkButton lb = new LinkButton();
lb.ID = "mc" + file.ModuleFileID;
lb.Attributes.Add("onclick", cs.GetPostBackEventReference(lb, "LoadControl_Clk"));
lb.Text = file.Name;
Page.RegisterRequiresRaiseEvent(lb);
lb.RenderControl(writer);
writer.RenderEndTag();
}
writer.RenderEndTag();
writer.RenderEndTag();
writer.RenderEndTag();
}
}
return sw.ToString();
Here is my click event:
protected void LoadControl_Clk(object sender, EventArgs e)
{
Response.Write("Hello World");
}
Finally here is what I have in the Page_Load event. Note: I tried moving this around to PreRender, PreInt, etc.
protected void Page_Load(object sender, EventArgs e)
{
LiteralControl lit = new LiteralControl();
lit.Text = CreateModuleMenu();
phModuleMenu.Controls.Add(lit);
if (DefaultModuleFile == null)
Response.Write("Error.");
else
{
Control ctrl = LoadControl(DefaultModuleFile.Src);
phAdminModules.Controls.Add(ctrl);
}
}
Lost. Thanks.
Perhaps you need to only load the control in Page_Load on the first time the page is called, that is, if !IsPostBack.
If you load the control on every page load, you will lose the event being fired.

Resources