ASP.NET, VB.NET, and Database Issue - asp.net

I am trying to learn how to do this .NET frameworks for my job and what not..... I can't figure why it isn't working.
Error occurs here:
myCommand.Connection.Open()
I am assuming it is because of how I am doing....
Dim idbox As TextBox = E.Item.Cells(numCols - 1).Controls(0)
myCommand.Parameters("#Id").Value = Integer.Parse(idbox.Text)
Source:
<%# Import Namespace="System.Data" %>
<%# Import Namespace="System.Data.SqlClient" %>
<%# Import Namespace="System.Data.OleDb" %>
<html>
<script language="VB" runat="server">
Dim myConnection As SqlConnection
' Create a connection to the "pubs" SQL database located on the
' local computer.
Sub Page_Load(Src As Object, E As EventArgs)
If Session("Admin") <> True Then
Response.Redirect("login.aspx")
Else
Dim myConnection As SqlConnection = New SqlConnection("CONNECTION INFO")
' Determine whether this page is a postback. If it is not a
' postback, call BindGrid.
If Not IsPostBack Then
Dim dbconn As OleDbConnection
Dim sql As String
Dim dbcomm As OleDbCommand
Dim dbread As OleDbDataReader
dbconn = New OleDbConnection("CONNECTION INFO")
dbconn.Open()
sql = "SELECT Name FROM TestData"
dbcomm = New OleDbCommand(sql, dbconn)
dbread = dbcomm.ExecuteReader()
DropDownList1.Items.Clear()
While dbread.Read
DropDownList1.Items.Add(dbread(0))
End While
dbread.Close()
dbconn.Close()
BindGrid()
End If
End If
End Sub
' Create an index to the DataGrid row that is clicked and
' call BindGrid.
Sub MyDataGrid_Edit(sender As Object, E As DataGridCommandEventArgs)
MyDataGrid.EditItemIndex = CInt(E.Item.ItemIndex)
BindGrid()
End Sub
' Cancel resets the index to the row's previous settings.
Sub MyDataGrid_Cancel(sender As Object, E As DataGridCommandEventArgs)
MyDataGrid.EditItemIndex = -1
BindGrid()
End Sub
' When the Update link is clicked, build a SQL UPDATE command,
' connect to the database, update the row's information in the
' database, and rebind the DataGrid to show the updated information.
Public Sub MyDataGrid_Update(sender As Object, _
E As DataGridCommandEventArgs)
Dim updateCmd As String = "UPDATE TestData SET AdoptedNum = #AdoptedNum, PrecinctNum = #PrecinctNum WHERE Id = #Id"
Dim myCommand As SqlCommand = New SqlCommand(updateCmd, myConnection)
myCommand.Parameters.Add(New SqlParameter("#Name", SqlDbType.VarChar))
myCommand.Parameters.Add(New SqlParameter("#PrecinctNum", SqlDbType.Int))
myCommand.Parameters.Add(New SqlParameter("#AdoptedNum", SqlDbType.Int))
myCommand.Parameters.Add(New SqlParameter("#Id", SqlDbType.Int))
' Initialize the SqlCommand "#ID" parameter to the ID of the row
' that must be clicked.
Dim numCols As Integer = E.Item.Cells.Count
Dim i As Integer
Dim colvalue As String
Dim txtBox As TextBox
Dim idbox As TextBox = E.Item.Cells(numCols - 1).Controls(0)
myCommand.Parameters("#Id").Value = Integer.Parse(idbox.Text)
' Create an array of column names.
Dim cols() As String = {"#Name", "#PrecinctNum", "#AdoptedNum", "#Id"}
' Skipping the first, second, and last columns, iterate through the
' columns, checking for empty values. If an empty value is found,
' display a message box. Also initialize the SqlCommand
' parameter values.
For i = 2 To numCols - 1
txtBox = E.Item.Cells(i).Controls(0)
colvalue = txtBox.Text
If (i < numCols And colvalue = "") Then
Message.InnerHtml = "ERROR: Null values not allowed for " _
& "Author ID, Name or Phone"
Message.Style("color") = "red"
Exit Sub
End If
myCommand.Parameters(cols(i - 1)).Value = colvalue
Next i
' Connect to the database and update the information.
myCommand.Connection.Open()
' Test whether the data was updated, and display the
' appropriate message to the user.
Try
myCommand.ExecuteNonQuery()
Message.InnerHtml = "<b>Record Updated.</b><br>"
MyDataGrid.EditItemIndex = -1
Catch ex As SqlException
If ex.Number = 2627 Then
Message.InnerHtml = "ERROR: A record already exists" _
& " with the same primary key"
Else
Message.InnerHtml = "ERROR: Could not update record," _
& " please ensure the fields are correctly filled out."
Message.Style("color") = "red"
End If
End Try
' Close the connection.
myCommand.Connection.Close()
' Rebind the DataGrid to show the updated information.
BindGrid()
End Sub
' The BindGrid procedure connects to the database and implements
' a SQL SELECT query to get all the data in the "Authors" tablea.
Public Sub BindGrid()
Dim myConnection As SqlConnection = _
New SqlConnection("CONNECTION INFO")
Dim myCommand As SqlDataAdapter = New SqlDataAdapter("SELECT *" _
& " FROM TestData WHERE Name='" & DropDownList1.SelectedValue & "'", myConnection)
Dim ds As DataSet= New DataSet()
myCommand.Fill(ds)
MyDataGrid.DataSource = ds
MyDataGrid.DataBind()
End Sub
Protected Sub MyDataGrid_SelectedIndexChanged(sender As Object, e As System.EventArgs)
End Sub
Sub DropDownList1_SelectedIndexChanged(sender As Object, e As EventArgs)
BindGrid()
End Sub
</script>
<body style="font: 10pt verdana">
<form id="Form1" runat="server"><center>
<h3><font face="Verdana">Updating a Row of Data.</font></h3>
<span id="Message" EnableViewState="false"
style="font:arial 11pt;" runat="server"/><p>
<asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="True" OnSelectedIndexChanged="DropDownList1_SelectedIndexChanged">
</asp:DropDownList>
<ASP:DataGrid id="MyDataGrid" runat="server"
Width="800"
BackColor="#ccccff"
BorderColor="black"
ShowFooter="false"
CellPadding=3
CellSpacing="0"
Font-Name="Verdana"
Font-Size="8pt"
HeaderStyle-BackColor="#aaaadd"
OnEditCommand="MyDataGrid_Edit"
OnCancelCommand="MyDataGrid_Cancel"
OnUpdateCommand="MyDataGrid_Update"
>
<Columns>
<ASP:EditCommandColumn EditText="Edit" CancelText="Cancel"
UpdateText="Update"/>
</Columns>
</ASP:DataGrid>
</center>
</form>
</body>
</html>

