Somehow one of my stored procedures just stopped executing from aspx page. It works if I run it from SQL Server using EXEC. But when I click a button on my aspx page which assigns parameters and values, and launches this procedure, page reloads but data is not updated. This button can run create or update procedure, depending on the page parameters in the address bar. But nothing is executed.
In the aspx page I create that button like this:
<asp:Button id="btnSaveChanges" runat="server"
class="class_Button Normal Enabled"
OnClick="btnSaveChanges_Click" Text="Save changes" Width="100" />
Then in the code-behind file:
protected void btnSaveChanges_Click(object s, EventArgs e)
{
//if (Page.IsValid)
//{
SqlCommand sqlComm1 = new SqlCommand();
SqlConnection sqlConn1 = new SqlConnection("Server=localhost\\SqlExpress;Database=TestDB;Integrated Security=true");
sqlConn1.Open();
if(param_id == 0)
{
sqlComm1 = new SqlCommand("dcspCreateEmpDetails", sqlConn1);
}
if(param_id > 0)
{
sqlComm1 = new SqlCommand("dcspUpdateEmpDetails", sqlConn1);
}
sqlComm1.CommandType = CommandType.StoredProcedure;
if (param_id > 0)
sqlComm1.Parameters.AddWithValue("#empID", param_id);
sqlComm1.Parameters.AddWithValue("#empName1", tbName1.Text);
sqlComm1.Parameters.AddWithValue("#empSurname", tbSurname.Text);
sqlComm1.Parameters.AddWithValue("#empBirthDate", Convert.ToDateTime(tbBirthDate.Text));
sqlComm1.ExecuteNonQuery();
//}
sqlConn1.Close();
}
That's it. Page is valid, 100%. And even if I remove validation check, no result.
Here is the procedure:
CREATE PROCEDURE dcspUpdateEmpDetails
#empID int,
#empName1 nvarchar(50) = null,
#empSurname nvarchar(50) = null,
#empBirthDate datetime = null
AS
UPDATE Employees
SET
name_1 = #empName1,
surname = #empSurname,
date_of_birth = #empBirthDate
WHERE (employee_id = #empID)
Hope you'll help me with it, guys. I really don't understand what happened to this stuff...
Updates for the topic:
Examining debug messages I found, that textbox loses its text before the stored procedure in the OnClick event takes this text as a parameter.
Is it really normal that server first restores the page and only after that it executes code in OnClick event? I think it's logically incorrect because Page_Load is designed to load the default page, while buttons and other controls are used to change and manipulate content of a page. Why do I need those controls if their code can't execute timely?
I took my backup copy and copied all stuff regarding this problem to my current version. It was just the same absolutely identical code. I just replaced current code with the same code from backup and it works now. What was that?
I can't mark anything as an answer because there are only comments here. I'll mark this one.
Related
I have a web forms project that has one filter. When the user filters the data and clicks on the next page, the filter seems to get taken off and the default data is displayed. How can I fix this? Is it the OnPageIndexChanging attribute method that needs updating? I've shown the code behind below for the ONPageIndexChanging method and the method used to bind the data (had to cut some out to get rid of the "too much code" error but if I'm missing anything that would be helpful, please let me know.)
protected void dashboard_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
dashboard.PageIndex = e.NewPageIndex;
BindDataToGridView();
}
void BindDataToGridView(SqlCommand cmdSQL = null)
{
// default sql
if (cmdSQL is null)
{
cmdSQL = new
SqlCommand("SELECT TabID, TabName, Title, CreatedOnDate, TabPath From [tableName].[dbo].[Tabs] Order By TabName");
}
var connectionFromConfig = WebConfigurationManager.ConnectionStrings["connstring"].ConnectionString;
using (cmdSQL)
{
cmdSQL.Connection = new SqlConnection(connectionFromConfig);
cmdSQL.Connection.Open();
DataTable rst = new DataTable();
rst.Load(cmdSQL.ExecuteReader());
dashboard.DataSource = rst;
dashboard.DataBind();
}
}
}
In place of your BindDataToGridView() for the paging event?
Call the SAME routine you have for the button click to filter the dates.
(you could even pull out the code for the button click into a separate routine. That routine filters by date, so have both your button click to filter, and the page index change event call that same routine.
So, for paging, you have to call the routine with the filter. This kind of suggests that you want one routine to load the grid, and it has to figure out if you have a filter or not. So, you might check for start/end date being blank. this would allow both page load event, the filter button, and the data page change event ALL to call ONE common routine.
So, a few things:
If you going to bind a grid/list view? and page? And filter?
(3 issues)?
Then make ONE common routine for all to call.
Say like this:
void BindDataToGridView()
{
SqlCommand cmdSQL = new SqlCommand("");
cmdSQL.CommandText = "SELECT TabID, TabName, Title, CreatedOnDate, TabPath From TableName Order By TabName";
if (startDate.Text != "")
{
// filter
cmdSQL.CommandText =
"SELECT TabID, TabName, Title, CreatedOnDate, TabPath From TableName " +
"WERE CreatedOnDate >= #Start AND <= #End ORDER By TabName";
cmdSQL.Parameters.Add("#Start", SqlDbType.Date).Value = startDate.Text;
cmdSQL.Parameters.Add("#End", SqlDbType.Date).Value = endDate.Text;
}
using (cmdSQL)
{
cmdSQL.Connection = new SqlConnection(conString);
cmdSQL.Connection.Open();
DataTable rst = new DataTable();
rst.Load(cmdSQL.ExecuteReader());
dashboard.DataSource = rst;
dashboard.DataBind();
}
}
So now we are NOT passing the filter. You could I suppose also put the sql or the status of the filter into view state, and have the filter routine check this, but you better off to do the above.
In fact, I often suggest that we filter the reocrdset against its built in "view", as that can save database hits, but it don't matter.
So, when introducing filters? AND paging? You have to keep the above in mind.
So, now we have one routine for page load, the button click and the pager changing index code.
In my simple starter asp page I create a DataTable and populate it with two rows. The web site allows users to add new rows. My problem is the DataTable doesn't save the information. I've stepped through the code and the row gets added but the next time a row is added it's not there, only the original two and the newest one to get entered.
I have gotten around this, in an inelegant way, but am really curious why the new rows are being saved.
My code:
protected void Page_Load(object sender, EventArgs e)
{
_Default.NameList = new DataTable();
DataColumn col = new DataColumn("FirstName", typeof(string));
_Default.NameList.Columns.Add(col);
col = new DataColumn("LastName", typeof(string));
_Default.NameList.Columns.Add(col);
DataRow row = _Default.NameList.NewRow();
row["FirstName"] = "Jane";
row["LastName"] = "Smith";
_Default.NameList.Rows.Add(row);
row = _Default.NameList.NewRow();
row["FirstName"] = "John";
row["LastName"] = "Doe";
_Default.NameList.Rows.Add(row);
}
protected void AddButton_Click(object sender, EventArgs e)
{
DataRow row = _Default.NameList.NewRow();
row["FirstName"] = this.TextBox1.Text;
row["LastName"] = this.TextBox2.Text;
_Default.NameList.Rows.Add(row);
_Default.NameList.AcceptChanges(); // I've tried with and without this.
}
I've tried saving them to GridView control but that seems like quite a bit of work.
I'm new to ASP.Net but have done windows programming in C# for the last two years.
You're creating a new DataTable object each time the page loads.
You need to persist the DataTable object to session state or a static variable, or save the data to a database.
Remember that handling events like your button click requires a full postback. You don't run just the click code, you run your entire page lifecycle on a new instance of your page class. The new instance of your page class means a new instance of the datatable as well.
The issue here is that your DataTable is being created every time your page loads and it goes out of scope when your page has finished loading and been displayed to the user. To get your desired effect, you will need to store the DataTable in either Session, ViewState, cache, use a control like GridView that will automatically store the underlying data in its state, or something else.
Since you're new to ASP.NET, check out your options for state management.
I have a *.aspx page that contains a text box and a button. When the user enters information in to the textbox and clicks post, it inserts the data into my sql database. The issue is, that if the user hits refresh, it will keep inserting the same data into the database. I am pretty sure the whole "click" method is called, not just the insert call. I tried messing with sessions but it complains. I am not really sure what to do. I am looking for a simple easy fix.
protected void PostButton_Click(object sender, EventArgs e)
{
string wpost = (string)Session["WallPost"];
DateTime wtime = (DateTime)Session["WallDateTime"];
if (txtWallPost.Text.Length > 0 && !wpost.Equals(txtWallPost.Text))
{
string strCon = System.Web.Configuration.WebConfigurationManager.ConnectionStrings["SocialSiteConnectionString"].ConnectionString;
using (SqlConnection conn = new SqlConnection(strCon))
{
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = "INSERT INTO [WallTable] ([UserId], [FriendId], [WallPost]) VALUES (#UserId, #FriendId, #WallPost)";
cmd.Parameters.AddWithValue("#UserId", User.Identity.Name);
cmd.Parameters.AddWithValue("#FriendId", User.Identity.Name);
cmd.Parameters.AddWithValue("#WallPost", txtWallPost.Text);
conn.Open();
cmd.ExecuteNonQuery();
Session.Add("WallPost", txtWallPost.Text);
Session.Add("WallDateTime", new DateTime());
conn.Close();
txtWallPost.Text = "";
LoadWallPosts();
}
}
}
return;
}
If the PostButton_Click is the server handler for the click event on your button then insert code shold be executed only if the user hits the post button - it should not happen in case of refresh.
I am pretty sure is not enough - to be sure put a breakpoint in your PostButton_Click method, hit F5 to run in debug mode and see if the breakpoint gets hit with a refresh.
If so it means that:
you are calling explicitly
PostButton_Click from somewhere
else (Page_Load?)
PostButton_Click was accidentally
set as event handler for some other
event on the page
A quick way of verifying hypotesis 1 & 2 is to run a search for PostButton_Click and see where you are calling it from or if it set as handler for some other element (maybe your form?) in the markup.
Add Response.Redirect(Request.Url.ToString(), false); to your button event and that should solve the problem.
if he refreshes or press the back button the post will happen again, thus your page will process the same data thus insert once again.
You have to change your logic
It would be preferable to redirect the client to another page after the insert, however, if you really need the client stay in the same page, you can use a (bool) variable on your page to state if the insert has been done, and skip the insert logic if it has been executed before
I have a asp:textbox that allows a user to enter information. When the user clicks the asp:button, it inserts the text from the textbox into my sql database, and then redirects back to the page. If the user hits refresh, the event from the button gets called again. I need to rectify this so that it no longer gets called or it doesn't repost the information.
protected void PostButton_Click(object sender, EventArgs e)
{
if (txtWallPost.Text.Length > 0)
{
string strCon = System.Web.Configuration.WebConfigurationManager.ConnectionStrings["SocialSiteConnectionString"].ConnectionString;
using (SqlConnection conn = new SqlConnection(strCon))
{
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = "INSERT INTO [WallTable] ([UserId], [FriendId], [WallPost]) VALUES (#UserId, #FriendId, #WallPost)";
cmd.Parameters.AddWithValue("#UserId", User.Identity.Name);
cmd.Parameters.AddWithValue("#FriendId", User.Identity.Name);
cmd.Parameters.AddWithValue("#WallPost", txtWallPost.Text);
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
txtWallPost.Text = "";
LoadWallPosts();
Response.Redirect("~/UserPages/UserProfile.aspx?view="+"wall");
}
}
}
return;
}
Classic problem, with a classic solution: Redirect After Post. You just need to redirect the user to another page (or the same page...) after processing the POST - that way when they hit refresh, the last request (and the one to be repeated) will be a GET.
See:
Refresh the page after a postback action in asp.net
How do I use the “Post/Redirect/Get” a.k.a. “Redirect after Post” with asp.net
Page Refresh Causes Duplicate POST in ASP.NET Applications
Curing the “Back Button Blues”
I ended up just adding a session id for the wall post text. In the post method, it checks to make sure the textbox text, is different from that of the session text. On refresh it clears out the session and therefore works fine.
I'm using the FormView control in ASP.NET for a simple form to insert into a MS SQL DB. I have an event for onItemInserting to set some values behind (such as time stamp, etc) and was curious how to check some user entered values in the onItemInserting event and cancel the item from being inserted. The reason I want to do it in the code behind is to query the database and use the values to validate the user entered data.
Pseudo Code is as follows:
protected void Form_addRoom_ItemInserting(object sender, FormViewInsertEventArgs e)
{
... Query DB for some values ...
if(enteredMaxPeople > queryMaxPeople)
{
**Cancel** DB Insert
statusLabel.text = "Value entered not valid";
}
}
In the end the question comes down to how do I cancel a FormView from inserting in the code behind?
Thank you!
Sean
e.Cancel = true;