DataGridView + SqlData Source Madness - asp.net

I am trying to populate data from a table created in aspnetdb.mdf that has game data stored in it, which has a uniqueidentifier that is UserId that is the users Asp Membership UserId. I want to select the users data from the table using a SqlDataSource and populate it into the DataGridView.
I have read thread after thread, and MSDN documentation, and for the life of me I can't get this joker to work. The DataGridView isn't even displayed, just a blank screen. In the designer I can see the columns I wan't to select.. Here is the code. If anyone has an idea, answer, or anything I would greatly appreciate it.
I have tried switching the parameter data types and just about anything I can think of, but that didn't work
In code behind:
protected void userGameData_Selecting(object sender, SqlDataSourceSelectingEventArgs e)
{
MembershipUser User = Membership.GetUser();
object UserGUID = User.ProviderUserKey;
userGameData.SelectParameters["UserId"].DefaultValue = UserGUID.ToString();
}
in aspx
<form id="frm" runat="server">
<asp:SqlDataSource ID="userGameData" runat="server" ConnectionString="<%$ ConnectionStrings:ConnectionString %>" SelectCommand="SELECT [cycleday], [playerwins], [housewins], [gametype], [gamedate], [phase] FROM [GameData] WHERE ([UserId] = #UserId)" OnSelecting="userGameData_Selecting">
<SelectParameters>
<asp:Parameter Name="UserId" Type="String" />
</SelectParameters>
</asp:SqlDataSource>
<asp:GridView ID="rawGameResults" runat="server" AutoGenerateColumns="False" DataSourceID="userGameData">
<Columns>
<asp:BoundField DataField="cycleday" HeaderText="cycleday" SortExpression="cycleday" />
<asp:BoundField DataField="playerwins" HeaderText="playerwins" SortExpression="playerwins" />
<asp:BoundField DataField="housewins" HeaderText="housewins" SortExpression="housewins" />
<asp:BoundField DataField="gametype" HeaderText="gametype" SortExpression="gametype" />
<asp:BoundField DataField="gamedate" HeaderText="gamedate" SortExpression="gamedate" />
<asp:BoundField DataField="phase" HeaderText="phase" SortExpression="phase" />
</Columns>
</asp:GridView>
</form>

Maybe the bind is not working from the markup, I would try it from code-behind
string sql = "SELECT [cycleday], [playerwins], [housewins], [gametype], [gamedate], [phase] FROM [GameData] WHERE UserId = (SELECT [UserId] FROM aspnet_users WHERE UserName = '" & User.Identity.Name & "')";
using (SqlConnection myConnection = new SqlConnection(connectionString))
{
using (SqlCommand myCommand = new SqlCommand(sql, myConnection))
{
myConnection.Open();
using (SqlDataReader myReader = myCommand.ExecuteReader())
{
DataTable myTable = new DataTable();
myTable.Load(myReader);
myConnection.Close();
YourDataGridView.DataSource = myTable;
YourDataGridView.DataBind();
}
}
}
Set connectionString to the CS you are using in your project :)

Related

How to update database in SQL Server when I have checkbox in gridview?

