using session variable within sql query - c#

i have an application where a user logs in and can edit his/other's data. however, if the user is an admin, he gets a gridview with all user's records which he can edit. if the user is not an admin, he will just get a listview where he can edit his own data.
when a user logs into the page, his userid, which is in itself also stored in the db, is stored as a session variable in Session["ID"]. now i need to populate the listview with the user's data. i thought it would be good to just query the data based on the Session["ID"] parameter. but i am not sure how to do this.
EDIT:
ok i have little code regarding this as i have no idea how to do it but i will post what i have. first is the method where i set the session variable of the userid:
objda = new SqlDataAdapter("[GetIDOfUser]", objcon);
objda.SelectCommand.CommandType = CommandType.StoredProcedure;
objda.SelectCommand.Parameters.Add("#Username", SqlDbType.VarChar).Value = tbUsername.Text;
objda.SelectCommand.Parameters.Add("#UserPassword", SqlDbType.VarChar).Value = tbPassword.Text;
String id = (string)objda.SelectCommand.ExecuteScalar();
Session["ID"] = id;
this is my markup:
<asp:ListView ID="ListView1" Visible="False" runat="server" DataSourceID="SqlDataSource2"></asp:ListView>
this is the code where i enable the listview:
protected void Page_Load(object sender, EventArgs e)
{
if (Session["UserAuthentication"] == null)
{
Response.Redirect("Login.aspx");
}
if (Session["Benutzerart"].ToString() == Enums.Enumerations.Benutzer.Administrator.ToString())
{
GridView1.Visible = true;
//Set controls for admin
}
if (Session["Benutzerart"].ToString() != Enums.Enumerations.Benutzer.Administrator.ToString())
{
ListView1.Visible = true;
//Set controls for other users
}
}
ok guys i have figured it out:
i just make normal listview as in the code above. only the data source has no selectcommand attribute in the markup. this attribute is set in-code:
if (Session["Benutzerart"].ToString() != Enums.Enumerations.Benutzer.Administrator.ToString())
{
ListView1.Visible = true;
SqlDataSource2.SelectCommand = "SELECT [Titel], [Bezeichnung], [Vorname], [Nachname], [Geburtsdatum], [Geburtsort], [Straße], [Nationalität], [Hausnummer], [PLZ], [Ort], [Land], [Mobil], [UrlaubstageGenommen], [UrlaubstageInsgesamt], [Status], [Benutzerart], [Homepage], [Email], [Festnetz], [Fax], [UrlaubstageRest], [Username], [UserPassword] FROM [Benutzer] WHERE [BenutzerID] = '" + Session["ID"] + "'";
}
markup of datasource:
<asp:SqlDataSource ID="SqlDataSource2" runat="server" ConnectionString="<%$ ConnectionStrings:ConnectionString %>" ></asp:SqlDataSource>

you are binding listview with SqlDataSource, use sqldatasource SelectParameter
<asp:SqlDataSource ID="SqlDataSource2" runat="server"
ConnectionString="<%$ ConnectionStrings:yourConnection %>"
SelectCommand="SELECT * FROM yourTable WHERE userid = #userid">
<SelectParameters>
<asp:SessionParameter Name="userid" SessionField="ID" Type="String" />
</SelectParameters>
</asp:SqlDataSource>

To select data from DB you can create sql data source and bind it to ListView:
SqlDataSource ds = new SqlDataSource();
ds.ConnectionString = yourDBconnectionString;
ds.SelectCommand = "SELECT * FROM records_table WHERE user_id=#user_id";
ds.SelectParameters.Add("user_id", Convert.ToInt32(Session["id"]));
ListView1.DataSource = ds;
ListView1.DataBind();
Then to bind records fields to ListView on aspx page use (just an example):
<%# Eval("recort_title") %>

Related

Update StoredProcedure executes but DB not updated

