Output parameter from SQL Server not printing to web form - c#

I have a store procedure
create proc spAddEmployees
#Name varchar(50),
#Gender varchar(10),
#Salary int,
#EmployeeId int out
as
begin
insert into tblEmployees values (#Name, #Gender, #Salary)
select EmployeeId = SCOPE_IDENTITY()
end
which has an output parameter that tells the user the current scope_identity
The markup looks like
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
<table style="border: 1px solid black; font-family:Arial">
<tr>
<td>
Employee Name
</td>
<td>
<asp:TextBox ID="txtEmployeeName" runat="server"></asp:TextBox>
</td>
</tr>
<tr>
<td>
Gender
</td>
<td>
<asp:DropDownList ID="ddlGender" runat="server">
<asp:ListItem>Male</asp:ListItem>
<asp:ListItem>Female</asp:ListItem>
</asp:DropDownList>
</td>
</tr>
<tr>
<td>
Salary
</td>
<td>
<asp:TextBox ID="txtSalary" runat="server"></asp:TextBox>
</td>
</tr>
<tr>
<td colspan="2">
<asp:Button ID="btnSubmit" runat="server" Text="Submit"
onclick="btnSubmit_Click" />
</td>
</tr>
<tr>
<td colspan="2">
<asp:Label ID="lblMessage" runat="server"></asp:Label>
</td>
</tr>
</table>
And the code behind
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnSubmit_Click(object sender, EventArgs e)
{
//read from the config file so you don't have to hardcode the connection string
string cs = ConfigurationManager.ConnectionStrings["dbcs"].ConnectionString;
//when you use the using statement the database connection is automatically closed for you
using(SqlConnection con = new SqlConnection(cs))
{
SqlCommand cmd = new SqlCommand("spAddEmployees", con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#Name", txtEmployeeName.Text);
cmd.Parameters.AddWithValue("#Gender",ddlGender.SelectedValue);
cmd.Parameters.AddWithValue("#Salary", txtSalary.Text);
SqlParameter outputParmeter = new SqlParameter();
outputParmeter.ParameterName = "#EmployeeId";
outputParmeter.SqlDbType = SqlDbType.Int;
outputParmeter.Direction = ParameterDirection.Output;
cmd.Parameters.Add(outputParmeter);
con.Open();
cmd.ExecuteNonQuery();
string EmpId = outputParmeter.Value.ToString();
lblMessage.Text = "Employee Id = " + EmpId;
}
}
}
This program should add a new row to the tblEmployees table and then output to the user the output parameter of the stored procedure. It runs and adds the row to the number when the button is clicked, but the output parameter isn't being printed to the screen. Thoughts?

Perhaps:
select EmployeeId = SCOPE_IDENTITY()
In the stored procedure should be:
select #EmployeeId = SCOPE_IDENTITY()

The syntax in the stored procedure isn't right.
You should use
select #EmployeeId = SCOPE_IDENTITY()
^
and also the usual way to retrieve the output parameter is through the command collection. I am not sure that in the process the parameter is replaced somewhere
string EmpId = cmd.Parameters["#EmplyeeId"].Value.ToString();

Related

Form Authentication in ASP.net

Greetings of the day!
I'm using Form Authentication, in registration it is OK, but while login, it's doing wrong, it is just doing opposite.
In Registration, suppose I entered password 123, now it will convert that password using form-authentication, and save in DB, now while login, if user enter 123 then it will be changed, and try to match with the stored one in DB.
In my case, it is doing opposite, if both password match, it shows, custom error message..and if not then increase counter variable for locking account
Please go over my code, and help me out....
Database:-
CREATE TABLE [dbo].[tblUsers](
[ID] [int] IDENTITY(1,1) NOT NULL,
[UserName] [nvarchar](15) NULL,
[Password] [nvarchar](15) NULL,
[Email] [nvarchar](200) NULL,
[RetryAttempts] [int] NULL,
[IsLocked] [bit] NULL,
[LockedDateTime] [datetime] NULL,
PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
CREATE proc [dbo].[sp_RegisterUser]
#UserName nvarchar(15),
#Password nvarchar(15),
#Email nvarchar(200)
As
Begin
Declare #Count int
Declare #ReturnCode int
Select #Count= COUNT(UserName) from tblUsers where UserName=#UserName
if(#Count=1)
Begin
Set #ReturnCode=-1
End
else
Begin
Set #ReturnCode=1
insert into tblUsers(UserName,Password,Email) values(#UserName,#Password,#Email)
End
Select #ReturnCode as ReturnValue
End
CREATE proc [dbo].[SP_AuthenticateUser]
#UserName nvarchar(15),
#Password nvarchar(15)
As
Begin
Declare #Count int
Declare #RetryCount int
Declare #AccountLocked bit
Select #AccountLocked= ISNULL(IsLocked,0) from tblUsers where UserName=#UserName
If(#AccountLocked=1)
Begin
Select 1 as AccountLocked,0 as Authenticate,0 as RetryAttempts
End
Else
Begin
Select #Count= COUNT(UserName) from tblUsers where UserName=#UserName and Password=#Password
If(#Count=1)
Begin
Select 0 as AccountLocked,1 as Authenticate,0 as RetryAttempts
End
Else
Begin
Select #RetryCount=ISNULL(RetryAttempts,0) from tblUsers where UserName=#UserName
Set #RetryCount=#RetryCount+1
If(#RetryCount<=3)
Begin
Update tblUsers set RetryAttempts=#RetryCount where UserName=#UserName
Select 0 as AccountLocked,0 as Authenticate,#RetryCount as RetryAttempts
End
Else
Begin
Update tblUsers set IsLocked=1,LockedDateTime=GETDATE() where UserName=#UserName
Select 1 as AccountLocked,0 as Authenticate,0 as RetryAttempts
End
End
End
End
Design:-
Registration_Page-
<%# Page Language="C#" AutoEventWireup="true" CodeFile="Registration.aspx.cs" Inherits="Registration" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div style="font-family:Arial">
<table style="border: 1px solid black">
<tr>
<td colspan="2">
<b>User Registration</b>
</td>
</tr>
<tr>
<td>
User Name
</td>
<td>
:<asp:TextBox ID="txtUserName" runat="server">
</asp:TextBox>
<asp:RequiredFieldValidator ID="RequiredFieldValidatorusername"
runat="server" ErrorMessage="User Name required" Text="*"
ControlToValidate="txtUserName" ForeColor="Red">
</asp:RequiredFieldValidator>
</td>
</tr>
<tr>
<td>
Password
</td>
<td>
:<asp:TextBox ID="txtPassword" TextMode="Password" runat="server">
</asp:TextBox>
<asp:RequiredFieldValidator ID="RequiredFieldValidatorPassword"
runat="server" ErrorMessage="Password required" Text="*"
ControlToValidate="txtPassword" ForeColor="Red">
</asp:RequiredFieldValidator>
</td>
</tr>
<tr>
<td>
Confirm Password
</td>
<td>
:<asp:TextBox ID="txtConfirmPassword" TextMode="Password" runat="server">
</asp:TextBox>
<asp:RequiredFieldValidator ID="RequiredFieldValidatorConfirmPassword"
runat="server" ErrorMessage="Confirm Password required" Text="*"
ControlToValidate="txtConfirmPassword" ForeColor="Red"
Display="Dynamic"></asp:RequiredFieldValidator>
<asp:CompareValidator ID="CompareValidatorPassword" runat="server"
ErrorMessage="Password and Confirm Password must match"
ControlToValidate="txtConfirmPassword" ForeColor="Red"
ControlToCompare="txtPassword" Display="Dynamic"
Type="String" Operator="Equal" Text="*">
</asp:CompareValidator>
</td>
</tr>
<tr>
<td>
Email
</td>
<td>
:<asp:TextBox ID="txtEmail" runat="server">
</asp:TextBox>
<asp:RequiredFieldValidator ID="RequiredFieldValidatorEmail"
runat="server" ErrorMessage="Email required" Text="*"
ControlToValidate="txtEmail" ForeColor="Red"
Display="Dynamic"></asp:RequiredFieldValidator>
<asp:RegularExpressionValidator ID="RegularExpressionValidatorEmail"
runat="server" ErrorMessage="Invalid Email" ControlToValidate="txtEmail"
ForeColor="Red" Display="Dynamic" Text="*"
ValidationExpression="\w+([-+.']\w+)*#\w+([-.]\w+)*\.\w+([-.]\w+)*">
</asp:RegularExpressionValidator>
</td>
</tr>
<tr>
<td>
</td>
<td>
<asp:Button ID="btnRegister" runat="server" Text="Register"
onclick="btnRegister_Click"/>
</td>
</tr>
<tr>
<td colspan="2">
<asp:Label ID="lblMessage" runat="server" ForeColor="Red">
</asp:Label>
</td>
</tr>
<tr>
<td colspan="2">
<asp:ValidationSummary ID="ValidationSummary1" ForeColor="Red" runat="server" />
</td>
</tr>
</table>
</div>
</form>
</body>
</html>
Login Page:_
<%# Page Language="C#" AutoEventWireup="true" CodeFile="Login.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div style="font-family:Arial">
<table style="border: 1px solid black">
<tr>
<td colspan="2">
<b>Login</b>
</td>
</tr>
<tr>
<td>
User Name
</td>
<td>
:<asp:TextBox ID="txtUserName" runat="server">
</asp:TextBox>
</td>
</tr>
<tr>
<td>
Password
</td>
<td>
:<asp:TextBox ID="txtPassword" TextMode="Password" runat="server">
</asp:TextBox>
</td>
</tr>
<tr>
<td>
<asp:CheckBox ID="chk_boxRememberMe" runat="server" Text="Remember Me" />
</td>
<td>
<asp:Button ID="btnLogin" runat="server" Text="Login" OnClick="btnLogin_Click" />
</td>
</tr>
<tr>
<td>
<asp:Label ID="lblMessage" runat="server" ForeColor="Red"></asp:Label>
</td>
</tr>
</table>
<br />
Click here to register
if you do not have a user name and password.
</div>
</form>
</body>
</html>
Code Behind:-
Registration Page:-
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
using System.Web.Security;
public partial class Registration : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnRegister_Click(object sender, EventArgs e)
{
if (Page.IsValid)
{
string CS = ConfigurationManager.ConnectionStrings["con"].ConnectionString;
using (SqlConnection Conn=new SqlConnection(CS))
{
SqlCommand cmd = new SqlCommand("sp_RegisterUser",Conn);
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter UserName = new SqlParameter("#UserName",txtUserName.Text);
string EncryptPassword = FormsAuthentication.HashPasswordForStoringInConfigFile(txtPassword.Text, "SHA1");
SqlParameter Password = new SqlParameter("#Password", EncryptPassword);
SqlParameter Email = new SqlParameter("#Email", txtEmail.Text);
cmd.Parameters.Add(UserName);
cmd.Parameters.Add(Password);
cmd.Parameters.Add(Email);
Conn.Open();
int ReturnCode=(int) cmd.ExecuteScalar();
if (ReturnCode==-1)
{
lblMessage.Text = "User Name alredy exists";
}
else
{
Response.Redirect("~/Login.aspx");
}
}
}
}
}
Login Page:-
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
using System.Web.Security;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnLogin_Click(object sender, EventArgs e)
{
//Login_WebConfig();
// Login_DataBase();
if (AuthenticateUser(txtUserName.Text, txtPassword.Text))
{
FormsAuthentication.RedirectFromLoginPage(txtUserName.Text, chk_boxRememberMe.Checked);
}
else
{
lblMessage.Text = "Invalid username/password";
}
}
//protected void Login_WebConfig()
//{
// if (FormsAuthentication.Authenticate(txtUserName.Text, txtPassword.Text))
// {
// FormsAuthentication.RedirectFromLoginPage(txtUserName.Text, chk_boxRememberMe.Checked);
// }
// else
// {
// lblMessage.Text = "Invalid user name/password";
// }
//}
protected void Login_DataBase()
{
}
private bool AuthenticateUser(string username, string password)
{
string CS = ConfigurationManager.ConnectionStrings["con"].ConnectionString;
using (SqlConnection Conn = new SqlConnection(CS))
{
SqlCommand cmd = new SqlCommand("SP_AuthenticateUser", Conn);
cmd.CommandType = CommandType.StoredProcedure;
string EncryptPassword = FormsAuthentication.HashPasswordForStoringInConfigFile(password, "SHA1");
SqlParameter paramUserName = new SqlParameter("#UserName", username);
SqlParameter paramPassword = new SqlParameter("#Password", EncryptPassword);
cmd.Parameters.Add(paramUserName);
cmd.Parameters.Add(paramPassword);
Conn.Open();
int ReturnCode = (int)cmd.ExecuteScalar();
return ReturnCode == 1;
}
}
}
Web Config:-
<?xml version="1.0"?>
<!--
For more information on how to configure your ASP.NET application, please visit
http://go.microsoft.com/fwlink/?LinkId=169433
-->
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
<authentication mode="Forms">
<forms loginUrl="Login.aspx" defaultUrl="Welcome.aspx" timeout="2" protection="All">
<!--<credentials passwordFormat="Clear">
<user name="rkbisht" password="1234"/>
</credentials>-->
</forms>
</authentication>
<authorization>
<deny users="?"/>
</authorization>
</system.web>
<appSettings>
<add key="ValidationSettings:UnobtrusiveValidationMode" value="None" />
</appSettings>
<connectionStrings>
<add name="con" connectionString="Data Source=.;Initial Catalog=Security_Learning;Integrated Security=true"/>
</connectionStrings>
</configuration>
Basically, you are not using the right tool for the job.
You are not acutually using FormsAuthentication and you are also not saving the hash in a config file so FormsAuthentication.HashPasswordForStoringInConfig is not what you should be using.
It is worth taking the time to get this right. Here is a starting point:
https://learn.microsoft.com/en-us/aspnet/core/security/data-protection/consumer-apis/password-hashing
Note, you should be using a hash and a salt, the salt should be unique to each user.
Personally I use the Microsoft.AspNetCore.Cryptography.KeyDerivation nuget package with an implementation similar to the following:
Helper Class
using Microsoft.AspNetCore.Cryptography.KeyDerivation;
using Resources;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Web;
public static class SecurityHelper
{
public static int DefaultIterations = 10000
//KeyDerivation.Pbkdf2
/// <summary>
/// Generates a random salt
/// </summary>
/// <returns>A byte array containing a random salt</returns>
public static byte[] GetRandomSalt()
{
byte[] saltBytes = new byte[32];
RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
rng.GetNonZeroBytes(saltBytes);
return saltBytes;
}
public static string GeneratePasswordHash(string plainPassword, int iterations, out string generatedRandomSalt)
{
generatedRandomSalt = Convert.ToBase64String(GetRandomSalt());
return Convert.ToBase64String(ComputeHash(plainPassword, generatedRandomSalt, iterations));
}
public static string GetPasswordHash(string plainPassword, string existingSalt, int iterations)
{
return Convert.ToBase64String(ComputeHash(plainPassword, existingSalt, iterations));
}
private static byte[] ComputeHash(string plainText, string salt, int iterations)
{
return KeyDerivation.Pbkdf2(
password: plainText,
salt: Convert.FromBase64String(salt),
prf: KeyDerivationPrf.HMACSHA256,
iterationCount: iterations,
numBytesRequested: 32);
}
}
Your workflow now changes:
When you save the password, you need to save the salt as well
When authenticating the user, get the user by UserName from the database, calculate the hash for the entered password, using the saved salt, compareing the result with the saved hash.
Roughly
//Registration
using (SqlConnection Conn=new SqlConnection(CS))
{
SqlCommand cmd = new SqlCommand("sp_RegisterUser",Conn);
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter UserName = new SqlParameter("#UserName",txtUserName.Text);
string Salt = string.Empty;
string Password = SecurityHelper.GeneratePasswordHash(txtPassword.Text, SecurityHelper.DefaultIterations, out salt);
;
SqlParameter Password = new SqlParameter("#Password", Password);
SqlParameter Email = new SqlParameter("#Email", txtEmail.Text);
SqlParameter Salt = new SqlParameter("#Salt", Salt);
cmd.Parameters.Add(UserName);
cmd.Parameters.Add(Password);
cmd.Parameters.Add(Email);
Conn.Open();
int ReturnCode=(int) cmd.ExecuteScalar();
if (ReturnCode==-1)
{
lblMessage.Text = "User Name alredy exists";
}
else
{
Response.Redirect("~/Login.aspx");
}
}
//Log In
private bool AuthenticateUser(string username, string password)
{
//Get the following from your database based on username
string savedHash = //fromDB;
string savedSalt = //fromDb;
return (SecurityHelper.GetPasswordHash(password, savedSalt, SecurityHelper.DefaultIterations) == tempUser.Password)
}
I've simplified this somewhat. I also save the iteration against the user in the database, in case we need to increase the default iterations.
My last bit of adivce, so some reading on why "salting" is a good thing.
Your authentication stored procedure (SP_AuthenticateUser) returns 3 columns but you are calling it using ExecuteScalar. You need to get the dataset and check the second column.
private bool AuthenticateUser(string username, string password)
{
string CS = ConfigurationManager.ConnectionStrings["con"].ConnectionString;
using (SqlConnection Conn = new SqlConnection(CS))
{
SqlCommand cmd = new SqlCommand("SP_AuthenticateUser", Conn);
cmd.CommandType = CommandType.StoredProcedure;
string EncryptPassword = FormsAuthentication.HashPasswordForStoringInConfigFile(password, "SHA1");
SqlParameter paramUserName = new SqlParameter("#UserName", username);
SqlParameter paramPassword = new SqlParameter("#Password", EncryptPassword);
cmd.Parameters.Add(paramUserName);
cmd.Parameters.Add(paramPassword);
Conn.Open();
var reader = cmd.ExecuteReader();
reader.Read();
return reader["Authenticate"] as bool;
}
}
Also, make sure you reset the retry counter after successful authentication.
Select #Count= COUNT(UserName) from tblUsers where UserName=#UserName and Password=#Password
If(#Count=1)
Begin
Update tblUsers set RetryAttempts = 0 where UserName = #UserName
Select 0 as AccountLocked,1 as Authenticate,0 as RetryAttempts
End
Your code has a few other problems too, but those two are likely to be causing the behavior noted in your question.
Here is a better way to hash your password.
The user will have to keep signing on unless you set a forms auth cookie. Click here for ideas on how.
You probably don't need credentials in your web.config. You only need to put them there if you intend to use FormsAuthentication.Authenticate. You seem to be using a database instead.

asp.net web application: Invalid postback or callback argument error on button click

I am working on developing an asp.net web application page with a set of cascading drop downs, text boxes and buttons on my page. The drop down lists are populated from the database and are dependent on previous drop downs. The buttons are supposed to write the selected values from the drop down and text boxes to the database.
The page gets loaded with the correct DDL lists. It works fine to write to the database if I only enter a value in the text box and click on the button.
It returns the following error if I select a value from the drop down list and enter a value in the text box and then click the button to add values to the database.
Error message:
"Invalid postback or callback argument. Event validation is enabled using in configuration or <%# Page EnableEventValidation="true" %> in a page. For security purposes, this feature verifies that arguments to postback or callback events originate from the server control that originally rendered them. If the data is valid and expected, use the ClientScriptManager.RegisterForEventValidation method in order to register the postback or callback data for validation."
I did some research and understand there can be security implications if I set enableEventValidation="false", so I don't want to use that option.
What is the other option? How do I use ClientScriptManager.RegisterForEventValidation method as suggested in the error message?
Here is the code I am using: Since it is still under development, I have not added any validations on the DDL or Text Boxes, which I intend to do eventually.
newlevel.aspx
<%# Page Title="" Language="C#" MasterPageFile="~/Main.Master" `AutoEventWireup="true" CodeBehind="newlevels.aspx.cs" Inherits="COA.newlevels" `%>
<%# Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="asp" %>
<%--<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
</asp:Content>--%>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
<div>
<table>
<tr>
<td>Totaling Level A</td>
<td>
<asp:DropDownList ID="ddlTotalingLevelA" runat="server" Width="250" OnSelectedIndexChanged="ddlTotalingLevelA_SelectedIndexChanged" ></asp:DropDownList>
<asp:CascadingDropDown ID="cdlTotalingLevelA" TargetControlID="ddlTotalingLevelA" PromptText="Select Totaling Level A"
PromptValue="" ServicePath="ServiceCS.asmx" ServiceMethod="GetLevelAList" runat="server"
Category="TOTALING_LEVEL_A" LoadingText="Loading..." />
</td>
</tr>
<tr>
<td>Totaling Level B</td>
<td>
<asp:DropDownList ID="ddlTotalingLevelB" runat="server" Width="250"></asp:DropDownList>
<asp:CascadingDropDown ID="cdlTotalingLevelB" TargetControlID="ddlTotalingLevelB" PromptText="Select Totaling Level B"
PromptValue="" ServicePath="ServiceCS.asmx" ServiceMethod="GetLevelBList" runat="server"
Category="TOTALING_LEVEL_B" ParentControlID="ddlTotalingLevelA" LoadingText="Loading..." />
</td>
<td><asp:TextBox ID="txtTotalingLevelB" runat="server" required></asp:TextBox></td>
<td>
<asp:Button ID="ButtonTotalingLevelB" runat="server" Text="Add New Totaling Level B" OnClick="ButtonTotalingLevelB_Click" />
</td>
</tr>
<tr>
<td>Totaling Level C</td>
<td>
<asp:DropDownList ID="ddlTotalingLevelC" runat="server" Width="250"></asp:DropDownList>
<asp:CascadingDropDown ID="cdlTotalingLevelC" TargetControlID="ddlTotalingLevelC" PromptText="Select Totaling Level C"
PromptValue="" ServicePath="ServiceCS.asmx" ServiceMethod="GetLevelCList" runat="server"
Category="TOTALING_LEVEL_C" ParentControlID="ddlTotalingLevelB" LoadingText="Loading..." />
</td>
<td><asp:TextBox ID="txtTotalingLevelC" runat="server"></asp:TextBox></td>
<td>
<asp:Button ID="ButtonTotalingLevelC" runat="server" Text="Add New Totaling Level C" OnClick="ButtonTotalingLevelC_Click" />
</td>
</tr>
<tr>
<td>Totaling Level D</td>
<td>
<asp:DropDownList ID="ddlTotalingLevelD" runat="server" Width="250"></asp:DropDownList>
<asp:CascadingDropDown ID="cdlTotalingLevelD" TargetControlID="ddlTotalingLevelD" PromptText="Select Totaling Level D"
PromptValue="" ServicePath="ServiceCS.asmx" ServiceMethod="GetLevelDList" runat="server"
Category="TOTALING_LEVEL_D" ParentControlID="ddlTotalingLevelC" LoadingText="Loading..." />
</td>
<td><asp:TextBox ID="txtTotalingLevelD" runat="server"></asp:TextBox></td>
<td>
<asp:Button ID="ButtonTotalingLevelD" runat="server" Text="Add New Totaling Level D" OnClick="ButtonTotalingLevelD_Click" />
</td>
</tr>
<tr>
<td>Totaling Level E</td>
<td>
<asp:DropDownList ID="ddlTotalingLevelE" runat="server" Width="250"></asp:DropDownList>
<asp:CascadingDropDown ID="cdlTotalingLevelE" TargetControlID="ddlTotalingLevelE" PromptText="Select Totaling Level E"
PromptValue="" ServicePath="ServiceCS.asmx" ServiceMethod="GetLevelEList" runat="server"
Category="TOTALING_LEVEL_E" ParentControlID="ddlTotalingLevelD" LoadingText="Loading..." />
</td>
<td><asp:TextBox ID="txtTotalingLevelE" runat="server"></asp:TextBox></td>
<td>
<asp:Button ID="ButtonTotalingLevelE" runat="server" Text="Add New Totaling Level E" OnClick="ButtonTotalingLevelE_Click" />
</td>
</tr>
<tr>
<td>Totaling Level F</td>
<td>
<asp:DropDownList ID="ddlTotalingLevelF" runat="server" Width="250"></asp:DropDownList>
<asp:CascadingDropDown ID="cdlTotalingLevelF" TargetControlID="ddlTotalingLevelF"
PromptValue="" ServicePath="ServiceCS.asmx" ServiceMethod="GetLevelFList" runat="server"
Category="TOTALING_LEVEL_F" ParentControlID="ddlTotalingLevelE" LoadingText="Loading..." />
</td>
<td><asp:TextBox ID="txtTotalingLevelF" runat="server"></asp:TextBox></td>
<td>
<asp:Button ID="ButtonTotalingLevelF" runat="server" Text="Add New Totaling Level F" OnClick="ButtonTotalingLevelF_Click" />
</td>
</tr>
</table>
</div>
</asp:Content>
newlevels.aspx.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data.SqlClient;
using System.Configuration;
using System.Data;
namespace ChartOfAccounts
{
public partial class newlevels : System.Web.UI.Page
{
SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["Chpcs"].ToString());
protected void Page_Load(object sender, EventArgs e)
{
}
protected void ButtonTotalingLevelB_Click(object sender, EventArgs e)
{
connection.Open();
SqlCommand cmd = connection.CreateCommand();
cmd.CommandType = CommandType.Text;
cmd.CommandText = "INSERT INTO [SCM].[LKP_TOTALING_LEVEL_B]([TOTALING_LEVEL_B],[TOTALING_LEVEL_A],[UNARY_OPERATOR],[SORTINGORDER]) VALUES('" + ddlTotalingLevelB.SelectedItem.Value + "','" + txtTotalingLevelB.Text + "','" + "','0')";
cmd.ExecuteNonQuery();
connection.Close();
}
protected void ButtonTotalingLevelC_Click(object sender, EventArgs e)
{
connection.Open();
SqlCommand cmd = connection.CreateCommand();
cmd.CommandType = CommandType.Text;
cmd.CommandText = "INSERT INTO [SCM].[LKP_TOTALING_LEVEL_B]([TOTALING_LEVEL_B],[TOTALING_LEVEL_A],[UNARY_OPERATOR],[SORTINGORDER]) VALUES('" + ddlTotalingLevelC.Text + "','" + txtTotalingLevelC.Text + "','" + "','0')";
cmd.ExecuteNonQuery();
connection.Close();
}
protected void ButtonTotalingLevelD_Click(object sender, EventArgs e)
{
connection.Open();
SqlCommand cmd = connection.CreateCommand();
cmd.CommandType = CommandType.Text;
cmd.CommandText = "INSERT INTO [SCM].[LKP_TOTALING_LEVEL_B]([TOTALING_LEVEL_B],[TOTALING_LEVEL_A],[UNARY_OPERATOR],[SORTINGORDER]) VALUES('" + ddlTotalingLevelD.Text + "','" + txtTotalingLevelD.Text + "','" + "','0')";
cmd.ExecuteNonQuery();
connection.Close();
}
protected void ButtonTotalingLevelE_Click(object sender, EventArgs e)
{
connection.Open();
SqlCommand cmd = connection.CreateCommand();
cmd.CommandType = CommandType.Text;
cmd.CommandText = "INSERT INTO [SCM].[LKP_TOTALING_LEVEL_B]([TOTALING_LEVEL_B],[TOTALING_LEVEL_A],[UNARY_OPERATOR],[SORTINGORDER]) VALUES('" + ddlTotalingLevelE.Text + "','" + txtTotalingLevelE.Text + "','" + "','0')";
cmd.ExecuteNonQuery();
connection.Close();
}
protected void ButtonTotalingLevelF_Click(object sender, EventArgs e)
{
connection.Open();
SqlCommand cmd = connection.CreateCommand();
cmd.CommandType = CommandType.Text;
cmd.CommandText = "INSERT INTO [SCM].[LKP_TOTALING_LEVEL_B]([TOTALING_LEVEL_B],[TOTALING_LEVEL_A],[UNARY_OPERATOR],[SORTINGORDER]) VALUES('" + ddlTotalingLevelF.Text + "','" + txtTotalingLevelF.Text + "','" + "','0')";
cmd.ExecuteNonQuery();
connection.Close();
}
protected void ddlTotalingLevelA_SelectedIndexChanged(object sender, EventArgs e)
{
}
}
}

OnClick button working only after second time Asp.NET c#

I'm new to web development and right now I'm working on a website. I have a problem with a Save button on an ASP.Net (front end) web form (back end is in C#). The button is supposed to save data entered in a textbox to a database.
When the Save button is clicked the first time, the page just 'reloads' and clear the textbox and nothing is saved in the SQL Server database (dbo connection). Then when I click the same 'Save' button a second time after re-entering information in the textbox, it actually saves to the database and goes back to a main menu page (as expected). And if I try to re-enter different information, the save button will be working just fine.
The problem happens when a user logs in and navigate to the page where he enters the data and saves it. It will never ever work the first time.
Unfortunately because of confidential purposes, I have to omit and rename certain file paths/directories and tables name!
Here's my Asp.NET code:
<%# Page Language="C#" debug="True" Inherits="Default" src="Default.cs" AutoEventWireup ="true"%>
<%# Register TagPrefix="ob" TagName="ComboTree" Src="/obout/Combotree/ComboTree.ascx" %>
<%# Reference Control="/obout/Combotree/ComboTree.ascx" %>
<HTML>
<HEAD>
<!-- #INCLUDE VIRTUAL="/.../" -->
</HEAD>
<BODY >
<FORM runat="server">
<BASEFONT face="Arial, Helvetica, Sans Serif" color=black size=2>
<TABLE height="100%" cellSpacing=0 cellPadding=0 width="780" align=Center border=0>
<!-- #INCLUDE VIRTUAL="/.../" -->
<TR VALIGN="top">
<!-- #INCLUDE VIRTUAL="/.../" -->
`enter code here`<TD vAlign=top width="100%" HEIGHT="100%">
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0 HEIGHT="100%">
<!-- #INCLUDE VIRTUAL="/.../" -->
<TR>
<!-- #INCLUDE VIRTUAL="/.../" -->
<TD vAlign=top align=left >
<!--- START YOUR CODE HERE!!!!! --->
<script>
function disableListItems(checkBoxListId, disable)
{
// Get the checkboxlist object.
ctr = 0;
while(1 == 1)
{
checkbox = document.getElementById(checkBoxListId + "_" + ctr);
if(checkbox == null)
{
return;
}
checkbox.checked = true;
checkbox.disabled = disable;
ctr++;
}
}
function checkForm()
{
var errMsg = "";
if(isBlank(document.getElementById("tbName").value))
{
errMsg += "\n-Folder Name";
}
if(errMsg!="")
{
alert("The following fields cannot be left blank." + errMsg);
return false;
}
return true;
}
</script>
<font Class="heading">File Library - <ASP:Label ID="lbTitle" RunAt="Server"/> Folder</font>
<INPUT Type="Hidden" ID="hdFolderID" RunAt="Server"/>
<INPUT Type="Hidden" ID="hdParentFolderID" RunAt="Server"/>
<TABLE CellPadding="4" CellSpacing="0" Width="100%" >
<TR>
<TD ColSpan="2" Class="spreadsheet_line"> </TD>
</TR>
<TR>
<TD Class="Spreadsheet"><B>Name</B></TD>
<TD Class="Spreadsheet" Width="100%"><ASP:TextBox ID="tbName" Columns="34" RunAt="Server"/></TD>
</TR>
<TR VAlign="Top" Visible="False" RunAt="Server">
<TD Class="Spreadsheet" NOWRAP><B>Description</B></TD>
<TD Class="Spreadsheet"><ASP:TextBox ID="tbDescription" TextMode="Multiline" Cols="25" Rows="5" RunAt="Server"/></TD>
</TR>
<TR>
<TD Class="Spreadsheet"><B>Active?</B></TD>
<TD Class="Spreadsheet"><ASP:CheckBox ID="cbActive" RunAt="Server"/></TD>
</TR>
<TR Visible="False" RunAt="Server">
<TD Class="Spreadsheet"><B>Folder</B></TD>
<TD Class="Spreadsheet"><ob:ComboTree id="ctFolders" runat="server"/></TD>
</TR>
<TR VAlign="Top" ID="trLicensees" RunAt="Server">
<TD Class="Spreadsheet"><B>Departments</B></TD>
<TD Class="Spreadsheet">
<ASP:DropDownList ID="ddLicensee" DataTextField="Name" DataValueField="DepartmentId" RunAt="Server"/>
<ASP:CheckBox ID="cbAll" Text="All" RunAt="Server"/>
<div style="text-align: left; width: 30%; margin-left:-3px">
<ASP:CheckBoxList ID="cblLicensees" DataTextField="Name" DataValueField="DepartmentId" style="background-color:F3F3F3" RunAt="Server"/> <!--**-->
</div>
</TD>
</TR>
<TR>
<TD Class="Spreadsheet" Align="Right" ColSpan="2">
<ASP:ImageButton ID="btnSave" OnClick="btnSave_OnClick" ImageUrl="/images/buttons/btnSave.gif" RunAt="Server"/>
</TD>
</TR>
</TABLE>
<!--- END YOUR CODE HERE!!!!! --->
</TD>
<!-- #INCLUDE VIRTUAL="/.../" -->
</TR>
<!-- #INCLUDE VIRTUAL="/.../" -->
</TABLE>
</TD>
<!-- #INCLUDE VIRTUAL="/.../" -->
</TR>
<!-- #INCLUDE VIRTUAL="/.../" -->
</TABLE>
</BASEFONT>
</FORM>
</BODY>
</HTML>
And here's the (back end) code for the Save button written in C#:
public void btnSave_OnClick(object sender, System.Web.UI.ImageClickEventArgs E){
int counter = int.Parse(Request.Cookies["counter"].Value);
counter++;
Response.Cookies["counter"].Value = counter.ToString();
try{
SqlConnection Conn = GetConnection();
string SQL;
SqlCommand Cmd;
SqlDataReader Dtr;
if(hdFileID.Value=="")
{
Response.Write("Executing Save (adding new folder to DB");
SQL = "EXEC sp_File_Add #Name,#Description,#UserID";
Response.Write("Save successfully executed. Added to DB");
}
else
{
Response.Write("Executing Save (saving info of folder to DB");
SQL = "EXEC sp_File_Update #Name,#Description,#UserID,#FileID";
Response.Write("Save successfully executed. Saved to DB");
}
Cmd = new SqlCommand(SQL,Conn);
Cmd.Parameters.Add(new SqlParameter("#Name", SqlDbType.VarChar));
Cmd.Parameters["#Name"].Value = tbName.Text;
Cmd.Parameters.Add(new SqlParameter("#Description", SqlDbType.Text));
Cmd.Parameters["#Description"].Value = tbDescription.Text;
Cmd.Parameters.Add(new SqlParameter("#UserID", SqlDbType.Int));
Cmd.Parameters["#UserID"].Value = Convert.ToInt32(hdUserID_Global.Value);
if(hdFileID.Value!="")
{
Cmd.Parameters.Add(new SqlParameter("#FileID", SqlDbType.Int));
Cmd.Parameters["#FileID"].Value = Convert.ToInt32(hdFolderID.Value);
}
Cmd.ExecuteNonQuery();
if(hdFileID.Value=="")
{
SQL = "SELECT MAX(FileID) AS FileID FROM tbl_File WHERE CreatedByUserID=#UserID";
Cmd = new SqlCommand(SQL,Conn);
Cmd.Parameters.Add(new SqlParameter("#UserID", SqlDbType.Int));
Cmd.Parameters["#UserID"].Value = Convert.ToInt32(hdUserID_Global.Value);
Dtr = Cmd.ExecuteReader();
if(Dtr.Read())
{
hdFileID.Value = Dtr["FileID"].ToString();
}
Dtr.Close();
}
SQL = "DELETE FROM tbl_FileLicense ";
SQL += " WHERE FileID=#FileID ";
Cmd = new SqlCommand(SQL,Conn);
Cmd.Parameters.Add(new SqlParameter("#FileID", SqlDbType.Int));
Cmd.Parameters["#FileID"].Value = Convert.ToInt32(hdFileID.Value.ToString());
Cmd.ExecuteNonQuery();
if(ddLicense.Visible)
{
SQL = "EXEC sp_doc_Folder_Add #FileID,#LicenseID,#UserID";
Response.Write("Save successfully executed. Added to DB");
Cmd = new SqlCommand(SQL,Conn);
Cmd.Parameters.Add(new SqlParameter("#FolderID", SqlDbType.Int));
Cmd.Parameters["#FileID"].Value = Convert.ToInt32(hdFileID.Value.ToString());
Cmd.Parameters.Add(new SqlParameter("#LicenseID", SqlDbType.Int));
Cmd.Parameters["#LicenseID"].Value = Convert.ToInt32(ddLicense.SelectedItem.Value.ToString());
Cmd.Parameters.Add(new SqlParameter("#UserID", SqlDbType.Int));
Cmd.Parameters["#UserID"].Value = Convert.ToInt32(hdUserID_Global.Value);
Cmd.ExecuteNonQuery();
}
else
{
}
Conn.Close();
Response.Redirect("/Library/Default2.aspx?FileID=" + Request["RootFileID"].ToString());
Response.End();
}
catch (Exception e){
Response.Write("An error occurred while saving: " + e);
Response.End();
}
}
I've been struggling for more than 2 days on that and I don't see why the button is not firing the first time but only as from the 2nd time. Any help will be greatly appreciated. Thank you.
You should open connection i.e Conn.open() before executing cmd.ExecuteNonQuery() method.
Try this, if it still doesn't work, in first line of webform.aspx i.e. <%# Page Language="C#" add this attribute and see if it works: EnableEventValidation="false". Also check the flow of code by setting breakpoints.
I got it to work by adding EnableViewState = False in the <FORM runat="server"> tag in the asp.NET code

How to get a runtime control id

Using asp.net and c#
Asp.net code
<asp:Button ID="btnAddNew" runat="server" Text="Add New"
onclick="btnAddNew_Click" />
<div id="divAdd" runat="server" style="display:none" >
<table width="100%">
<tr>
<td colspan="1">First Name :</td>
<td colspan="1" align="left"><asp:TextBox ID="txtFName" runat="server" ></asp:TextBox> </td>
</tr>
<tr>
<td colspan="1">Last Name :</td>
<td colspan="1" align="left"><asp:TextBox ID="txtLName" runat="server" ></asp:TextBox> </td>
</tr>
<tr>
<td colspan="1">Date Of Birth :</td>
<td colspan="1" align="left"><asp:TextBox ID="txtDob" runat="server" ></asp:TextBox> </td>
</tr>
<tr>
<td colspan="1">Age :</td>
<td colspan="1" align="left" ><asp:TextBox ID="txtAge" runat="server" ></asp:TextBox> </td>
</tr>
<tr>
<td colspan="2" align="center">
<asp:Button ID="btnSave" runat="server" Text="Save" OnClientClick=" return validate()" type="submit" />
<asp:Button ID="btnClose" runat="server" Text="Close" OnClientClick ="return clear()" type="submit" />
</td>
</tr>
</table>
</div>
C# Code
static void Insert()
{
try
{
string connectionString =
"server=JEBW1011ZAHID;" +
"initial catalog=employee;" +
"integrated security = true";
using (SqlConnection conn =
new SqlConnection(connectionString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(
"INSERT INTO [NyhedTB] ([NyhedDato], [NyhedTitel], [NyhedTekst]) " +
"VALUES (#NyhedDato, #NyhedTitel, #NyhedTekst)", conn))
{
cmd.Parameters.AddWithValue("#NyhedDato", txtfname.Text);
cmd.Parameters.AddWithValue("#NyhedTitel", txtlanme.Text);
cmd.Parameters.AddWithValue("#NyhedTekst", txtage.Text);
int rows = cmd.ExecuteNonQuery(); // Inserted rows number
}
}
}
catch (SqlException ex)
{
//Log exception
//Display Error message
}
}
Showing error as txtfname does not exist.
Need code help
You Insert method is static. It doesn't have access to any page elements. I would recommend you passing those values as parameters to the method instead of coupling it with your UI:
static void Insert(string fName, string lName, string age)
{
try
{
string connectionString =
"server=JEBW1011ZAHID;" +
"initial catalog=employee;" +
"integrated security = true";
using (SqlConnection conn = new SqlConnection(connectionString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(
"INSERT INTO [NyhedTB] ([NyhedDato], [NyhedTitel], [NyhedTekst]) " +
"VALUES (#NyhedDato, #NyhedTitel, #NyhedTekst)", conn))
{
cmd.Parameters.AddWithValue("#NyhedDato", fName);
cmd.Parameters.AddWithValue("#NyhedTitel", lName);
cmd.Parameters.AddWithValue("#NyhedTekst", age);
int rows = cmd.ExecuteNonQuery(); // Inserted rows number
}
}
}
catch (SqlException ex)
{
//Log exception
//Display Error message
}
}
and then when calling this method from your code behind you could pass whatever values you want:
protected void SomeButton_Click(object sender, EventArgs e)
{
Insert(txtfname.Text, txtlanme.Text, txtage.Text);
}
Now your Insert method is a little more reusable as it is no longer coupled to your UI.
Remove the static in your method
Put this code public void Insert() instead of static void Insert()

how to insert / edit values from repeaters dynamically?

.aspx page something like this
<form id="Form1" runat="server">
<asp:Repeater ID="Repeater1" runat="server">
<HeaderTemplate>
<table border="0" width="600px" cellpadding="2" cellspacing="1" style="border: 1px solid maroon;">
<tr bgcolor="maroon">
<th> Subject_Id </th>
<th> Subject_Name </th>
<th> Fill_Marks </th>
</tr>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td width="100">
<asp:TextBox ID="Subject_Id" runat="Server" Text='<%#Eval("Subject_Id")%>'></asp:TextBox>
</td>
<td>
<asp:TextBox ID="Subject_Name" runat="Server" Text='<%#Eval("Subject_Name")%>'></asp:TextBox>
</td>
<td>
<asp:TextBox ID="Marks" runat="server"></asp:TextBox>
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
<asp:Button ID="btnInsert" runat="server" onclick="btnInsert_Click" Text="Insert" CommandArgument="" CommandName=""/>
<asp:Button ID="btnUpdate" runat="server" onclick="btnUpdate_Click" Text="Update" CommandArgument="" CommandName=""/>
</form>
C# - Code behind...
protected void btnInsert_Click(object sender, EventArgs e)
{
cn = new SqlConnection(ConfigurationManager.ConnectionStrings["DbConnect"].ConnectionString);
cn.Open();
foreach (RepeaterItem item in Repeater1.Items)
{
TextBox Subject_Id = (TextBox)item.FindControl("Subject_Id");
TextBox Subject_Name = (TextBox)item.FindControl("Subject_Name");
TextBox Marks = (TextBox)item.FindControl("Marks");
SqlCommand cmd = new SqlCommand("Insert into result VALUES (id='"+#Subject_Id+"',name='"+#Subject_Name+"',marks='"+#Marks+"')", cn);
Repeater1.DataSource = cmd.ExecuteReader();
Repeater1.DataBind();
cn.Close();
cmd.Connection.Close();
cmd.Connection.Dispose();
}
}
Now i want to insert that data into following table.....
result_table
id varchar(10)
name varchar(20)
marks varchar(3)
how can i perform insert and update function to retrieve data from to the database... with easy way ? ? thanks...
Implement the btnInsert_Click function with the following
** edited as per your new function
protected void btnInsert_Click(object sender, EventArgs e)
{
String connectionString = ConfigurationManager.ConnectionStrings["DbConnect"].ConnectionString;
String queryString = "";
using (SqlConnection connection = new SqlConnection(connectionString))
{
foreach (RepeaterItem item in Repeater1.Items)
{
TextBox Subject_Id = (TextBox)item.FindControl("Subject_Id");
TextBox Subject_Name = (TextBox)item.FindControl("Subject_Name");
TextBox Marks = (TextBox)item.FindControl("Marks");
queryString = "Insert into result VALUES (id='"+#Subject_Id+"',name='"+#Subject_Name+"',marks='"+#Marks+"')";
SqlCommand command = new SqlCommand(queryString, connection);
// execute the query to update the database
cmd.ExecuteNonQuery();
}
}
//call the function to load the gridview if it is lost on postback.
}
It is always better to move the database and grid view filling codes to separate functions, so that it is easy to repeat the actions on button clicks.
insert some property in your button tags:
CommandArgument="" CommandName=""
Repeater1.ItemCommand +=new RepeaterCommandEventHandler(Repeater1_ItemCommand);
Create a function named protected void Repeater1_ItemCommand(object source, RepeaterCommandEventArgs e){ some code you want to write.........}
Dim permissionList As New List(Of OPASWCFApp.PROJECT_NOTE_CONTACT_MAP)
For Each rItem As RepeaterItem In rptProducts.Items
Dim qty1 As Integer
Dim qty2 As Integer
Dim hdnvalue As Integer
Dim txtBox1 As TextBox = DirectCast(rItem.FindControl("numAdmin1"), TextBox)
Dim txtBox2 As TextBox = DirectCast(rItem.FindControl("numAdmin2"), TextBox)
Dim hdnf As HiddenField = DirectCast(rItem.FindControl("hdnContacttype"), HiddenField)
qty1 = Convert.ToInt32(txtBox1.Text)
qty2 = Convert.ToInt32(txtBox2.Text)
hdnvalue = Convert.ToInt32(hdnf.Value)
If qty1 > 0 Or qty2 > 0 Then
Dim _d As OPASWCFApp.PROJECT_NOTE_CONTACT_MAP =
New OPASWCFApp.PROJECT_NOTE_CONTACT_MAP()
_d.PROJECT_NOTE_CONTACT_MAP_CONTACT_TYPE_ID = hdnvalue
_d.PROJECT_NOTE_CONTACT_MAP_DURATION = CInt((qty1 * 60) + qty2)
_d.PROJECT_NOTE_CONTACT_MAP_CONTACT_TYPE_ID = hdnvalue
permissionList.Add(_d)
End If
Next
ProcessDataResult.ContactMap = permissionList.ToArray()

Categories