I suspect the problem is you define but never initialize the instance variable myConnection. You define and instantiate a local variable of the same name within the Page_Load function, but that is a distinct and different object than your instance variable.
In your Page_Load, if you change this:
Dim myConnection As SqlConnection = New SqlConnection("CONNECTION INFO")
to this:
myConnection As SqlConnection = New SqlConnection("CONNECTION INFO")
then your instance variable should be initialized and ready for use in your MyDataGrid_Update event handler.

Did this even compile? This wont work because your code has a bug.
SqlCommand won't support myCommand.Connection.Open()

Related

How to get values from an object in sql query in asp.net vb.net

I want to run a select command and I've a dropdownlist populated with database table names. How to write the select command? Here is my code
Dim da As New OdbcDataAdapter("select table_name from INFORMATION_SCHEMA.tables WHERE TABLE_TYPE = 'BASE TABLE' and table_schema='public'", dbcon.con)
Dim dt As New DataTable
da.Fill(dt)
ddltablename.DataSource = dt
ddltablename.DataTextField = "table_name"
ddltablename.DataValueField = "table_name"
ddltablename.DataBind()
End Sub
Protected Sub btndump_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btndump.Click
Dim da As New OdbcDataAdapter("select * from ddltablename.SelectedItem.tostring", dbcon.con)
Dim ds As New DataSet
da.Fill(ds)
End Sub
Sure, lets drop in your combo box, and then a gridview.
like this:
<asp:DropDownList ID="cboTables" runat="server" Height="31px" Width="179px"
DataTextField ="table_name"
DataValueField ="table_name" Rows="50" >
</asp:DropDownList>
<asp:Button ID="cmdShowTables" runat="server" Text="Show Selected table" Width="175px" style="margin-left:25px"/>
<br />
<br />
<asp:GridView ID="GridView1" runat="server"></asp:GridView>
And our code can thus be:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
Dim strSQL As String =
"SELECT table_name from INFORMATION_SCHEMA.tables " &
"WHERE TABLE_TYPE = 'BASE TABLE' ORDER BY table_name"
cboTables.DataSource = MyRst(strSQL)
cboTables.DataBind()
End If
End Sub
Protected Sub cmdShowTables_Click(sender As Object, e As EventArgs) Handles cmdShowTables.Click
Dim rst As New DataTable
rst = MyRst("SELECT * from " & cboTables.SelectedItem.Value)
'GridView1.DataSource
GridView1.DataSource = rst
GridView1.DataBind()
End Sub
Function MyRst(strSQL As String) As DataTable
Dim rstData As New DataTable
Using conn As New OdbcConnection(My.Settings.TEST3ODBC)
Using cmdSQL As New OdbcCommand(strSQL, conn)
conn.Open()
rstData.Load(cmdSQL.ExecuteReader)
End Using
End Using
Return rstData
End Function
Output:
Or you can say do this:
Dim rst As New DataTable
rst = MyRst("SELECT * from " & cboTables.SelectedItem.Value)
For Each OneRow as DataRow in rst.rows
debug.print ("Hotel Name = " & OneRow("HoteName").ToString())
Next
Probably something like this:
Protected Sub btndump_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btndump.Click
Dim tableName = ddltablename.SelectedItem.ToString();
' It would be prudent to create a function to verify table names against a
' whitelist before sending it, since generating a sql command
' using string concatenation carries the risk of sql injection
Dim da As New OdbcDataAdapter("select * from " & tableName & ";", dbcon.con)
Dim ds As New DataSet
da.Fill(ds)
End Sub
Getting the value of your control, ddltablename, has to be done in the application context, not within the SQL command.