I've searched around for a while and tried all the different solutions but I can't seem to get the database updated.
I've executed the stored procedure on its own through SSMS and it works fine.
Here's my asp settings:
<asp:SqlDataSource ID="SqlDataSource5" runat="server" ConnectionString="<%$ ConnectionStrings:ConnectionString %>" ProviderName="<%$ ConnectionStrings:ConnectionString.ProviderName %>" UpdateCommand="spProofStamp" UpdateCommandType="StoredProcedure">
<UpdateParameters>
<asp:Parameter Name="sID" Type="String" />
<asp:Parameter Name="UserID" Type="String" />
</UpdateParameters>
</asp:SqlDataSource>
Button:
<dx:LayoutItem Caption="">
<LayoutItemNestedControlCollection>
<dx:LayoutItemNestedControlContainer ID="LayoutItemNestedControlContainer1" runat="server">
<dx:ASPxButton ID="ASPxFormLayout2_E2" OnClick="Button1_Click" runat="server" Text="Validate" AutoPostBack="false">
<ClientSideEvents Click="function(s,e){validate();}" />
</dx:ASPxButton>
</dx:LayoutItemNestedControlContainer>
</LayoutItemNestedControlCollection>
</dx:LayoutItem>
My code behind (I've tried databind and update separately as well).
I've also traced through the values and they're all there, how can I tell if the Update/DataBind works or not? Other Databinds within my code are working fine:
protected void Button1_Click(object sender, EventArgs e)
{
SqlDataSource5.UpdateCommandType = SqlDataSourceCommandType.StoredProcedure;
SqlDataSource5.UpdateCommand = "spProofStamp";
SqlDataSource5.UpdateParameters["sID"].DefaultValue = selectedValue;
SqlDataSource5.UpdateParameters["UserID"].DefaultValue = login.ToUpper();
SqlDataSource5.Update();
SqlDataSource5.DataBind();
}
StoredProcedure:
ALTER PROCEDURE [dbo].[spProofStamp]
#UserID nvarchar(15),
#sID nvarchar(15)
AS
SET NOCOUNT ON
UPDATE [dbo].[ORDER]
SET [USERID] = #UserID,
[DATE] = CURRENT_TIMESTAMP
WHERE ID = #sID
I would like to recommend you to change your method from sqldatasource to code behind, as it makes your code more clear and it is more effective.
You may use the next method:
protected void UpdateDB(string user_id, string sid){
SqlConnection con = new SqlConnection(your_connection_string);
SqlCommand cmd = new SqlCommand("spProofStamp", con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("#USERID", SqlDbType.NVarChar).Value = user_id;
cmd.Parameters.Add("#SID", SqlDbType.NVarChar).Value = sid;
try{
con.Open();
cmd.ExecuteNonQuery();
}
catch(Exception ex){
//process your exception
}
finally{
con.Close();
Response.Redirect(Request.Url.AbsoluteUri); //refresh this page
}
}
And call your method:
UpdateDB(login.ToUpper(), selectedValue);

How to retrieve text from dropdownlist?

I must audit the changes into a database. On most pages this works perfect, as there were just textboxes - however on a page I am working on right now, with dropdownlists, my code isn't working.
<td>
<asp:DropDownList ID="DropDownList4" runat="server" DataSourceID="SqlDatacountry" DataTextField="country_name" DataValueField="country_id">
</asp:DropDownList>
<asp:SqlDataSource ID="SqlDatacountry" runat="server" ConnectionString="<%$ ConnectionStrings:songtypecons %>" SelectCommand="SELECT * FROM [country_detail]"></asp:SqlDataSource>
</td>
code behind:
string sql1 = "selectcust_fname,cust_mname,cust_lname,cust_birthdate,cust_gender,cust_address,cust_contact_num,cust_country,cust_state,cust_city,cust_zip from cust_detail where cust_id ='" + ds.Tables["filldata"].Rows[0].ItemArray[0].ToString() + "' ";
SqlDataAdapter adpt1 = new SqlDataAdapter(sql1, con);
DataSet ds1 = new DataSet();
adpt1.Fill(ds1, "custdata");
if (ds1.Tables["custdata"].Rows.Count > 0)
{
for (int d = 0; d < DropDownList4.Items.Count; d++)
{
if (ds1.Tables["custdata"].Rows[0].ItemArray[7].ToString() == DropDownList4.Items[d].Text)
{
DropDownList4.Items[d].Selected = true;
break;
}
}
}
If I understand your question clearly, you just need to use your code in your ListControl.SelectedIndexChanged event.
Occurs when the selection from the list control changes between posts
to the server.
<asp:DropDownList ID="DropDownList4" runat="server" AutoPostBack="True"
onselectedindexchanged="DropDownList4_SelectedIndexChanged" ...>
</asp:DropDownList>
protected void DropDownList4_SelectedIndexChanged(object sender, EventArgs e)
{
...
}
As I wrote in my comment, you should always use parameterized queries in your sql commands, your code is open for an SQL Injection attacks.

checkboxlist databinding to an entity framework table

I have placed a checkboxlist in a formview object.
I would like to store and load the results of the checkboxlist in a table of an entity framework.
I filled the cbl with values and labels coming from a table that has 2 columns, using the DataSourceID, DataTextField and DataValueField attributes but I can't seem to find how to bind the cbl to the entity framework object in order to store the checked values when the formview is in "EDIT" mode.
Any help would be appreciate. Thanks!
<asp:FormView ID="formView1" runat="server" DataSourceID="Ods1"
Height="203px" Width="495px"
onpageindexchanging="formView1_PageIndexChanging">
<EditItemTemplate>
<asp:CheckBoxList ID="cblProducts" runat="server" RepeatColumns="3"
Width="782px" DataSourceID="SqlDataSource1" DataTextField="ProductName"
DataValueField="ProductCode">
</asp:CheckBoxList>
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:ApplicationServices %>"
SelectCommand="SELECT [ProductCode], [ProductName] FROM [Products]">
</asp:SqlDataSource>
</EditItemTemplate>
</asp:FormView>
<asp:ObjectDataSource ID="Ods1" runat="server"
DataObjectTypeName="WebApplication1.EDM.Emp" DeleteMethod="DeleteEmp"
InsertMethod="CreateNewEmp" OldValuesParameterFormatString="original_{0}"
SelectMethod="GetEmpByEmpId" TypeName="WebApplication1.EDM.EmpLogic"
UpdateMethod="UpdateEmp" OnSelecting="Ods1_Selecting">
<SelectParameters>
<asp:RouteParameter Name="EmpId" RouteKey="EmpId" Type="String" />
</SelectParameters>
</asp:ObjectDataSource>
<asp:FormView ID="formView1" runat="server"
OnItemUpdating="formView1_ItemUpdating" ...>
protected void formView1_ItemUpdating(object sender, FormViewUpdateEventArgs e)
{
var cblProducts = formView1.FindControl("cblProducts") as CheckBoxList;
foreach (ListItem item in cblProducts.Items)
{
if (item.Selected)
{
// Check if item.Value is not in the db for this employee, if so add it
}
else
{
// Check if item.Value is in the db for this employee, if so delete it
}
}
// save
}
You need to do the following;
foreach (ListItem chk in cblProducts.Items)
{
string productId= chk.Value;
if (IsProductAvailable(productId) // this method will basically goes to database and return true of false
chk.Selected = true;
else
chk.Selected = false;
}
private void IsProductAvailable(string productId)
{
string query = "SELECT [ProductId] FROM [Product] ";
query += "WHERE [ProductId] = #ProductId";
DbCommand comm = new DbCommand();
comm.CommandText = query;
DbParameter param = comm.CreateParameter();
param.ParameterName = "#ProductId";
param.Value = productId;
comm.Parameters.Add(param);
DataTable table = comm.ExecuteCommand();
if (table.Rows.Count > 0)
{
return true;
}
else
return false;
}
please modify query and parameters according to your need.

ASP.NET Page does not refresh after running a DELETE SQL Query

I am using VS2005. Currently I have a delete linkButton in my gridview, and if I presses on it to delete a row, the GridView goes empty, and I will have to click on the link again to access the page.
Below is my codefor .aspx:
<asp:GridView ID="GridView1" runat="server" DataSourceID="SqlDataSource1" ondatabound="gv_DataBound" OnSelectedIndexChanged="GridView1_SelectedIndexChanged">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:CheckBox ID="UserSelection" OnCheckedChanged="UserSelector_CheckedChanged" runat="server" />
<asp:LinkButton ID="lnkDelete" runat="server" onclick="lnkDelete_Click" Text="Delete" CommandArgument='<%# Eval("Employee") %>' ></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Below is my code for .cs
protected void lnkDelete_Click(object sender, EventArgs e)
{
LinkButton lnk = (LinkButton)sender;
string stid = lnk.CommandArgument.ToString();
SqlDataSource1.SelectCommand = "DELETE FROM [UserDB]where Employee like '%"+stid+"%'";
SqlDataSource1.DataBind();
}
I have tried assigning my delete query to SqlDataSource1 and select query to source2, but if that's the case, my delete query would not work.
I have also tried using IsPostBack on my PageLoad method, but the GridView goes empty as well after clicking on the delete button.
Currently both of my queries are assigned to SqlDataSource1, and once the query is deleted, the page just go blank, although the query is deleted.
May I know how can I refresh the page or reload the GridView table after the delete query is ran?
Thank you.
Thanks to the help from you guys, the problem is solved. Currently my working code is as follows:
LinkButton lnk = (LinkButton)sender;
string stid = lnk.CommandArgument.ToString();
SqlConnection conn = new SqlConnection("DATA-SOURCE");
string sql = string.Format("DELETE FROM [UserDB] where Employee like '%{0}%'",stid);
SqlCommand cmd = new SqlCommand(sql,conn);
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
SqlDataSource1.SelectCommand = "SELECT * FROM [UserDB]";
SqlDataSource1.DataBind();
Response.Redirect("/Project/UserList.aspx");
I used a sql connection string for the delete query, and sqldatasource for the select query afterwards, finally refreshed the page by using response.redirect. Hope it helped newbies like me who met this error too.
Great thanks to all who provided help
Why are you assigning a DELETE command to the SelectCommand property ?
Just run the DELETE on a separate SqlCommand instance with ExecuteNonQuery and commit. Another option is to use DeleteCommand of the existing SqlDataSource.
Another point:
The way you build the DELETE SQL is vulnerable to a serious security problem called SQL injection - easiest and best way to avoid that is to use bind parameters!
First you should read up on what databinding in ASP.NET can do for you. (Then you won't have to write any codebehind for this scenario.)
Example: (Not tested in VS)
You should use the SqlDataSource's DeleteCommand to set the delete command and its parameters like this:
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="..."
SelectCommand="..."
DeleteCommand="DELETE FROM [UserDB] WHERE Employee=#Employee">
<DeleteParameters>
<asp:Parameter Name="Employee" />
</DeleteParameters>
</asp:SqlDataSource>
And the on the GridView, you should set the DataKeyNames property, and inside the ItemTemplate's Linkbutton you should set the CommandName property to "Delete" as shown below:
<asp:GridView ID="GridView1" runat="server" DataSourceID="SqlDataSource1"
ondatabound="gv_DataBound" DataKeyNames="Employee"
OnSelectedIndexChanged="GridView1_SelectedIndexChanged">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:CheckBox ID="UserSelection" runat="server"
OnCheckedChanged="UserSelector_CheckedChanged" />
<asp:LinkButton ID="lnkDelete" runat="server"
onclick="lnkDelete_Click" Text="Delete"
CommandArgument='<%# Eval("Employee") %>'
CommandName="Delete" ></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Try like this
protected void lnkDelete_Click(object sender, EventArgs e)
{
LinkButton lnk = (LinkButton)sender;
string stid = lnk.CommandArgument.ToString();
SqlConnection conn = new SqlConnection(<put your connectionstring here>);
string sql = string.Format("DELETE FROM [UserDB] where Employee like '%{0}%'",stid);
SqlCommand cmd = new SqlCommand(sql,conn);
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
BindTheGridView();
//or you can use SelectCommand of your SqlDataSource1 and can bind again simply.
}
EDIT:
public void BindTheGridView()
{
SqlConnection conn = new SqlConnection(Connstring);
string sql = "Select * from [UserDB]";
SqlCommand cmd = new SqlCommand(sql, conn);
conn.Open();
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataTable dtb = new DataTable();
da.Fill(dtb);
conn.Close();
SqlDataSource1.DataSource = dtb;
SqlDataSource1.DataBind();
}
And you can call this for any time to bind the values.
It's wrong to run change operation (DELETE in your example) as a SelectCommand. SelectCommand must be used as it called - only to SELECTs.
Run the DELETE query separately, then run a SELECT command to show the relevant records for the grid.
SqlDataSource1.SelectCommand = "DELETE FROM [UserDB]where Employee like '%"+stid+"%'";
SqlDataSource1.DataBind();
Why are you using Delete query in SelectCommand. The query is open to SqlInjection attack. I would have used a stored procedure and verify the parameter before passing it to the procedure.
Moreover the Grid won't show/bind any data as your code is not return any data back. It is just deleting the data.
I guess you can do a gridview.DataBind() instead of sqlDatasource.databind. The gridviews databind internally performs the sqldatasource databind and also refreshes the gridview.

Passing gridview values(data) to textbox fields

For my view,
In the page:
1) I have a gridview with the select hyperlink in it. The gridview data is from the SQLDataSource.
2) And, I also have a few textboxes (abt 5) - not in the gridview.
What I would like to do is to use the select hyperlink to select the row that i want to edit. And when i click select, the data in the row should come out to their respective textboxes.
How do I go about doing this?
Grid views have inline record editing support, you can enable this functionality by setting the AutoGenerateEditButton property to true. You must specify the name of a stored procedure or SQL query in the UpdateCommand property, this is used to update data in the underlying data base.
From MSDN:
<asp:gridview id="CustomersGridView"
datasourceid="CustomersSqlDataSource"
autogeneratecolumns="true"
autogeneratedeletebutton="true"
autogenerateeditbutton="true"
datakeynames="CustomerID"
runat="server">
</asp:gridview>
<asp:sqldatasource id="CustomersSqlDataSource"
selectcommand="Select [CustomerID], [CompanyName], [Address], [City], [PostalCode], [Country] From [Customers]"
updatecommand="Update Customers SET CompanyName=#CompanyName, Address=#Address, City=#City, PostalCode=#PostalCode, Country=#Country WHERE (CustomerID = #CustomerID)"
deletecommand="Delete from Customers where CustomerID = #CustomerID"
connectionstring="<%$ ConnectionStrings:NorthWindConnectionString%>"
runat="server">
</asp:sqldatasource>
See here for the full example code.
Wireup OnSelectedIndexChanged event:
ASPX:
<asp:GridView id="gvTest" OnSelectedIndexChanged="gvTest_SelectedIndexChanged"
..........></asp:GridView>
<asp:TextBox id="text1" runat="server"/>
Code:
protected void gvTest_SelectedIndexChanged(object sender, EventArgs e)
{
//get currently selected row
var r =gvTest.Rows[gvTest.SelectedIndex];
//THIS WAY YOU CAN GET TEXT FROM ALL COLUMNS
text1.Text = r.Cells[r.Cells.Count - 1].Text;
}
protected void gvofertas_RowCommand(object sender, GridViewCommandEventArgs e)
{
try
{
gvofertas.SelectedIndex = Convert.ToInt32(e.CommandArgument);
switch (e.CommandName)
{
case "ELIMINAR":
{
//lblSolEliminar.Text = "Usuario: " + Convert.ToString(gvCorreos.DataKeys[gvCorreos.SelectedIndex].Values["etspcpusrn"]);
mpeEliminar.Show();
break;
}
case "EDITAR":
{
Limpiar();
Session["NROOFERTAACTUALIZA"] = Convert.ToString(gvofertas.DataKeys[gvofertas.SelectedIndex].Values["efophcodi"]).Trim();
txtDescripcion.Text = Convert.ToString(gvofertas.DataKeys[gvofertas.SelectedIndex].Values["efophdesc"]).Trim();
StartDate.Text= Convert.ToDateTime(gvofertas.DataKeys[gvofertas.SelectedIndex].Values["efophfini"]).ToShortDateString();
EndDate.Text = Convert.ToDateTime(gvofertas.DataKeys[gvofertas.SelectedIndex].Values["efophffin"]).ToShortDateString();
txtRango1Localidades1Agregar.Text = Convert.ToString(gvofertas.DataKeys[gvofertas.SelectedIndex].Values["efophloci"]).Trim();
txtRango2Localidades1Agregar.Text = Convert.ToString(gvofertas.DataKeys[gvofertas.SelectedIndex].Values["efophlocf"]).Trim();
this.mpeAgregar.Show();
BtnGuardar2.Text = "Actualizar";
txtDescripcion.Focus();
break;
}
}
catch (Exception ex)
{
ucMsje.RegistrarMensajeCliente("dvMsjeError", F.m_strImagenError, ex.Message);
}

Categories