I tried to make a message board.
After someone leave message, manager can check message context can be show for others or not.
I use gridView to connect to my SQL Server data, and there is a checkbox in the gridview.
If I checked checkbox, and click "sent" button, SQL Server data will be updated.
If I would like to update checkbox result into SQL Server data, what should I do?
This is my aspx
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="id" OnRowDeleting="GridView1_RowDeleting">
<Columns>
<asp:TemplateField HeaderText="check or not" SortExpression="replyCheck">
<EditItemTemplate>
<asp:CheckBox ID="CheckBox1" runat="server" Checked='<%# Bind("replyCheck") %>' />
</EditItemTemplate>
<ItemTemplate>
<asp:CheckBox ID="CheckBox2" runat="server" Checked='<%# Bind("replyCheck") %>' Enabled="True" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<br/>
<asp:Button ID="Button1" runat="server" Text="sent" OnClick="Button1_Click"/>
And this is my aspx.cs - if I use foreach, it can't update into my database
protected void Button1_Click(object sender, EventArgs e)
{
var id = GridView1.DataKeys.ToString();
foreach (GridViewRow row in GridView1.Rows)
{
CheckBox reply = (row.Cells[0].FindControl("CheckBox2") as CheckBox);
if (reply.Checked)
{
SqlConnection sqlConnection = new SqlConnection(getsql);
sqlConnection.Open();
SqlCommand cmd = new SqlCommand($"UPDATE reply SET replyCheck ='1' WHERE (id = {id})", sqlConnection);
cmd.ExecuteNonQuery();
sqlConnection.Close ();
DataBind();
}
}
}
If I use for, it showed error about "datakey array"
protected void Button1_Click(object sender, EventArgs e)
{
var id = GridView1.DataKeys.ToString();
int messageCheck, displayCheck;
SqlConnection sqlConnection = new SqlConnection(getsql);
sqlConnection.Open();
for (int i = 0; i < GridView1.Rows.Count; i++)
{
CheckBox message = (CheckBox)GridView1.Rows[i].FindControl("CheckBox2");
if (message.Checked == true)
{
messageCheck = 1;
SqlCommand cmd1 = new SqlCommand($"UPDATE reply SET replyCheck = {messageCheck} WHERE (id = {id})", sqlConnection);
cmd1.ExecuteNonQuery();
}
else
{
messageCheck = 0;
SqlCommand cmd2 = new SqlCommand($"UPDATE reply SET replyCheck = {messageCheck} WHERE (id = {id})", sqlConnection);
cmd2.ExecuteNonQuery();
}
}
sqlConnection.Close();
}
Without javascript, how could I do it?
Thanks for you all
Ok, the way this works is that datafields (non templated columns) in the GV use the cells[] collection.
However, for templated columns, we have to use find control.
And also we will use the data keys feature, as that lets us have/use/work with the database PK row ID, but NOT have to display in the markup/grid for users.
Ok, so here is a GV with both datafiles (the cells()), and also check box.
We will select the check boxes, and then with a save button, send changes back to database.
So, our markup:
<div style="width:50%;padding:25px">
<asp:GridView ID="GVHotels" runat="server" class="table borderhide"
AutoGenerateColumns="false" DataKeyNames="ID">
<Columns>
<asp:BoundField DataField="FirstName" HeaderText="FirstName" />
<asp:BoundField DataField="LastName" HeaderText="LastName" />
<asp:BoundField DataField="City" HeaderText="City" />
<asp:BoundField DataField="HotelName" HeaderText="HotelName" HeaderStyle-Width="200" />
<asp:BoundField DataField="Description" HeaderText="Description" />
<asp:TemplateField HeaderText="Smoking" ItemStyle-HorizontalAlign="Center" >
<ItemTemplate>
<asp:CheckBox ID="chkSmoking" runat="server"
Checked='<%# Eval("Smoking") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Balcony" ItemStyle-HorizontalAlign="Center" >
<ItemTemplate>
<asp:CheckBox ID="chkBalcony" runat="server"
Checked='<%# Eval("Balcony") %>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:Button ID="cmdSave" runat="server" Text="Save changes" CssClass="btn"/>
</div>
And now our code to fill out above could be say this:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
LoadGrid();
}
void LoadGrid()
{
using (SqlConnection con = new SqlConnection(Properties.Settings.Default.TEST4))
{
using (SqlCommand cmdSQL =
new SqlCommand("SELECT * from tblHotels ORDER BY HotelName ", con))
{
con.Open();
GVHotels.DataSource = cmdSQL.ExecuteReader();
GVHotels.DataBind();
}
}
}
And now we see this:
Now, there is two ways we can update the database. We could in fact update using a datatable, and in one whole shot upate the datbase.
but, we just loop the GV, and execute updates. (if I have time, I'll try and post the 2nd more cool approach).
So, our button to update/save changes (for check boxes). Could be this:
protected void cmdSave_Click(object sender, EventArgs e)
{
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
conn.Open();
string strSQL = "UPDATE tblHotels Set Smoking = #S, Balcony = #B " +
"WHERE ID = #ID";
foreach (GridViewRow gRow in GVHotels.Rows)
{
CheckBox cSmoke = (CheckBox)gRow.FindControl("chkSmoking");
CheckBox cBlacony = (CheckBox)gRow.FindControl("chkBalcony");
int PKID = (int)GVHotels.DataKeys[gRow.RowIndex]["ID"];
using (SqlCommand cmdSQL = new SqlCommand(strSQL, conn))
{
cmdSQL.Parameters.Add("#S", SqlDbType.Bit).Value = cSmoke.Checked;
cmdSQL.Parameters.Add("#B", SqlDbType.Bit).Value = cBlacony.Checked;
cmdSQL.Parameters.Add("#ID", SqlDbType.Int).Value = PKID;
cmdSQL.ExecuteNonQuery();
}
}
}
}
Note how we use row index to get the PK row ID. NOTE the DataKeys setting for the GV. This allows you to use/have/enjoy use of the database PK row ID (named "ID" in this code example), and NOT have to display/include the PK in the GV display.
Note that you would continue to use cells() collection for NON templated columns. But for any templated column - you have to use FindControl on that row, pluck out the control, and then you can have at it in regards to that control value.
We could also pull each GV row into a data table, and execute ONE datatable update into the database. But, as the above code shows - we actually keep the connection open for the update - and thus not a big deal either way.
Kindly check with this code
Protected Sub Button1_Click(sender As Object, e As EventArgs)
For Each row In GridView1.Rows
Dim chk As CheckBox = row.FindControl("CheckBox2")
If chk.Checked Then
'sql update query
Else
End If
Next
End Sub

