This is my first time working with sql and asp.net. I am working on a few examples to ensure I have all the basics I need. I was walking though a tutorial and where everything should be working just fine, I am getting an .ExecuteNonQuery() Error. SqlException was unhandled by user code // Incorrect syntax near the keyword 'Table'.
If you have any pointers, let me know. I worked the tutorial twice, I'm sure I'm doing something wrong here. -Thanks
.CS Code:
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;
namespace WebSite
{
public partial class _default : System.Web.UI.Page
{
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString);
protected void Page_Load(object sender, EventArgs e)
{
con.Open();
}
protected void Button1_Click(object sender, EventArgs e)
{
SqlCommand cmd = new SqlCommand("insert into Table values('" + txtfName.Text + "','" + txtlName.Text + "','" + txtpNumber.Text + "')", con);
cmd.ExecuteNonQuery();
con.Close();
Label1.Visible = true;
Label1.Text = "Your DATA has been submitted";
txtpNumber.Text = "";
txtlName.Text = "";
txtfName.Text = "";
}
}
}
.aspx File:
<form id="form1" runat="server">
<div class="auto-style1">
<strong>Insert data into Database<br />
<br />
</strong>
</div>
<table align="center" class="auto-style2">
<tr>
<td class="auto-style3">First Name:</td>
<td class="auto-style4">
<asp:TextBox ID="txtfName" runat="server" Width="250px"></asp:TextBox>
</td>
</tr>
<tr>
<td class="auto-style3">Last Name:</td>
<td class="auto-style4">
<asp:TextBox ID="txtlName" runat="server" Width="250px"></asp:TextBox>
</td>
</tr>
<tr>
<td class="auto-style3">Phone Number:</td>
<td class="auto-style4">
<asp:TextBox ID="txtpNumber" runat="server" Width="250px"></asp:TextBox>
</td>
</tr>
<tr>
<td class="auto-style3"> </td>
<td class="auto-style4">
<asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Submit" Width="150px" />
</td>
</tr>
</table>
<br />
<br />
<asp:Label ID="Label1" runat="server" ForeColor="#663300" style="text-align: center" Visible="False"></asp:Label>
<br />
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:ConnectionString %>" SelectCommand="SELECT * FROM [Table]"></asp:SqlDataSource>
</form>
SQL Database:
CREATE TABLE [dbo].[Table] (
[Id] INT IDENTITY (1, 1) NOT NULL,
[fName] VARCHAR (50) NOT NULL,
[lName] VARCHAR (50) NOT NULL,
[pNumber] VARCHAR (50) NOT NULL,
PRIMARY KEY CLUSTERED ([Id] ASC)
);
Usually this error message is caused by a single quote present in your input textboxes or by the use of a reserved keyword. Both problems are present in your query. The TABLE word is a reserved keyword for SQL Server and thus you should encapsulate it with square brackets, while for the possible presence of a single quote in the input text the correct approach is to use Parameterized Query like this
SqlCommand cmd = new SqlCommand("insert into [Table] values(#fnam, #lnam, #pNum)", con);
cmd.Parameters.AddWithValue("#fnam", txtfName.Text );
cmd.Parameters.AddWithValue("#lnam", txtlName.Text );
cmd.Parameters.AddWithValue("#pNum", txtpNumber.Text);
cmd.ExecuteNonQuery();
With this approach you shift the work to parse your input text to the framework code and you avoid problems with parsing text and Sql Injection
Also, I suggest to NOT USE a global variable to keep the SqlConnection reference. It is an expensive resource and, if you forget to close and dispose it, you could have a significant impact on the performance and the stability of your application.
For this kind of situations the using statement is all you really need
using(SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings
["ConnectionString"].ConnectionString));
{
con.Open();
SqlCommand cmd = new SqlCommand("insert into [Table] values(#fnam, #lnam, #pNum)", con);
cmd.Parameters.AddWithValue("#fnam", txtfName.Text );
cmd.Parameters.AddWithValue("#lnam", txtlName.Text );
cmd.Parameters.AddWithValue("#pNum", txtpNumber.Text);
cmd.ExecuteNonQuery();
}
Of course remove the global variable and the open in the Page_Load
Your query is trying to insert into a table called Table. Does that really exist? If not then put the actual table name into the query. If your table really is called Table then I strongly recommend you change it to something less confusing.
Also, stop writing commands by concatenating text now. Learn how to use parameters in order to prevent SQL injection
EDIT
An insert statement uses the format specified in the BOL documents for INSERT, and the examples provided therein. Table is a keyword, so don't use it as a table name. If you have to use a keyword, you need to escape it using square brackets. See BOL: Delimited Identifiers
I still say, don't use "Table" as the name for a table. Make your life easier.
Oh, and write secure code (see the above comment re SQL injection, and how Linked In got hit, and how much it cost them)
Changed 'insert into Table values' to 'insert into [Table] values' and all works fine. Thanks Note to self, stay away from simple names.
SqlConnection conn = new SqlConnection("Data Source=MCTX-ZAFEER\\SQLEXPRESS;Initial Catalog=ZKAbid_Db;Persist Security Info=True;User ID=sa;Password=sa#1234");
public int checkLogin(Ad_login ad)
{
SqlCommand cmd = new SqlCommand("Sp_Login", conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#Admin_id", ad.Ad_id);
cmd.Parameters.AddWithValue("#Password", ad.Ad_Password);
// cmd.InsertCommand.Connection = connection1;
SqlParameter objLogin = new SqlParameter();
objLogin.ParameterName = "#isValid";
objLogin.SqlDbType = SqlDbType.Bit;
objLogin.Direction = ParameterDirection.Output;
cmd.Parameters.Add(objLogin);
conn.Open();
cmd.ExecuteNonQuery();
int res = Convert.ToInt32(objLogin.Value);
conn.Close();
return res;
}
Wherever you are using ExecuteNonQuery() you should catch SqlException or you need to throws from your function.
In the case given above Button1_Click is the function using ExecuteNonQuery() from SqlCommand class.
Now what happens that this function ( ExecuteNonQuery ) has definition to throws SqlException. so you have two option
- you can also throws SqlException
- or you can put this line in try catch block to handle the Exception.
Related
I am trying to design a notification section for my ASP.NET website.
My requirement is similar to this image layout.
I was able to implement this with the asp repeater control and binding it with database.
I have table in my DB that has image, name and comments as its columns.
So according to the no. of rows in the DB table, the repeater control will get me the contents in the defined layout.
But i also wanted to implement the close button ("X" - top right corner). this close button will just remove the particular comment (but it will not delete data in DB).
Could you please help me in achieving this ??
Also thanks to suggest any other possible option to acheive this.
PFB the code i have done so far
<asp:Repeater ID="Repeater1" runat="server">
<ItemTemplate>
<table>
<tr>
<td style="height:64px;width:64px">
<asp:Image ID="imgEmployee" CssClass="imgClass" ImageUrl='<%# Eval("ImagePath")%>'runat="server" />
</td>
<td>
<asp:Label runat="server" Text='<%# Eval("Name")%>'></asp:Label>
<p> <%# Eval("Comments")%></p>
</td>
</tr>
</table>
</ItemTemplate>
</asp:Repeater>
and code behind
protected void Page_Load(object sender, EventArgs e)
{
DataSet ds = GetData();
Repeater1.DataSource = ds;
Repeater1.DataBind();
}
private DataSet GetData()
{
string CS = ConfigurationManager.ConnectionStrings["con"].ConnectionString;
using (SqlConnection con = new SqlConnection(CS))
{
SqlDataAdapter da = new SqlDataAdapter("Select * from tblNotification", con);
DataSet ds = new DataSet();
da.Fill(ds);
return ds;
}
}
And my table (tblNotification) has 3 columns - "ImagePath", "Name" and "Comments"
hai guys here is my question please help me
I have a gridview with hyperlink fields here my requirement is if I click on hyperlink of particular row I need to display that particular row values into other page in that page user will edit record values after that if he clicks on update button I need to update that record values and get back to previous home page. if iam clicking hyper link in first window new window should open with out any url tool bar and minimize close buttons like popup modular Ajax ModalPopUpExtender but iam un able to ge that that one please help me
the fillowing code is defalut.aspx
<head runat="server">
<title>PassGridviewRow values </title>
<style type="text/css">
#gvrecords tr.rowHover:hover
{
background-color:Yellow;
font-family:Arial;
}
</style>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:GridView runat="server" ID="gvrecords" AutoGenerateColumns="false"
HeaderStyle-BackColor="#7779AF" HeaderStyle-ForeColor="White" DataKeyNames="UserId" RowStyle-CssClass="rowHover">
<Columns>
<asp:TemplateField HeaderText="Change Password" >
<ItemTemplate>
<a href ='<%#"UpdateGridviewvalues.aspx?UserId="+DataBinder.Eval(Container.DataItem,"UserId") %>'> <%#Eval("UserName") %> </a>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="FirstName" HeaderText="FirstName" />
<asp:BoundField DataField="LastName" HeaderText="LastName" />
<asp:BoundField DataField="Email" HeaderText="Email" />
</Columns>
</asp:GridView>
</div>
</form>
</body>
</html>
following code default.aspx.cs code
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
BindGridview();
}
}
protected void BindGridview()
{
SqlConnection con = new SqlConnection("Data Source=.;Integrated Security=SSPI;Initial Catalog=testdb1");
con.Open();
SqlCommand cmd = new SqlCommand("select * from UserDetails", con);
SqlDataAdapter da = new SqlDataAdapter(cmd);
cmd.ExecuteNonQuery();
con.Close();
DataSet ds = new DataSet();
da.Fill(ds);
gvrecords.DataSource = ds;
gvrecords.DataBind();
}
}
this is updategridviewvalues.aspx
<head runat="server">
<title>Update Gridview Row Values</title>
<script type="text/javascript">
function Showalert(username) {
alert(username + ' details updated successfully.');
if (alert) {
window.location = 'Default.aspx';
}
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<table>
<tr>
<td colspan="2" align="center">
<b> Edit User Details</b>
</td>
</tr>
<tr>
<td>
User Name:
</td>
<td>
<asp:Label ID="lblUsername" runat="server"/>
</td>
</tr>
<tr>
<td>
First Name:
</td>
<td>
<asp:TextBox ID="txtfname" runat="server"></asp:TextBox>
</td>
</tr>
<tr>
<td>
Last Name:
</td>
<td>
<asp:TextBox ID="txtlname" runat="server"></asp:TextBox>
</td>
</tr>
<tr>
<td>
Email:
</td>
<td>
<asp:TextBox ID="txtemail" runat="server"></asp:TextBox>
</td>
</tr>
<tr>
<td>
</td>
<td>
<asp:Button ID="btnUpdate" runat="server" Text="Update" onclick="btnUpdate_Click" />
<asp:Button ID="btnCancel" runat="server" Text="Cancel" onclick="btnCancel_Click"/>
</td>
</tr>
</table>
</div>
</form>
</body>
</html>
and my updategridviewvalues.aspx.cs code is follows
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class UpdateGridviewvalues : System.Web.UI.Page
{
SqlConnection con = new SqlConnection("Data Source=.;Integrated Security=SSPI;Initial Catalog=testdb1");
private int userid=0;
protected void Page_Load(object sender, EventArgs e)
{
userid = Convert.ToInt32(Request.QueryString["UserId"].ToString());
if(!IsPostBack)
{
BindControlvalues();
}
}
private void BindControlvalues()
{
con.Open();
SqlCommand cmd = new SqlCommand("select * from UserDetails where UserId=" + userid, con);
SqlDataAdapter da = new SqlDataAdapter(cmd);
cmd.ExecuteNonQuery();
con.Close();
DataSet ds = new DataSet();
da.Fill(ds);
lblUsername.Text = ds.Tables[0].Rows[0][1].ToString();
txtfname.Text = ds.Tables[0].Rows[0][2].ToString();
txtlname.Text = ds.Tables[0].Rows[0][3].ToString();
txtemail.Text = ds.Tables[0].Rows[0][4].ToString();
}
protected void btnUpdate_Click(object sender, EventArgs e)
{
con.Open();
SqlCommand cmd = new SqlCommand("update UserDetails set FirstName='" + txtfname.Text + "',LastName='" + txtlname.Text + "',Email='" + txtemail.Text + "' where UserId=" + userid, con);
SqlDataAdapter da = new SqlDataAdapter(cmd);
int result= cmd.ExecuteNonQuery();
con.Close();
if(result==1)
{
ScriptManager.RegisterStartupScript(this, this.GetType(), "ShowSuccess", "javascript:Showalert('"+lblUsername.Text+"')", true);
}
}
protected void btnCancel_Click(object sender, EventArgs e)
{
Response.Redirect("~/Default.aspx");
}
}
My requirement is new window should come like pop window as new window with out having url and close button
my database tables is
ColumnName DataType
-------------------------------------------
UserId Int(set identity property=true)
UserName varchar(50)
FirstName varchar(50)
LastName varchar(50)
Email Varchar(50)
There are a host of options in the jQuery field:
jQueryUI's dialog
Wijmo's Dialog
SimpleModal
If you'd already using jQuery, jQueryUI's option may be a good fit. Wijmo is also jQueryUI compatible/friendly (use the same theme CSS class names and patterns), so it's also a good fit.
So it kind of depends on what you want. Something very simple - maybe jQueryUI. Flashy/pretty -- SimpleModal. More complex but jQueryUI-friendly - Wijmo.
Sort listview using column headings in the LayoutTemplate
I am able to sort a basic list view using asp:SqlDataSource and setting the list view property DataSourceID by pointing it to the asp:SqlDataSource ID. I am having an issue when sorting when not using the asp:SqlDataSource and just DataBinding from the code behind.
SqlDataSource Example:
<asp:ListView ID="ContactsListView" DataSourceID="ContactsDataSource" runat="server">
<LayoutTemplate>
<table width="640px" runat="server">
<tr class="header" align="center" runat="server">
<td>
<asp:LinkButton runat="server" ID="SortByFirstNameButton" CommandName="Sort" Text="First Name" CommandArgument="FirstName" />
</LayoutTemplate>
....
</asp:ListView>
<asp:SqlDataSource ID="ContactsDataSource" runat="server"
ConnectionString="<%$ ConnectionStrings:MainConnString %>"
SelectCommand="SELECT * FROM TableName">
</asp:SqlDataSource>
DataBind Example:
<asp:ListView ID="ContactsListView" DataSourceID="ContactsDataSource" runat="server">
<LayoutTemplate>
<table width="640px" runat="server">
<tr class="header" align="center" runat="server">
<td>
<asp:LinkButton runat="server" ID="SortByFirstNameButton" CommandName="Sort" Text="First Name" CommandArgument="FirstName" />
</LayoutTemplate>
....
</asp:ListView>
protected void Page_Load(object sender, EventArgs e)
{
String SQL = "SELECT * FROM Customer";
SqlDataAdapter da= new SqlDataAdapter(SQL, ConnStr);
DataSet ds = new DataSet();
da.Fill(ds);
ContactsListView.DataSource = ds.Tables[0];
ContactsListView.DataBind();
}
Both code samples populate the list view, but the second example data binding does not work for sorting. With the first example, the sorting just works with the added asp:LinkButton in the LayoutTemplate adding the CommandName="sort" and setting the CommandArugment="ColumnName", but it does not work with the second example.
Can anyone please explain why and how to get the sorting working using the code behind DataBind method?
Thanks!
I solved my issue.
I added an event to handle the sorting. The event grabs the command name (Data column) and passes it and the sorting direction into a function which will make another call to the database sort the returned results and rebind to the List View.
I had to create a view state to hold the List View Sort Direction because for some reason, the onsorting event handler kept saying that the sort direction was ascending.
Front End
<asp:ListView ID="ContactsListView" OnSorting="ContactsListView_Sorting" runat="server">
<LayoutTemplate>
<table width="640px" runat="server">
<tr class="header" align="center" runat="server">
<td>
<asp:LinkButton runat="server" ID="SortByFirstNameButton" CommandName="Sort" Text="First Name" CommandArgument="FirstName" />
</LayoutTemplate>
....
</asp:ListView>
Back End
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
BindContacts(string.Empty);
}
}
protected SortDirection ListViewSortDirection
{
get
{
if (ViewState["sortDirection"] == null)
ViewState["sortDirection"] = SortDirection.Ascending;
return (SortDirection)ViewState["sortDirection"];
}
set { ViewState["sortDirection"] = value; }
}
protected void ContactsListView_Sorting(Object sender, ListViewSortEventArgs e)
{
BindContacts(e.SortExpression + " " + ListViewSortDirection.ToString());
// Check the sort direction to set the image URL accordingly.
string imgUrl;
if (ListViewSortDirection == SortDirection.Ascending)
ListViewSortDirection = SortDirection.Descending;
else
ListViewSortDirection = SortDirection.Ascending;
}
private void BindContacts(string sortExpression)
{
sortExpression = sortExpression.Replace("Ascending", "ASC");
sortExpression = sortExpression.Replace("Descending", "DESC");
using (SqlConnection conn = new SqlConnection(_connStr))
{
conn.Open();
using (SqlDataAdapter dAd = new SqlDataAdapter("SELECT * FROM Customer", conn))
{
DataTable dTable = new DataTable();
dAd.Fill(dTable);
// Sort now
dTable.DefaultView.Sort = sortExpression;
// Bind data now
ContactsListView.DataSource = dTable;
ContactsListView.DataBind();
}
conn.Close();
}
}
I guess you could try to add a handler for ListView's Sorting event. There you are given the sorting column and the sort order in the event arguments. This could be easily usable to build a specific query and bind it to the list.
Because depending on the sort expression (which you defined in your markup) SqlDataSource will very likely do something like this (I'm not sure this is exactly what it does) for you behind the scenes:
Expression<Func<DataRow,object>> myExpression = row => row["SortExpressionYouDefinedForTheColumn"];
IEnumerable<DataRow> ex = ds.Tables[0].AsEnumerable().OrderBy(myExpression.Compile());
Or SqlDataSource may be using a DataView to sort the DataTable.
SqlDataSource can do this because by default it uses a DataSet to store the result set (or so says the documentation):
The data retrieval mode identifies how a SqlDataSource control retrieves data from the underlying database.
When the DataSourceMode property is set to the DataSet value, data is
loaded into a DataSet object and stored in memory on the server. This
enables scenarios where user interface controls, such as GridView,
offer sorting, filtering, and paging capabilities..
Since you chose to bind manually to a DataSet, you need to do the "magic" yourself; in other words, you handle the OnSort command, get the sort expression, get your data source again (however you do it, from Session or by calling the database again) and do your sort similarly to the lines shown above and rebind to your Gridview.
I am building an ASP.NET website that allows users to create and take tests. Tests can contain various types of questions (multiple choice, true/false, essay, etc.). Because of the dynamic nature of the tests, I am creating the "Take Test" page with repeaters.
My problem now is: how can I get the user's answers? With a fixed number/type of questions this would be simple, but I'm not sure how to grab answers from items with dynamically created IDs or how to pass a variable number of answers back to my database.
Edit:
I found my answer here.
You can use Request.Form
But Here is Another approach using FindControl and Repeater:
For Each item As RepeaterItem In Me.RptItems.Items
Dim value = CType(item.FindControl("TxtName"), TextBox).Text
Next
you can use FindControl method with each RepeaterItem and find desired control inside it by ID.
ASPX file:
<asp:Repeater ID="RptItems" runat="server">
<HeaderTemplate>
<table>
<tr>
<td>
Name
</td>
</tr>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td>
<asp:TextBox ID="TxtName" runat="server" Text='<%# Eval("Name")%>'></asp:TextBox>
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
If you are using Asp.Net MVC you can reference this article. Model Bind To Collection
If its webforms you can always access each of the inputs submitted via the Request.Form collection.
Here is what I ended up doing for each question type, based on links including this one.
foreach (RepeaterItem item in myRptr.Items)
{
if (item.ItemType == ListItemType.Item || item.ItemType == ListItemType.AlternatingItem)
{
OracleCommand cmd = new OracleCommand();
cmd.Connection = conn;
cmd.CommandText = "myPackage.myProcedure";
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.Parameters.Add("user_id", OracleType.VarChar).Value = Session["UserId"].ToString();
cmd.Parameters.Add("question_id", OracleType.Number).Value = ((HiddenField)item.FindControl("myHidden")).Value;
cmd.Parameters.Add("answer", OracleType.VarChar).Value = ((TextBox)item.FindControl("myTxt")).Text;
cmd.ExecuteNonQuery();
}
}
I have a ListView on my checkout page with an ItemTemplate which build up a table of items ordered by customer. I want to add a total in the footer of the table, I have the following markup:
<asp:ListView ID="lvOrderSummary" runat="server">
<LayoutTemplate>
<table id="tblOrderSummary">
<tr>
<td><b>Title</b></td>
<td><b>Cost</b></td>
</tr>
<asp:PlaceHolder ID="itemPlaceholder" runat="server" />
<tr>
<td><b>Total Cost:</b></td>
<td><%# GetTotalCost().ToString()%></td>
</tr>
</table>
</LayoutTemplate>
<ItemTemplate>
<tr>
<td><%#Eval("Title") %></td>
<td><%#Eval("Cost") %> </td>
</tr>
</ItemTemplate>
</asp:ListView>
I have a server side method called GetTotalCost that return the value I require. The problem I'm having is that this method is never called.
I have also tried and instead of using:
<td><%# GetTotalCost().ToString()%></td>
I've tried using
<td id="tdTotal" runat="server"></td>
---------------
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
TableCell td = ((TableCell)this.FindControl("lvOrderSummary_tdTotal"));
}
}
Check this article for an example how to display a total in the ListView.
Basically you can add a label in the layout template:
<asp:ListView ID="lvOrderSummary" runat="server"
OnPreRender="lvOrderSummary_PreRender" ...>
<LayoutTemplate>
...
<td><asp:Label ID="lblTotalCost" runat="server" Text="Total"/></td>
..
</LayoutTemplate></asp:ListView>
And then you set the label's text in the PreRender event handler:
protected void lvOrderSummary_PreRender(object sender, EventArgs e)
{
Label lbl = lvOrderSummary.FindControl("lblTotalCost") as Label;
lbl.Text = GetTotalCost().ToString();
}
Try
Dim strcon As String = "Data Source=.\SQLEXPRESS;AttachDbFilename=D:\webarticles\App_Data\mydatabase.mdf;Integrated Security=True;User Instance=True"
Dim con As New SqlConnection(strcon)
con.Open()
Dim da As SqlDataAdapter
Dim ds As New DataSet
Dim sqlstring As String = "SELECT * FROM tblstudent "
da = New SqlDataAdapter(sqlstring, con)
da.Fill(ds)
DetailsView1.DataSource = ds.Tables(0)
DetailsView1.DataBind()
Catch ex As Exception
MsgBox("There is some Error")
End Try
Another data handeling control is DetailsView control which gives you the ability to display, delete, edit, insert a single record at a time from its associated data source. The DetailsView control does not support sorting.By default, the DetailsView control displays each field of a record on its own line.