asp.net DropDownList postback not executing method on first postback

I'm facing very un natural problem suddenly. I have DropDownList with autopostback is true. Postback executes a method which populates other things onpage according to selection. Now When I select any value first time from that dropdown then page gets postback but nothing get populate but from second time it works fine. Even I put breakpoint on that dropdown & it's not even hitting breakpoint for first postback.
<asp:DropDownList ID="ClientCode" runat="server" ClientIDMode="Static" CssClass="field-pitch" AutoPostBack="true"></asp:DropDownList>
Private Sub ClientCode_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ClientCode.SelectedIndexChanged
Me.populateConsignerDetails()
End Sub
Private Sub populateConsignerDetails()
Try
Dim str As String = "SELECT * FROM clientsDetails WHERE clientID = #clientID"
con.Open()
Dim cmd As New MySqlCommand(str, con)
cmd.Parameters.AddWithValue("#clientID", ClientCode.SelectedItem.ToString)
Dim da As New MySqlDataAdapter(cmd)
Dim dt As New DataTable
da.Fill(dt)
con.Close()
Dim payingParty As String = String.Empty
If dt.Rows.Count > 0 Then
consignerName.Text = dt.Rows(0)("clientName").ToString
consignerAddress.Text = dt.Rows(0)("companyAddress").ToString
consignerMobile1.Text = dt.Rows(0)("contactNumber1").ToString
consignerCity.Text = dt.Rows(0)("city").ToString
consignerState.Text = dt.Rows(0)("state").ToString
consignerPinCode.Text = dt.Rows(0)("pinCode").ToString
End If
Catch ex As Exception
Response.Write(ex)
End Try
End Sub
Update
Private Sub myadmin_shipment_details2_Load(sender As Object, e As EventArgs) Handles Me.Load
If Not Me.IsPostBack Then
populateClient()
End If
End Sub
Private Sub populateClient()
Using conn As New MySqlConnection()
conn.ConnectionString = ConfigurationManager _
.ConnectionStrings("conio").ConnectionString()
Using cmd As New MySqlCommand()
cmd.CommandText = "Select * from clientsDetails where status = 'active'"
cmd.Connection = conn
conn.Open()
Using sdr As MySqlDataReader = cmd.ExecuteReader()
While sdr.Read()
Dim item As New ListItem()
item.Text = sdr("clientID").ToString()
item.Value = sdr("ClientName").ToString()
ClientCode.Items.Add(item)
End While
End Using
conn.Close()
End Using
End Using
End Sub