SqlDataSource won't retrieve logged in user's data from database?

I tried retrieving the user's data based on the logged in UserId, but no progress. Any suggestions?
protected void SqlDataSource1_Selecting(object sender, SqlDataSourceSelectingEventArgs e)
{
// Get a reference to the currently logged on user
MembershipUser currentUser = Membership.GetUser();
// Determine the currently logged on user's UserId value
Guid currentUserId = (Guid)currentUser.ProviderUserKey;
// Assign the currently logged on user's UserId to the #UserId parameter
e.Command.Parameters["#UserId"].Value = currentUserId;
}
And this is the SqlDataSource
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString='<%$ ConnectionStrings:NaviConnectionString %>'
SelectCommand="SELECT [UserId], [FirstName], [LastName] FROM [UserProfiles] WHERE ([UserId] = #UserId)">
<SelectParameters>
<asp:Parameter Name="UserId" Type="String"></asp:Parameter>
</SelectParameters>
</asp:SqlDataSource>
And this is the GridView
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKFFeyNames="UserId" DataSourceID="SqlDataSource1"
EmptyDataText="There are no data records to display."
DataKeyNames="UserId">
<Columns>
<asp:BoundField DataField="UserId" HeaderText="UserId" SortExpression="UserId" />
<asp:BoundField DataField="FirstName" HeaderText="FirstName" SortExpression="FirstName" />
<asp:BoundField DataField="LastName" HeaderText="LastName" SortExpression="LastName" />
</Columns>
</asp:GridView>
There are no data records to display.
However, when I execute the code in query builder, it works.
So I need to get the UserId manually from the database.
Then go to the query builder then execute then paste the userid in to the value of UserID.
Then it displays the correct data based on the UserId:
I also tried changing it to this:
<SelectParameters>
<asp:Parameter Name="UserId" Type="Empty" DbType="Guid"></asp:Parameter>
</SelectParameters>
You should set a break point and see if currentUserId is populated. I believe that it is. If so, then retrieving the UserId is not the problem, but instead the problem is setting the parameter value or selecting the data.
I think you need to change the type of your parameter from string to Guid
<SelectParameters>
<asp:Parameter Name="UserId" Type="Guid"></asp:Parameter>
</SelectParameters>
Just Change This:
protected void SqlDataSource1_Selecting(object sender, SqlDataSourceSelectingEventArgs e)
{
// Get a reference to the currently logged on user
MembershipUser currentUser = Membership.GetUser();
// Determine the currently logged on user's UserId value
Guid currentUserId = (Guid)currentUser.ProviderUserKey;
// Assign the currently logged on user's UserId to the #UserId parameter
e.Command.Parameters["#UserId"].Value = currentUserId.ToString();
}
in parameter types there is no guid option. (Also in above codes sql data source has not been set SqlDataSource1_Selecting.) How could it be answer? Just declare parameter name and its ok.
<asp:Parameter Name="UserId"></asp:Parameter>

