I have an asp.net web page that allows for manual entry of a record, or an import from an excel spreadsheet to import multiple records.
After the records are added by either process, they display in a Gridview control (bound to a SQLDataReader). This allows the user to edit or delete a record before submitting the entire dataset for processing.
I'm using an Ajax Toolkit AsyncFileUpload control to handle the import. The UploadedComplete c# function runs properly and the records are inserted into the SQL table. The code then calls my DataBindGrid() function to refresh the grid. I can step through the code and see that every line is executing, however, it seems like it never actually finishes, even though stepping through debugging completes.
Two steps are not actually completing, the grid refresh and the label display that indicates to the user that the process is complete.
For testing purposes, I've added a linkButton that calls the BindDataGrid() when clicked. This works to refresh the grid and to also display the status label. It's not a permanent solution, it would be too risky to have a user remember to refresh, they are likely to think that all their records have already been submitted.
At first I thought my problem was trying to do more inside the UploadComplete function then just upload the file (I'm reading the Excel file that was uploaded), so I broke out the code and added a button for the user to click to initiate the actual data processing. This failed because although I could see the file name being saved into a hidden form during the UploadComplete function, when I went to read that hidden field, the data was no longer in it. I'm not loosing the values in any of the other hidden fields.
I've been researching this for 3 days and I'm really stuck. I'm assuming that I am having a problem with postback, but have no clue at this point.
Here is my code:
<%@ Page Title="" Language="C#" MasterPageFile="~/WTIMS.Master" AutoEventWireup="true" CodeBehind="OptionsEntry.aspx.cs" Inherits="WTIMS_OptionsEntry.Pages.OptionsEntry" %>
<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="asp" %>
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
<script type="text/javascript" language=javascript>
function uploadError(sender, args) {
var errMsg = args.get_errorMessage();
updateUploadStatus("error", errMsg);
}
function updateUploadStatus(status, message) {
var uploadStatLabel = document.getElementById('ContentPlaceHolder1_lblError');
uploadStatLabel.innerText = message;
if (status == "error") {
uploadStatLabel.className = "LabelErrorMessage";
}
else {
uploadStatLabel.className = "LabelScucessMessage";
}
}
function startUpload(sender, args) {
var fileName = args.get_fileName();
var fileExt = fileName.substring(fileName.lastIndexOf(".") + 1);
if (fileExt == "xlsx") {
return true;
}
else {
var err = new Error()
err.name = "Upload Error";
err.message = "Only .xlsx files can be uploaded";
throw (err);
return false;
}
}
function uploadComplete(sender, args) {
var rowCount = sender.rowCount;
}
</script>
<asp:ToolkitScriptManager ID="ToolkitScriptManager1" runat="server">
</asp:ToolkitScriptManager>
<table width = 100% cellpadding=1>
<tr>
<td colspan=2>
<asp:Label ID="Label19" runat="server" Text="Upload batch" CssClass=LabelInfo></asp:Label>
</td>
</tr>
<tr>
<td width=50%>
<asp:AsyncFileUpload
ID="AsyncFileUpload1"
Width=400px
ThrobberID=Throbber
UploaderStyle=Modern
CompleteBackColor = "#9BCD9B"
ErrorBackColor="#D44942"
OnClientUploadStarted="startUpload"
OnClientUploadError="uploadError"
OnClientUploadComplete="uploadComplete"
OnUploadedComplete=AsyncFileUpload1_UploadedComplete
OnUploadedFileError=AsyncFileUpload1_UploadedFileError
UploadingBackColor=AliceBlue
runat="server" />
<asp:Label ID="Throbber" runat="server" Text="Label" Style="display:none">
<img src="../../images/LoadingWait.gif" alt="loading" />
</asp:Label>
</td>
</tr>
<tr>
<td>
<asp:LinkButton ID="lkbRefresh" CssClass=linkButton
Text = "Records Upload, Click to View" runat="server"
onclick="lkbRefresh_Click">LinkButton</asp:LinkButton>
</td>
</tr>
<tr>
<td>
<asp:Label ID="lblError" runat="server" Text="" CssClass="LabelErrorMessage"></asp:Label>
</td>
</tr>
<tr>
<td>
<asp:Label ID="lblStatus" runat="server" Text="" CssClass=LabelFormLabel></asp:Label>
</td>
</tr>
</table>
asp.net code for Grid:
<table>
<tr>
<td>
<asp:Label ID="Label18" runat="server" Text="Pending Options" CssClass=LabelInfo></asp:Label>
</td>
</tr>
<tr>
<td>
<asp:Button ID="btnSubmit" runat="server" Text="Submit Pending Options"
CssClass=button onclick="btnSubmit_Click" />
</td>
</tr>
<tr>
<td>
<asp:GridView ID="grdOptions"
runat="server"
AutoGenerateColumns="False"
DataKeyNames="OptionRecordID"
EmptyDataText="You Have no pending Options"
onrowdatabound="grdOptions_RowDataBound">
<FooterStyle CssClass="FooterStyle" />
<HeaderStyle CssClass="HeaderStyle" />
<RowStyle CssClass="RowStyle" />
<AlternatingRowStyle CssClass="AlternatingRowStyle" />
<PagerStyle CssClass="PagerStyle" />
<Columns>
<asp:TemplateField>
<EditItemTemplate>
<asp:LinkButton ID="lkbSave" runat="server" Text= "Save" CssClass=linkButton onclick="lkbSave_Click"></asp:LinkButton>
<asp:LinkButton ID="lkbCancek" runat="server" Text="Cancel" CssClass=linkButton onclick="lkbCancel_Click"></asp:LinkButton>
</EditItemTemplate>
<ItemTemplate>
<asp:LinkButton ID="lkbEdit" runat="server" Text= "Edit" CssClass=linkButton onclick="lkbEdit_Click"></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="OptionRecordID" InsertVisible="False"
SortExpression="OptionRecordID" Visible="False">
<EditItemTemplate>
<asp:Label ID="lblOptionIDEdit" runat="server" Text='<%# Eval("OptionRecordID") %>'></asp:Label>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="lblOptionID" runat="server" Text='<%# Bind("OptionRecordID") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="SecurityID" SortExpression="SecurityID">
<ItemTemplate>
<asp:Label ID="Label2" runat="server" Text='<%# Bind("SecurityID") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Symbol" SortExpression="Symbol">
<EditItemTemplate>
<asp:TextBox ID="txtSymbolEdit" Width=75px runat="server" Text='<%# Bind("Symbol") %>'></asp:TextBox>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label3" runat="server" Text='<%# Bind("Symbol") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Call/Put" SortExpression="CallPut">
<EditItemTemplate>
<asp:DropDownList ID="ddlPutCallEdit" runat="server" CssClass=dropdownList SelectedValue='<%# Bind("CallPut") %>'>
<asp:ListItem Text="Select" Value="Select"></asp:ListItem>
<asp:ListItem Text ="Put" Value = "Put"></asp:ListItem>
<asp:ListItem Text ="Call" Value = "Call"></asp:ListItem>
</asp:DropDownList>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label4" runat="server" Text='<%# Bind("CallPut") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Buy Write" SortExpression="BuyWrite">
<EditItemTemplate>
<asp:DropDownList ID="ddlWtriteBuyEdit" runat="server" CssClass=dropdownList SelectedValue='<%# Bind("BuyWrite") %>'>
<asp:ListItem Text="Select" Value="Select"></asp:ListItem>
<asp:ListItem Text ="Buy" Value = "Buy"></asp:ListItem>
<asp:ListItem Text ="Write" Value = "Write"></asp:ListItem>
</asp:DropDownList>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label8" runat="server" Text='<%# Bind("BuyWrite") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Price" SortExpression="Price">
<EditItemTemplate>
<asp:TextBox ID="txtPriceEdit" Width=75px runat="server" Text='<%# Bind("Price") %>'></asp:TextBox>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label5" runat="server" Text='<%# Bind("Price") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Expiration Date" SortExpression="ExpirationDate">
<EditItemTemplate>
<asp:TextBox ID="txtExpirationDateEdit" Width=100px runat="server" Text='<%# Convert.ToDateTime(Eval("ExpirationDate")).ToString("d") %>'></asp:TextBox>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label6" runat="server" Text='<%# Convert.ToDateTime(Eval("ExpirationDate")).ToString("d") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Description" SortExpression="Description">
<EditItemTemplate>
<asp:TextBox ID="txtDescriptionEdit" runat="server" Text='<%# Bind("Description") %>'></asp:TextBox>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label7" runat="server" Text='<%# Bind("Description") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="UploadStatus" SortExpression="UploadStatus">
<ItemTemplate>
<asp:Label ID="lblStatus" runat="server" Text='<%# Bind("UploadStatus") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton ID="lkbDelete" runat="server" CssClass=linkButton Text="Delete" onclick="lkbDelete_Click"></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</td>
</tr>
</table>
C# Code:
protected void AsyncFileUpload1_UploadedComplete(object sender, AjaxControlToolkit.AsyncFileUploadEventArgs e)
{
strFileName = Server.MapPath("~/Files/" + this.hdnSessionID.Value + "_uploaded.xlsx");
string strUploadFileName = AsyncFileUpload1.FileName.ToString();
InsertData.InsertLogMessage("File to upload: " + strFileName, "OptionsEntry", this.hdnUserID.Value);
this.hdnUploadFileName.Value = strFileName;
AsyncFileUpload1.SaveAs(strFileName);
InsertData.InsertLogMessage("File saved: " + strFileName, "OptionsEntry", this.hdnUserID.Value);
UploadData(strFileName);
DataBindGrid();
}
protected void UploadData(string strUploadFileName)
{ //process the file that was uploaded
try
{
InsertData.InsertLogMessage("Starting Upload", "OptionsEntry", this.hdnUserID.Value);
int i = 0;
// string strFileName = this.hdnUploadFileName.Value;
FileStream myStream = File.Open(strUploadFileName, FileMode.Open, FileAccess.Read);
IExcelDataReader myReader = ExcelReaderFactory.CreateOpenXmlReader(myStream);
myReader.IsFirstRowAsColumnNames = true;
DataSet result = myReader.AsDataSet();
foreach (DataTable dt in result.Tables)
{
foreach (DataRow dr in dt.Rows)
{
Boolean blnIsValid = true;
//code here to loop through file and insert records
InsertData.InsertOptionEntryFormData(strSymbol, strCallPut, strUnformattedPrice, dtmExpirationDate, strDescription, strBuyWrite, this.hdnUserID.Value, strTicker, strStatus);
i = i + 1;
}
}
this.lblStatus.Text = i + " records have been imported to the pending table. Please review and correct any errors before submitting.";
InsertData.InsertLogMessage( i + " records have been imported", "OptionsEntry", this.hdnUserID.Value);
DataBindGrid();
}
catch (Exception ex)
{
InsertData.InsertLogMessage("An error occured: " + ex.Message, "OptionsEntry", this.hdnUserID.Value);
this.lblStatus.Text = "There was a problem importing the data, please check the file and try again.";
}
}
protected void DataBindGrid()
{
this.grdOptions.DataSource = GetData.GetOptionEntryFormData(this.hdnUserID.Value);
this.grdOptions.DataBind();
}
Any suggestions would be greatly appreciated!
Christine
EDIT - Code for the grdOptions
protected void grdOptions_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
Label lblStatus = (Label)e.Row.Cells[9].Controls[1];
if (lblStatus.Text == "Invalid")
{
e.Row.CssClass = "RowError";
}
else
{
if (e.Row.RowState == DataControlRowState.Alternate)
{
e.Row.CssClass = "AlternatingRowStyle";
}
else
{
e.Row.CssClass = "RowStyle";
}
}
}
}
#region Grid Link Actions
protected void lkbSave_Click(object sender, EventArgs e)
{
this.lblErrorMessage.Visible = false;
ClearFormColor();
Boolean blnIsValid = true; //start off assuming everthing is valid
//get the row that we are sitting on
WebControl wc = (WebControl)sender;
GridViewRow row = (GridViewRow)wc.NamingContainer;
//get the data we need
Label lblOptionIDEdit = (Label)row.FindControl("lblOptionIDEdit");
int intOptionIDEdit = int.Parse(lblOptionIDEdit.Text);
TextBox txtSymbolEdit = (TextBox)row.FindControl("txtSymbolEdit");
strSymbol = txtSymbolEdit.Text;
if(!ValidateSymbol())
{
ToggleTextBoxColor(false,txtSymbolEdit);
blnIsValid = false;
}
DropDownList ddlPutCallEdit = (DropDownList)row.FindControl("ddlPutCallEdit");
strCallPut = ddlPutCallEdit.SelectedValue;
if(!ValidateCallPut())
{
ToggleDropDownColor(false,ddlPutCallEdit);
blnIsValid = false;
}
DropDownList ddlWtriteBuyEdit = (DropDownList)row.FindControl("ddlWtriteBuyEdit");
strBuyWrite = ddlWtriteBuyEdit.SelectedValue;
if(!ValidateBuyWrite())
{
ToggleDropDownColor(false,ddlWtriteBuyEdit);
blnIsValid= false;
}
TextBox txtPriceEdit = (TextBox)row.FindControl("txtPriceEdit");
strPrice = txtPriceEdit.Text;
if(!ValidateStrikePrice())
{
ToggleTextBoxColor(false,txtPriceEdit);
blnIsValid= false;
}
TextBox txtExpirationDateEdit = (TextBox)row.FindControl("txtExpirationDateEdit");
strExpirationDate = txtExpirationDateEdit.Text;
if(!ValidateExpirationDate())
{
ToggleTextBoxColor(false,txtExpirationDateEdit);
blnIsValid = false;
}
TextBox txtDescriptionEdit = (TextBox)row.FindControl("txtDescriptionEdit");
strDescription = txtDescriptionEdit.Text;
if(!blnIsValid)
{
this.lblErrorMessage.Text = "Please corrext the data highlighted in yellow";
this.lblErrorMessage.Visible= true;
return;
}
FormatTicker();
//update the data
UpdateData.UpdateOptionEntryFormData(intOptionIDEdit, strSymbol, strCallPut, strUnformattedPrice, dtmExpirationDate, strDescription, strBuyWrite, strTicker, "Manual");
//refresh the grid
this.grdOptions.EditIndex = -1;
DataBindGrid();
}
protected void lkbEdit_Click(object sender, EventArgs e)
{
WebControl wc = (WebControl)sender;
GridViewRow row = (GridViewRow)wc.NamingContainer;
int intIndex = row.RowIndex;
this.grdOptions.EditIndex = intIndex;
DataBindGrid();
}
protected void lkbDelete_Click(object sender, EventArgs e)
{
//get the row that we are sitting on
WebControl wc = (WebControl)sender;
GridViewRow row = (GridViewRow)wc.NamingContainer;
//get the data we need
Label lblRecordID = (Label)row.FindControl("lblOptionID");
int intRecordID = int.Parse(lblRecordID.Text);
//delete the record
DeleteData.DeleteOption(intRecordID);
//refresh the grid
DataBindGrid();
}
protected void lkbCancel_Click(object sender, EventArgs e)
{
this.grdOptions.EditIndex = -1;
}
#endregion