Why ViewState and Control Values lost on partial Postback using AJAXFileUpload? - asp.net

I have a .aspx page containing button which opens the popup on button click.
The popup window have AJAXFileUpload control. When button is clicked to open the popup, session values are sent to popup and on page load these session values are assigned to ViewState and HiddenField, DataTable.
Problem:
When i click on Upload button in popup containing AjaxFileUploadit saves the images to the table in AJAXUploadComplete event. In this event i am not able to access the ViewState,HiddenField and DataTable Values dont know why?
Popup.aspx.cs
DataTable dt=new DataTable();
protected void Page_Load(object sender, EventArgs e)
{
int noOfImages;
string[] imagePaths;
if (dt != null && dt.Rows.Count==0)
{
dt.Columns.Add("QuoteID");
dt.Columns.Add("PrepID");
dt.Columns.Add("IsPrep");
dt.Rows.Add(string.Empty, string.Empty, string.Empty);
}
if ((!IsPostBack ))
{
if (Session["IsPrep"] != null || ViewState["IsPrep"]!= null)
{
int Isprep = Convert.ToInt32(Session["IsPrep"].ToString());
if (Session["IsPrep"] != null)
{
ViewState["IsPrep"] = Session["IsPrep"];
ViewState["QuoteID"] = Convert.ToString(Session["QuoteIDForListing"]);
int intQuoteID = Convert.ToInt32(ViewState["QuoteID"]);
hdnQuoteID.Value = intQuoteID.ToString();
ViewState["PrepID"] = Convert.ToString(Session["PrepIDForListing"]);
if (dt != null && dt.Rows.Count > 0)
{
dt.Rows[0]["QuoteID"] = Convert.ToString(Session["QuoteIDForListing"]);
dt.Rows[0]["PrepID"] = Convert.ToString(Session["PrepIDForListing"]);
dt.Rows[0]["IsPrep"] = Convert.ToString(Session["IsPrep"]);
}
Session["IsPrep"] = null;
Session["QuoteIDForListing"] = null;
Session["PrepIDForListing"] = null;
}
}
}
}
protected void AjaxFileUpload1_UploadComplete1(object sender, AjaxControlToolkit.AjaxFileUploadEventArgs e)
{
//here: ViewState,HiddenField,DataTable values are all get cleared dont know why?
if (dt != null && dt.Rows.Count > 0)
{
//here dt is set to null any idea?
}
//if (!string.IsNullOrEmpty(Convert.ToString(ViewState["QuoteID"])))
if (!string.IsNullOrEmpty(Convert.ToString(hdnQuoteID.Value))&& hdnIsPrepId.Value=="0")
{
int QuoteID = Convert.ToInt32(ViewState["QuoteID"]);
///some code here
}
// else if (!string.IsNullOrEmpty(Convert.ToString(ViewState["PrepID"])))
else if (!string.IsNullOrEmpty(Convert.ToString(hdnPrepID.Value)) && hdnIsPrepId.Value == "1")
{
int PrepID = Convert.ToInt32(ViewState["PrepID"]);
///some code here
}
}
NOTE: Same functionality works fine on a page. But, used with the popup it flushed all the values of HiddenField,DataTable,ViewState.
Session cant be used to store data after popup opened because multiple instance of windows may be opened at a time.
Also, when query string is used with Popup to send values the AjaxFileUpload gives error as it appends its own querystring contextkey and guid.
Please suggest any solution/change?

Related

Selected a row in a grid view, now want to update that record with update button click