how can i access string variable value of .aspx.cs file in .aspx file

i m getting a string value regression as regression = (Session["Regression"]).ToString(); in .aspx.cs file then i want to use this value in .aspx file in SelectCommand of SqlDataSource property as below
SelectCommand="SELECT [issue_oid], [issue_num], [regression],
[status], [tested_by], [tested_on], [patch_name], [arrived_on], [previous_info], [comment], [is_duplicate] FROM [itt_monthly_patch_issue_list] where status='Not Tested' and `regression='<%#regression%>'"`
.aspx.cs file page_load method is as below
protected void Page_Load(object sender, EventArgs e)
{
if ((Session["UserName"].ToString()) == string.Empty)
{
Server.Transfer("regressionType.aspx");
}
regression = (Session["Regression"]).ToString();
usrname = (Session["UserName"]).ToString();
DataBind();
}
please suggest me how can i do this?
thanks in advance...
You can you Session Variable's value in your SQLDatasource. Like this Example.
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:testDatabaseConnectionString %>"
SelectCommand="SELECT * FROM [UserTable] WHERE ([userID] = #UserID)">
<SelectParameters>
<asp:SessionParameter Name="UserID" SessionField="UserID" Type="Int32" />
</SelectParameters>
</asp:SqlDataSource>
let us know any other concerns on this..
add Session paramter to your sql Datasource like this
<asp:SqlDataSource SelectCommand="SELECT [issue_oid], [issue_num], [regression],
[status], [tested_by], [tested_on], [patch_name], [arrived_on], [previous_info], [comment], [is_duplicate] FROM [itt_monthly_patch_issue_list] where status='Not Tested' and `regression='<%#regression%>'"`>
<SelectParameters>
<asp:SessionParameter SessionField="Regression" Name="ParameterName" Type="String" />
</SelectParameters>
</asp:SqlDataSource>
Try this:
SelectCommand="SELECT [issue_oid], [issue_num], [regression],
[status], [tested_by], [tested_on], [patch_name], [arrived_on], [previous_info], [comment], [is_duplicate] FROM [itt_monthly_patch_issue_list] where status='Not Tested' and `regression='<%=ReturnRegression()%>'"`
In codebehind:
string regression=null;//Before Page_Load
protected string ReturnRegression()
{
//Write logic here to prevent null being returned
return regression;
}
try this:
public StringBuilder regression = new StringBuilder();
regression.Append((Session["Regression"]).ToString());
Then in the .aspx page (in the selct command), you can use "regression" as:
<% =regression %>

Grab query results from SqlDataSource and store as string