Program won't give me the right Sum

I want to get the sum of the selected items in the listbox and display them in a label but i am always getting 0,i also want to put the selected items in another label too which is also not working.
Here is what the code look like:
Dim sum As Integer
Dim Items1 As String = "None"
Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
Label2.Text = Request.QueryString("Name").ToString()
Dim connetionString As String = Nothing
Dim connection As SqlConnection
Dim command As SqlCommand
Dim adapter As New SqlDataAdapter()
Dim ds As New DataSet()
Dim sql As String
connetionString = "Data Source=.;Initial Catalog=Shop;integrated security=true"
sql = "select PhoneName,PhonePrice from SmartPhones"
connection = New SqlConnection(connetionString)
connection.Open()
command = New SqlCommand(sql, connection)
adapter.SelectCommand = command
adapter.Fill(ds)
adapter.Dispose()
command.Dispose()
connection.Close()
ListBox1.DataSource = ds.Tables(0)
ListBox1.DataTextField = "PhoneName"
ListBox1.DataValueField = "PhonePrice"
ListBox1.DataBind()
End Sub
code where the display should happen:
Protected Sub Button2_Click(sender As Object, e As EventArgs) Handles TotalPrice.Click
sum = 0 'reset sum to 0
For Each i As Integer In ListBox1.GetSelectedIndices
Dim CurrentItem As ListItem = ListBox1.Items(i)
sum = sum + CInt(CurrentItem.Value)
Items1 = Items1 + " , " + CStr(CurrentItem.Text)
Next
Label3.Text = Items1
Label1.Text = sum
End Sub
Here is the page Design and the Page On the web Respectively:
PhoneName is of type varchar in database & PhonePrice is of type integer (Both Filled correctly).
ListBox code:
<asp:ListBox ID="ListBox1" runat="server" SelectionMode="Multiple" ></asp:ListBox>
What's the reason that the code won't give me the desired result?
What is happening is that when you click TotalPrice a postback is performed (What is a postback?). If you look at the ASP.NET page lifecycle you will see that the Load event happens before the postback event handling (e.g. your Sub Button2_Click).
So, you click the button, it runs the Me.Load handler and... your list is reset before the click handler gets a chance to run.
There is a property you can check to see if the page is running as a result of a postback: Page.IsPostBack.
So all you need to do is check it to see if you need to populate the list:
Sub FillItemsList()
Dim connectionString As String = "Data Source=.;Initial Catalog=Shop;integrated security=true"
Dim dt As New DataTable()
Using connection As New SqlConnection(connectionString)
Dim sql As String = "SELECT PhoneName,PhonePrice FROM SmartPhones"
Using adapter As New SqlDataAdapter(sql, connection)
adapter.Fill(dt)
End Using
End Using
ListBox1.DataSource = dt
ListBox1.DataTextField = "PhoneName"
ListBox1.DataValueField = "PhonePrice"
ListBox1.DataBind()
End Sub
Private Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
Label2.Text = Request.QueryString("Name").ToString()
If Not Page.IsPostBack Then
FillItemsList()
End If
End Sub

DataTable must be set prior to using DataView. Am I binding my data the wrong way?