I have been stuck on this and tried a few different things to use the update button to update the record that I selected from the grid view. I have 2 columns in the table Id and Name. I select the record and it populates a text box with the name.... this works fine. I just need to take that same record and update the name from that same text box after it is pulled into the text box by using an update button click event. I have two other buttons that work just fine which are "Add" and "Delete" and I will add that code as well but here is the code:
This is how I have populated the grid view on page load or when I call the method:
private void PopulateCompanyListGrid() //This will populate the grid with the table data on page load
{
IList<Company> companies;
using (var context = new IMSDBContext())
{
companies = context.Companies.ToList();
}
grdvwCompanyList.DataSource = companies;
grdvwCompanyList.DataBind();
}
This is how the grid view is set up:
<asp:GridView runat="server" ID="grdvwCompanyList" OnSelectedIndexChanged="SelectGridRow" DataKeyNames="Id, Name" AllowSorting="True" AutoGenerateSelectButton="True"></asp:GridView>
This is how I put the selected record in the text box:
public void SelectGridRow(object sender, EventArgs e) //This will populate the textbo with the row selected from the gridview
{
GridViewRow name = grdvwCompanyList.SelectedRow;
if (name != null)
{
var dataKey = grdvwCompanyList.DataKeys[name.RowIndex];
if (dataKey != null)
txtCompanyName.Text = (string)dataKey["Name"];
}
}
This is how I am adding records:
protected void btnAdd_Click(object sender, EventArgs e) // This method adds a record to the database
{
if (btnAdd.Text == "Add") // Clears the textbox and notification label and calls method to change name of button if the button says "Add"
{
txtCompanyName.Text = "";
lblCompanyNameNotification.Text = "";
ButtonChangeAddToSave();
}
else if (btnAdd.Text == "Save") // Checks if the button says "Save" and compares textbox and database for a matching record
{
IMSDBContext context = new IMSDBContext();
Company CompanyCheck = context.Companies.SingleOrDefault(Company => Company.Name == txtCompanyName.Text);
if (CompanyCheck != null) // Displays a notification if there is already a matching record
{
lblCompanyNameNotification.Text = "There is already a Company with that name.";
}
else if(txtCompanyName.Text == null)
{
lblCompanyNameNotification.Text = "Please enter a name of a company";
}
else if (txtCompanyName.Text != null) // Write the record to the database if no matching record in the database
{
Company n = new Company();
n.Name = txtCompanyName.Text.ToString();
context.Companies.Add(n);
context.SaveChanges();
txtCompanyName.Text = "";
lblCompanyNameNotification.Text = "";
ButtonChangeSaveToAdd();
}
}
PopulateCompanyListGrid(); // Calls method to repopulate the gridview
}
Add a hidden field in the markup to hold company Id:
<asp:HiddenField ID="hdnCompanyId" runat="server" ></asp:HiddenField>
In the selectGridRow method populate the hidden field with company Id:
public void SelectGridRow(object sender, EventArgs e) //This will populate the textbo with the row selected from the gridview
{
GridViewRow name = grdvwCompanyList.SelectedRow;
if (name != null)
{
var dataKeys = grdvwCompanyList.DataKeys[name.RowIndex];
if (dataKeys["Name"] != null)
txtCompanyName.Text = (string)dataKeys["Name"];
if (dataKeys["Id"] != null)
hdnCompanyId.Value = dataKeys["Id"].ToString();
}
}
In the btnUpdate_Click method get the company by Id and update it :
protected void btnUpdate_Click(object sender, EventArgs e)
{
int companyId;
string companyName = txtCompanyName.Text;
if(int.TryParse(hdnCompanyId.Value, out companyId)){
IMSDBContext context = new IMSDBContext();
Company company = context.Companies.SingleOrDefault(Company => Company.Id == companyId);
if (company != null && txtCompanyName.Text != "")
{
company.Name = companyName;
context.SaveChanges();
}
else
{
lblCompanyNameNotification.Text = "The Company does not exist.";
}
}
PopulateCompanyListGrid(); // Calls method to repopulate the gridview
}

Unable to load Controls from Empty Data Template in GridView asp.net

I have a GridView which is binded with DataTable for the datasource, when there is no records in the underlying datasource i show up the EmptyDataTemplate with Two DropDown (State and City) and based on the State i fills up City.
Now my problem is till i have some records inside the Datasource it works fine, but as soon as i delete the last remaining record from the datasource, it throws error, it switches to the emptydatatemplate but it could not find the States Dropdownlist (based on which i am filling city dropdown). But once i refresh the page it works fine.
I don't understand which event to grab to place the codes
Here's what i am doing
Below function gets the stateid and fills the cities based on it
private void FillCitiesByStateId()
{
drpCity = grdLocationView.Controls[0].Controls[0].FindControl("drpCitiesAdd") as DropDownList;
drpState = grdLocationView.Controls[0].Controls[0].FindControl("drpStatesAdd") as DropDownList; // Fetches the States DropDown from EmptyDataTemplate.
if (drpState != null)
{
objCity.StateId = Convert.ToInt32(drpState.SelectedValue); //It always throws error on this line.
drpCity.DataSource = objCity.GetCitiesByStateId();
drpCity.DataTextField = "Name";
drpCity.DataValueField = "Id";
drpCity.DataBind();
}
}
Below is the code i which is used to bind the records in dropdowns
protected void grdLocationView_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (dt.Rows.Count == 0)
{
FillCitiesByStateId();
}
else
{
if (e.Row.RowType == DataControlRowType.Header)
{
drpCity = e.Row.FindControl("drpCities") as DropDownList;
drpState = e.Row.FindControl("drpStates") as DropDownList;
objCity.StateId = Convert.ToInt32(drpState.SelectedValue);
drpCity.DataSource = objCity.GetCitiesByStateId();
drpCity.DataTextField = "Name";
drpCity.DataValueField = "Id";
drpCity.DataBind();
}
}
}
Can anyone provide any suggestion whats going wrong with it
Make sure you are only calling the FillCitiesByStateId() for appropriate row types. Maybe you're calling it for a footer row?
DataControlRowType Enumeration
instead of:
if (dt.Rows.Count == 0)
{
FillCitiesByStateId();
}
try:
if (e.Row.RowType == DataControlRowType.EmptyDataRow)
{
FillCitiesByStateId();
}