I have a SQL query that will result in one string. Rather than bind a gridview, listview, etc to it and have a single lonely label inside, I just want to store the string (it'll eventually get used later elsewhere). For the life of me I cannot figure this out.
<asp:SqlDataSource ID="SqlDataSource3" runat="server" ConnectionString="<%$ ConnectionStrings:ConnectionString %>"
SelectCommand="select [title] from [books]
where([Genre]=#Genre)
OnSelected="SqlDataSource3_Selected">
<SelectParameters>
<asp:Parameter Name="Title" Direction="ReturnValue" Type="String" />
<asp:ControlParameter ControlID="DropDownList1" Name="genre"
PropertyName="SelectedValue" />
</SelectParameters>
</asp:SqlDataSource>
protected void SqlDataSource3_Selected(object sender, SqlDataSourceStatusEventArgs e)
{
string sqlreturnString = Convert.ToString(e.Command.Parameters["#Title"].Value);
Label3.Text = sqlreturnString;
}
All this does is spit out '0' when I want it to display the title. If I change ["#Title"] to [1], it'll display the Genre. Right now there are only four books, each with a unique genre.
Add a button and write this code in the handler of button's click.
DataSourceSelectArguments sr = new DataSourceSelectArguments();
DataView dv =(DataView) SqlDataSource3.Select(sr);
if(dv.Count!=0)
Label1.Text = dv[0][0].ToString();
I encountered this same issue also when doing C# and ASP.NET, it would be really nice to have a method that dumps out a string of the text results of the query in a SQLDataSource or an AccessDatasource. Until then, Here is an example of the solution I found that works very well:
AccessDataSource MyDataSource = new AccessDataSource("~/App_Data/MyDB.mdb",
"SELECT Name FROM Employees");
DataView MyView = (DataView) MyDataSource.Select(DataSourceSelectArguments.Empty);
lblResults.Text = MyView[0][1].ToString();
This example will also work with SqlDataSource objects.

How do I move this sample aspx code to aspx.cs (to implement code behind)?

I have a dropdownlist which is populated with data from an SQL db. This is what I might have in the aspx file. How do I move (as much as possible) the code from the aspx file to the aspx.cs file to implement the code behind technique?
I mean at least the SELECT portion.
Thanks.
<asp:DropDownList ID="DropDownList1" ... runat="server"/>
...
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:Pubs %>"
SelectCommand="SELECT [au_id], [au_lname], [au_fname], [state] FROM [authors] WHERE [state] = #state">
<SelectParameters>
<asp:ControlParameter Name="state" ControlID="DropDownList1" PropertyName="SelectedValue" />
</SelectParameters>
</asp:SqlDataSource>
suppose you are binding a grid with data source SqlDataSource1 then you can catch SelectedIndexChanged event in codebehind and get data to bind the grid like this:
ASPX file:
<asp:DropDownList ID="DropDownList1" runat="server"
OnSelectedIndexChanged="ddlChanged" />
C# (codebehind):
protected void ddlChanged(object sender, EventArgs e)
{
var cs=..;//get connection string
using(var con=new SqlConnection(cs))
{
using(var com=new SqlCommand(con))
{
com.Open();
com.CommandType = CommandType.Text;
com.CommandText="SELECT [au_id], [au_lname], [au_fname], [state]
FROM [authors] WHERE [state] = #state";
var state=....;//GET VALUE OF STATE FROM DROPDOWN
var p = com.Parameters.Add("#state");//set other properties
p.Value = state;
using(var adptr=new SqlDataAdapter(com))
{
var dtb=new DataTable();
adptr.Fill(dtb);
grid.DataSource=dtb;
grid.DataBind();
}
}
}
}
The SelectCommand is a property of the datasource object you are using. These can be applied in the code behind as needed, but you may want to do it in an overridden Init page function as this might be used quite early on in the asp.net page life cycle. for eg, although I'm not sure exactly where.
protected override OnInit(object sender, EventArgs e)
{
dsMySource.SelectCommand = "SELECT [au_id], [au_lname], [au_fname], [state] FROM [authors] WHERE [state] = #state"
}
You are also going to have to make sure the #state parameter is used correctly in the code behind as well, this can be accessed also as a property (dsMySource.SelectParameters).

Resources