it have been a week since I start with this project but I'm totally clueless on what to fix anymore. down here is part of my coding.
Protected Sub bpn_Click(sender As Object, e As EventArgs)
Try
Using connection As New SqlConnection(ConfigurationManager.ConnectionStrings("SQLServer2005DBConnectionString").ToString())
connection.Open()
Dim sql As String = ("select * from LOT_ WHERE PRODUCTNAME ='" & txtbpn.Text & "'")
Dim cmd As SqlCommand = New SqlCommand(sql, connection)
Using reader As SqlDataReader = cmd.ExecuteReader
If reader.HasRows Then
lblerror.Visible = False
connection.Dispose()
connection.Close()
Me.BindBpn()
txtbpn.Text = String.Empty
TextBox2.Text = String.Empty
TextBox3.Text = String.Empty
TextBox4.Text = String.Empty
TextBox5.Text = String.Empty
Else
connection.Dispose()
connection.Close()
lblerror.Text = "bpn not found"
lblerror.Visible = True
txtbpn.Text = String.Empty
TextBox2.Text = String.Empty
TextBox3.Text = String.Empty
TextBox4.Text = String.Empty
TextBox5.Text = String.Empty
End If
End Using
Catch ex As Exception
Response.Write(ex.Message)
Response.AppendHeader("Refresh", "1;url=Summary.aspx")
End Try
End Sub
1.the binding sub
Private Sub BindBpn()
Using con As New SqlConnection(ConfigurationManager.ConnectionStrings("SQLServer2005DBConnectionString").ToString())
Using cmd As New SqlCommand("SELECT * FROM LOT_ WHERE PRODUCTNAME='" & txtbpn.Text & "'order by checkin asc")
Using sda As New SqlDataAdapter()
con.Open()
cmd.Connection = con
sda.SelectCommand = cmd
Dim dt As New DataTable()
sda.Fill(dt)
Dim dv As New DataView(dt)
GridView1.DataSource = dv
GridView1.DataBind()
' Me.BindGridView()
con.Close()
End Using
End Using
End Using
If GridView1.Visible = False Then
GridView1.Visible = True
End If
If Button1.Visible = False Then
Button1.Visible = True
End If
End Sub
2.the error happen when I'm trying to sort the data.
Protected Sub SortRecords(sender As Object, e As GridViewSortEventArgs)
Dim SortDir As String = String.Empty
Dim sortExpression As String = e.SortExpression
Dim dv As New DataView(GridView1.DataSource)
If dv IsNot Nothing Then
If direction = SortDirection.Ascending Then
direction = SortDirection.Descending
SortDir = "Desc"
ViewState("SortExpression") = Convert.ToString(e.SortExpression & " " & SortDir)
Else
direction = SortDirection.Ascending
SortDir = "Asc"
ViewState("SortExpression") = Convert.ToString(e.SortExpression & " " & SortDir)
End If
End If
dv.Sort = ViewState("SortExpression").ToString
GridView1.DataSource = dv
GridView1.DataBind()
end sub
The error happen on this code
dv.Sort = ViewState("SortExpression").ToString
Any help would be great. Thanks in advance
this is my aspx GridView:
<asp:GridView ID="GridView1" width="100%" runat="server"
AllowSorting="True"
OnSorting="SortRecords"
OnRowDataBound="GridView1_RowDataBound"
ItemStyle-HorizontalAlign="Center"
AutoGenerateColumns="False" >
<Columns>
<asp:TemplateField HeaderText="ID" ItemStyle-HorizontalAlign="Center">
<ItemTemplate>
<%# Container.DataItemIndex + 1 %>
</ItemTemplate>
<ItemStyle HorizontalAlign="center" Width="5%" />
</asp:TemplateField>
<asp:BoundField DataField="Location" HeaderText="Location" />
<asp:BoundField DataField="LOT_ID" HeaderText="Lot ID" />
<asp:BoundField DataField="PkgName" HeaderText="PIN PACKAGE NAME" />
<asp:BoundField DataField="MBTBoardNo" HeaderText="MBTBoardNo" SortExpression="MBTBoardNo" />
<asp:BoundField DataField="BTProgramName" HeaderText="BT Program Name" />
<asp:BoundField DataField="ProductRank" HeaderText="ProdRank"/>
<asp:BoundField DataField="BASEPRODUCTNAME" HeaderText="BPN" />
<asp:BoundField DataField="MCNo" HeaderText="MC No" />
<asp:BoundField DataField="QTY" HeaderText="Qty" />
<asp:BoundField DataField="CreateDate" HeaderText="Start Date" />
<asp:BoundField DataField="CheckIn" HeaderText="CheckIn" />
<asp:BoundField DataField="CheckOut" HeaderText="CheckOut" />
</Columns>
</asp:GridView>
This may be overkill butI need to explain some things.
Sql injection attacks aside for the moment you have a lot of other thing to understand first.
You are having trouble sorting because you have not Cached the retrieved data to any persistence mechanism. This Code in your sorting mechanism will always evaluate to Nothing:
Dim dv As New DataView(GridView1.DataSource)
A GridView DataSource is not persisted across postbacks unless you
use a Caching data control like SqlDataSource which manages the
cache for you.
Or you do so programmatically in one of:
ViewState(bad idea)
SessionState(not perfect)
the Application Cache(ideal)
But back to basics:
Here is an edited and annotated version of the first part of your post
I'll provide a cleaned up version following this:
Protected Sub bpn_Click(sender As Object, e As EventArgs)
' Added for clarity
Dim cs as String = ConfigurationManager.ConnectionStrings("SQLServer2005DBConnectionString").ToString()
' Try is generally not needed if you are using Using
' at least not here. Move it to the inner most Using block and
' wrap it around the actual command execution to catch sql errors
' you want to personally manage.
' Try
Using connection As New SqlConnection(cs)
connection.Open()
' String.Format() - learn to love this function
Dim sql As String = String.Format("select * from LOT WHERE PRODUCTNAME ='{0}' order by checkin asc", txtbpn.Text)
Dim cmd As SqlCommand = New SqlCommand(sql, connection)
' This reader is not necessary as all you are doing
' is using it to determine if there is anything to do
' This is a waste of time
' You already have one open connection and
' now you are jumping to a bind operation
' that opens more.
' Generally speaking:
' open a data connection, get the data, close the connection
Using reader As SqlDataReader = cmd.ExecuteReader
' Do this here, not in both parts of the `If`
lblerror.Visible = reader.HasRows
' lblerror.Text can be initialized here or in the .aspx
' as you do nothing else with it but toggle its visibility
' Plus you can make use of a GridView's EmptyDataText property
' and get rid of the Label altogether.
lblerror.Text = "bpn not found"
If reader.HasRows Then
Me.BindBpn()
End If
' This code is not needed as it's handled by the outer Using
' connection.Dispose()
' connection.Close()
// Since this code happens in both parts of the
// IF, it only needs to happen once.
txtbpn.Text = String.Empty
TextBox2.Text = String.Empty
TextBox3.Text = String.Empty
TextBox4.Text = String.Empty
TextBox5.Text = String.Empty
// Check your original code: 2 Using requires 2 End Using
End Using
End Using
' See Try above
Catch ex As Exception
Response.Write(ex.Message)
'Why are you trying to refresh every second?
Response.AppendHeader("Refresh", "1;url=Summary.aspx")
End Try
End Sub
Here is the Revised Code without all the comments
Protected Sub bpn_Click(sender As Object, e As EventArgs)
Dim cs as String = ConfigurationManager.ConnectionStrings("SQLServer2005DBConnectionString").ToString()
Using connection As New SqlConnection(cs)
connection.Open()
Dim sql As String = String.Format("select * from LOT WHERE PRODUCTNAME ='{0}' order by checkin asc", txtbpn.Text)
Dim cmd As SqlCommand = New SqlCommand(sql, connection)
Using sda As New SqlDataAdapter( cmd )
Try
Dim dt As New DataTable()
sda.Fill(dt)
Dim dv as New DataView(dt)
' This will persist the retrieved record set
' -- Replaced C# syntax with VB
Cache("AStringToIdentifyThisGridviewCache") = dv
GridView1.DataSource = Cache("AStringToIdentifyThisGridviewCache")
Gridview1.EmptyDataText = "bpn not found"
GridView1.DataBind()
GridView1.Visible = (GridView1.Rows.Count > 0)
txtbpn.Text = String.Empty
TextBox2.Text = String.Empty
TextBox3.Text = String.Empty
TextBox4.Text = String.Empty
TextBox5.Text = String.Empty
Catch ex As Exception
Gridview1.EmptyDataText = ex.Message
End Try
End Using
End Using
End Sub
One more thing, your data is going to be retrieved from the database and will overwrite the Cache and rebind to the GridView every time you hit the button.
Typically you want to retrieve the data once and then work with the Cached dataset until the data is modified in some way that it requires another database hit.
Programmatic data retrieval and binding is certainly useful, but I find I rarely need to use it. You may be under requirements for this project but for GridView operations, it's hard to beat the provided DataSource Controls.
Hope this helps.
Happy Coding.
Sorting Code lifted from MSDN Sample for GridView Sorting
Protected Sub SortRecords(ByVal sender As Object, ByVal e As GridViewSortEventArgs)
'Retrieve the table from the session object.
Dim dv As DataView = TryCast(Cache("AStringToIdentifyThisGridviewCache"), DataView)
If dv IsNot Nothing Then
'Sort the data.
dv.Sort = e.SortExpression & " " & GetSortDirection(e.SortExpression)
GridView1.DataSource = Cache("AStringToIdentifyThisGridviewCache")
GridView1.DataBind()
End If
End Sub
Private Function GetSortDirection(ByVal column As String) As String
' By default, set the sort direction to ascending.
Dim sortDirection = "ASC"
' Retrieve the last column that was sorted.
Dim sortExpression = TryCast(ViewState("SortExpression"), String)
If sortExpression IsNot Nothing Then
' Check if the same column is being sorted.
' Otherwise, the default value can be returned.
If sortExpression = column Then
Dim lastDirection = TryCast(ViewState("SortDirection"), String)
If lastDirection IsNot Nothing _
AndAlso lastDirection = "ASC" Then
sortDirection = "DESC"
End If
End If
End If
' Save new values in ViewState.
ViewState("SortDirection") = sortDirection
ViewState("SortExpression") = column
Return sortDirection
End Function