How to reference a user control in its own code behind?

Let's say I have a user control with a couple of buttons. I'd like to know which one caused the postback, using this method:
public static Control GetPostBackControl(Page page)
{
Control control = null;
string ctrlname = page.Request.Params.Get("__EVENTTARGET");
if (ctrlname != null && ctrlname != string.Empty)
{
control = page.FindControl(ctrlname);
}
else
{
foreach (string ctl in page.Request.Form)
{
Control c = page.FindControl(ctl);
if (c is System.Web.UI.WebControls.Button)
{
control = c;
break;
}
}
}
return control;
}
And this is how I am calling it:
string btn = GetPostBackControl(this.Page).ID;
I'm getting the "Object reference not set to an instance of an object." I know now that the problem comes from the fact that I'm using this.Page, which represents the parent page.
How to reference the user control that I'm in? (not the parent page) So that it can work with the method to find the button that caused the postback?
Thanks for helping.
EDIT
Both buttons are located inside the user control. GetPostBackControl() is also in the code-behind of the user control.
I did a quick example on your given code and it worked out pretty fine. Perhaps you did miss checking for Page.IsPostBack? Obviously there will only be a postBackControl if there is a postBack...
#Buttons - they will be rendered as <input type="submit"> so they won't appear within ___EVENTTARGET. That's why Ryan Farlay wrote in his blog
However, you can still get to it, just in a different way. Since the
button (or input) is what causes the form to submit, it is added to
the items in the Form collection, along with all the other values from
the submitted form. [...] If you were to
look in the Form collection for anything that is a button then that
will be what caused the postback (assuming that it was a button that
caused the page to submit). If you first check the __EVENTTARGET, then
if that is blank look for a button in the Form collection then you
will find what caused the postback
protected void Page_Load(object sender, EventArgs e)
{
if (Page.IsPostBack)
{
Control postBackControl = GetPostBackControl(this.Page);
Debug.WriteLine("PostBackControl is: " + postBackControl.ID);
}
}
public static Control GetPostBackControl(Page page)
{
Control control = null;
string ctrlname = page.Request.Params.Get("__EVENTTARGET");
if (ctrlname != null && ctrlname != string.Empty)
{
control = page.FindControl(ctrlname);
}
else
{
foreach (string ctl in page.Request.Form)
{
Control c = page.FindControl(ctl);
if (c is System.Web.UI.WebControls.Button)
{
control = c;
break;
}
}
}
return control;
}

Trying to Call an Update method in Button Click event

I am looping 2 Datagrids and getting the IndividualID's (PrimaryKeys) of the person(s) that are selected. I have debugged this and the loops are working fine. Howver when I call my Update Method from my Table Adapter, nothing seems to happen. It does not update. Here is my code. Not sure what I'm doing wrong:
protected void imgbtnReassgin_Click(object sender, ImageClickEventArgs e)
{
foreach (GridViewRow row in gvAdminCustomer.Rows)
{
CheckBox cb = (CheckBox)row.FindControl("chkitemSelectorCustomers");
if (cb != null && cb.Checked)
{
int oIndividualID = Convert.ToInt32((gvAdminCustomer.DataKeys[row.RowIndex].Value));
// GlobalVar.oIndividualID = oIndividualID;
foreach (GridViewRow r in gvReassignCustomers.Rows)
{
CheckBox chkBox = (CheckBox)row.FindControl("chkitemSelectorAllManagersandSalesman");
if (chkBox != null && chkBox.Checked)
{
int oNewParentID = Convert.ToInt32((gvReassignCustomers.DataKeys[r.RowIndex].Value));
individualTableAdapter ind = new individualTableAdapter();
//Individual ind = new Individual();
ind.reassign_Individual(oIndividualID, oNewParentID);
}
}
gvAdminCustomer.DataBind();
}
}
}
Is it updating the database record and not reflecting on the grid? If that is the case, then it looks like it is just rebinding the grid with the datasource it used prior to the loop. You'll need to refresh your dataset and then rebind:
gvAdminCustomer.DataSource = YourDataSource;
gvAdminCustomer.DataBind();
Good Luck!

Passing Value from textboxes in one webform to texboxes in another webform

am trying to get users to enter some details into a textbox in form1 and get the entry validated against the database. if the entry is correct, form2 loads with other texboxes including the one they made entries into. however i dont want them to make any changes to the textboxes they entered values into previously neither should they have to re-enter the values again.
how do i get the values in the textboxes to move from form1 to form2?
the code below shows what ive done with both forms but the second form dosent display the items in the textboxes when the form is loaded.
first form
protected void Button1_Click(object sender, EventArgs e)
{
string strConn;
strConn = "Provider=MIcrosoft.Jet.OLEDB.4.0;data Source=" +
Server.MapPath("App_Data/test.mdb");
OleDbConnection mDB = new OleDbConnection(strConn);
mDB.Open();
prodSnStr = pSnTextBox.Text;
purDate = Convert.ToDateTime(purDateTextBox.Text);
string dateStr = purDateTextBox.Text;
productClass aProduct = new productClass();
if (aProduct.Prods(mDB, prodSnStr, purDate))
{
Session["ProdSn"] = pSnTextBox.Text;
Session["PurDate"] = purDateTextBox.Text.ToString();
Response.Redirect("Warranty.aspx");
}
else
{
//error message
}
}
form two
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
if (Request.QueryString["ProdSn"] != "")
{
pSNoTextBox.Text = Request.QueryString["ProdSn"];
if (Request.QueryString["PurDate"] != "")
{
dateTextBox.Text = Request.QueryString["PurDate"];
}
else
{
//error message to display
}
}
else
{
//error message to display
}
}
eagaerly waiting for your responses..thanks..
In your code you are putting the values on one page into the session:
Session["ProdSn"] = pSnTextBox.Text;
Session["PurDate"] = purDateTextBox.Text.ToString();
However you are trying to read them out on the 2nd page from the Request collection:
if (Request.QueryString["ProdSn"] != "")
{
pSNoTextBox.Text = Request.QueryString["ProdSn"];
if (Request.QueryString["PurDate"] != "")
{
dateTextBox.Text = Request.QueryString["PurDate"];
}
This makes no sense. If you want to use the session, you must also get the values back out from the session object.
Personally I would look into Cross Page postbacks and Server.Transfer combined with Page.PreviousPage. Just make sure you don't set preserveForm parameter to false if using Server.Transfer.
You aren't passing your values as a query string. If you were your Response.Redirect would look like this:
Response.Redirect("Warranty.aspx?ProdSn=something&PurDate=something");
Instead since you are saving these values in a Session variable try this:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
if (Session["ProdSn"] != "")
{
pSNoTextBox.Text = Session["ProdSn"];
if (Session["PurDate"] != "")
{
dateTextBox.Text = Session["PurDate"];
}
else
{
//error message to display
}
}
else
{
//error message to display
}
}
In the button_click of the first form i entered this code
Session["ProdSn"] = pSnTextBox.Text;
Session["PurDate"] = purDateTextBox.Text.ToString();
Response.Redirect("Warranty.aspx?ProdSn=" + Server.UrlEncode(pSnTextBox.Text) +
"&PurDate=" + Server.UrlEncode(purDateTextBox.Text));
and then in the Page_load event of the second form i did this..
string value = Request["ProdSn"];
string value1 = Request["PurDate"];
pSnTextBox.Text = value;
purDateTextBox.Text = value1;
no hassle sustained....easy and perfectly working....
thank for ya'11 helping....
am very grateful
your asp.net page must post your data to second page.
just set your buttons PostBackUrl attribute.
<asp:Button ID="Button1" runat="server" Text="Button" PostBackUrl="target.aspx" />
I do not understand while you are making things complex.
When users clicks the button all data will be send to your target page.

Resources