Editing a Gridview w/o using an SqlDatasource using VB.Net

I developed the following code for editing a GridView (following a tutorial written in C#), It goes into edit mode, but my edits do not take effect, here is my code:
aspx.vb code:
Imports System.Data
Imports System.Data.SqlClient
Imports System.Globalization
Partial Class MemberPages_editOutage
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
If Not IsPostBack Then
BindGrid()
End If
End Sub
Private Sub BindGrid()
Dim dt As New DataTable()
Dim connection As New SqlConnection("server='\SQLEXPRESS'; trusted_connection='true'; Database='OutagesMgt_db'")
Try
connection.Open()
Dim sqlStatement As String = "SELECT OutageDetailId, LocationName, Description, DetailDescription, CreateDate, StatusId FROM OutageDetail WHERE StatusId='1' ORDER BY CreateDate DESC"
Dim cmd As New SqlCommand(sqlStatement, connection)
Dim sqlDa As New SqlDataAdapter(cmd)
sqlDa.Fill(dt)
If dt.Rows.Count > 0 Then
MyDataGrid.DataSource = dt
MyDataGrid.DataBind()
End If
Catch ex As System.Data.SqlClient.SqlException
Dim msg As String = "Fetch Error:"
msg += ex.Message
Throw New Exception(msg)
Finally
connection.Close()
End Try
End Sub
'edit command
Protected Sub MyDataGrid_RowEditing(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewEditEventArgs) Handles MyDataGrid.RowEditing
'turn to edit mode
MyDataGrid.EditIndex = e.NewEditIndex
'Rebind the GridView to show the data in edit mode
BindGrid()
End Sub
'cancel command
Protected Sub MyDataGrid_RowCancelingEdit(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewCancelEditEventArgs) Handles MyDataGrid.RowCancelingEdit
' switch back to edit default mode
MyDataGrid.EditIndex = -1
'Rebind the GridView to show the data in edit mode
BindGrid()
End Sub
'Update Function
Private Sub UpdateRecord(ByVal SOutageDetailId As String, ByVal SDescription As String, ByVal SDetailDescription As String, ByVal SCreateDate As String, ByVal SstatusId As String)
Dim connection As New SqlConnection("server='\SQLEXPRESS'; trusted_connection='true'; Database='OutagesMgt_db'")
Dim sqlStatement As String = String.Empty
sqlStatement = "UPDATE OutageDetail SET #OutageDetailId = #OutageDetailId, LocationName = #LocationName, " & _
"Description = #Description, DetailDescription= #DetailDescription, " & _
"CreateDate = #CreateDate, StatusId = #StatusId WHERE OutageDetailId = #OutageDetailId"
connection.Open()
Dim cmd As New SqlCommand(sqlStatement, connection)
cmd.Parameters.Add(New SqlParameter("#OutageDetailId", SOutageDetailId))
cmd.Parameters.Add(New SqlParameter("#LocationName", SDescription))
cmd.Parameters.Add(New SqlParameter("#Description", SDescription))
cmd.Parameters.Add(New SqlParameter("#DetailDescription", SDetailDescription))
cmd.Parameters.Add(New SqlParameter("#CreateDate", SCreateDate))
cmd.Parameters.Add(New SqlParameter("#StatusId", SstatusId))
cmd.CommandType = CommandType.Text
cmd.ExecuteNonQuery()
' MyDataGrid.EditIndex = -1
connection.Close()
BindGrid()
End Sub
'update command
Protected Sub MyDataGrid_RowUpdating(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewUpdateEventArgs) Handles MyDataGrid.RowUpdating
'Accessing Edited values from the GridView
Dim SOutageDetailId As String = MyDataGrid.Rows(e.RowIndex).Cells(0).Text
Dim SDescription As String = MyDataGrid.Rows(e.RowIndex).Cells(1).Text
Dim SDetailDescription As String = MyDataGrid.Rows(e.RowIndex).Cells(2).Text
Dim SCreateDate As String = MyDataGrid.Rows(e.RowIndex).Cells(3).Text
Dim SstatusId As String = MyDataGrid.Rows(e.RowIndex).Cells(4).Text
'Call the function to update the GridView
UpdateRecord(SOutageDetailId, SDescription, SDetailDescription, SCreateDate, SstatusId)
MyDataGrid.EditIndex = -1
'Rebind Gridview to reflect changes made
BindGrid()
End Sub
End Class
aspx code:
<asp:GridView id="MyDataGrid" runat="server"
Width="750px"
CssClass="gridViewEdit"
BackColor="White"
BorderColor="Black"
CellPadding="3"
Font-Name="Verdana"
Font-Size="8pt"
HeaderStyle-BackColor="#FFFFFF"
OnEditCommand="MyDataGrid_RowEditing"
OnCancelCommand="MyDataGrid_RowCancelingEdit"
OnUpdateCommand="MyDataGrid_RowUpdating"
DataKeyField="OutageDetailId"
Font-Names="Verdana">
<Columns>
<asp:CommandField ShowEditButton="True" EditText="Edit" CancelText="Cancel" UpdateText="Update" />
</Columns>
<HeaderStyle BackColor="White"></HeaderStyle>
</asp:GridView>
Could someone shed some light on what I am missing please.
The moment you hit the Edit, you go to get the ID of the line that must be update, and you get it from this line
Dim SOutageDetailId As String = MyDataGrid.Rows(e.RowIndex).Cells(0).Text
but on page load you have set
If Not IsPostBack Then
BindGrid()
End If
so on the post back, the grid up to the point you try to get the id from the cell, is empty.
Two ways, ether give again the data on post back, and make DataBind right after the update, or get the Index of the Grid View to make the Update, and not take the Cell.
For example, I will change your code to:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
BindGrid()
End Sub
Private Sub BindGrid()
Dim dt As New DataTable()
Dim connection As New SqlConnection("server='\SQLEXPRESS'; trusted_connection='true'; Database='OutagesMgt_db'")
Try
connection.Open()
Dim sqlStatement As String = "SELECT OutageDetailId, LocationName, Description, DetailDescription, CreateDate, StatusId FROM OutageDetail WHERE StatusId='1' ORDER BY CreateDate DESC"
Dim cmd As New SqlCommand(sqlStatement, connection)
Dim sqlDa As New SqlDataAdapter(cmd)
sqlDa.Fill(dt)
If dt.Rows.Count > 0 Then
MyDataGrid.DataSource = dt
If Not IsPostBack Then
MyDataGrid.DataBind()
End If
End If
Catch ex As System.Data.SqlClient.SqlException
Dim msg As String = "Fetch Error:"
msg += ex.Message
Throw New Exception(msg)
Finally
connection.Close()
End Try
End Sub
[*] Assuming that you do not have other bugs on sql...

Resources