Crystal report database connections not disposing - asp.net

I am using Visual Studio 2013 in my asp.net web application and using Crystal Reports heavily. My database is SQL Server (using AWS RDS). Everything is working perfectly. The only issue is, from the database side, the Crystal Report connections are not closing/disposing even after closing the browser window. It continuously increasing the number of connections.
This is my code:
ReportDocument cryRpt = new ReportDocument();
ParameterFields paramFields = new ParameterFields();
ParameterField paramField = new ParameterField();
cryRpt.Load(Server.MapPath("~/Reports/Report001.rpt"));
String host = System.Configuration.ConfigurationManager.AppSettings["SqlServer"];
String database = System.Configuration.ConfigurationManager.AppSettings["SqlDatabase"];
String user = System.Configuration.ConfigurationManager.AppSettings["SqlUsername"];
String password = System.Configuration.ConfigurationManager.AppSettings["SqlPassword"];
var connectionInfo = new ConnectionInfo
{
Type = ConnectionInfoType.SQL,
ServerName = host,
DatabaseName = database
};
connectionInfo.IntegratedSecurity = false;
connectionInfo.UserID = user;
connectionInfo.Password = password;
TableLogOnInfo newLogonInfo = null;
foreach (CrystalDecisions.CrystalReports.Engine.Table currentTable in cryRpt.Database.Tables)
{
newLogonInfo = currentTable.LogOnInfo;
newLogonInfo.ConnectionInfo = connectionInfo;
currentTable.ApplyLogOnInfo(newLogonInfo);
}
ParameterField pReportName = new ParameterField();
pReportName.ParameterFieldName = "REPONAME";
ParameterDiscreteValue dcpReportName = new ParameterDiscreteValue();
dcpReportName.Value = "REPORT";
pReportName.CurrentValues.Add(dcpReportName);
paramFields.Add(pReportName);
CrystalReportViewer1.ParameterFieldInfo = paramFields;
CrystalReportViewer1.Zoom(100);
CrystalReportViewer1.PrintMode = CrystalDecisions.Web.PrintMode.ActiveX;
CrystalReportViewer1.ReportSource = cryRpt;
CrystalReportViewer1.ReuseParameterValuesOnRefresh = true;
CrystalReportViewer1.ShowFirstPage();
// Disposing the report
foreach (CrystalDecisions.CrystalReports.Engine.Table currentTable in cryRpt.Database.Tables)
{
currentTable.Dispose();
}
CrystalReportViewer1.ReportSource = null;
cryRpt.Database.Dispose();
cryRpt.Close();
cryRpt.Dispose();
cryRpt = (ReportDocument)CrystalReportViewer1.ReportSource;
CrystalReportViewer1.Dispose();
connectionInfo.Attributes.Collection.Clear();
GC.Collect();
Tried to use the unload method also like this. but no luck.
protected void CrystalReportViewer1_Unload(object sender, EventArgs e)
{
cryRpt.Close();
cryRpt.Dispose();
CrystalReportViewer1.Dispose();
}
As a temporary solution, I'm manually killing the sleeping database connection from the database using a stored procedure.
I'm using ODBC connection to get the data. ODBC credentials are stored in the config file and retrieved as follows.
String host = System.Configuration.ConfigurationManager.AppSettings["SqlServer"];
String database = System.Configuration.ConfigurationManager.AppSettings["SqlDatabase"];
String user = System.Configuration.ConfigurationManager.AppSettings["SqlUsername"];
String password = System.Configuration.ConfigurationManager.AppSettings["SqlPassword"];
Kindly help me to come out of this issue.

In your above code, how do you exactly use the ODBC connection that is stored in a config file ? for example [Is it a DataSet?], because, if so! then you close the Database connection anyway before loading the report as in before this line, here :
cryRpt.Load(Server.MapPath("~/Reports/Report001.rpt"));
I think your problem lies within the Database connection itself with the application, not with Crystal Reports Components.
Try to, close the connection Connection.Close before disposing the viewer CrystalReportViewer1.Dispose();, but caution :
Do not call Close or Dispose on a Connection, a DataReader, or any
other managed object in the Finalize method of your class. In a
finalizer, you should only release unmanaged resources that your class
owns directly. If your class does not own any unmanaged resources, do
not include a Finalize method in your class definition. For more
information, see Garbage Collection.
source
Also, your situation is natural, because the client keeps the connection open, read this too
Here is a sample of Code that I use (without ODBC and with MS-Access) :
Imports CrystalDecisions.CrystalReports.Engine
Imports System.Data.OleDb
Imports CrystalDecisions.Shared
Public Class CrystalForm
Dim cryRpt As New ReportDocument
Dim crtableLogoninfos As New TableLogOnInfos
Dim crtableLogoninfo As New TableLogOnInfo
Dim crConnectionInfo As New ConnectionInfo
Dim CrTables As Tables
Dim CrTable As Table
Private Sub CrystalForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim CMDSelect As String = ("SELECT * FROM Table_Name")
Try
Using DT As New DataTable
Using CN As New OleDbConnection With {.ConnectionString = GetBuilderCNString()}
CN.Open()
Using DataAdapt As New OleDbDataAdapter(CMDSelect, CN)
DataAdapt.Fill(DT)
End Using
End Using
cryRpt.Load(IO.Path.Combine(Application.StartupPath, "Crystal_Report.rpt"))
AssignConnection(cryRpt)
cryRpt.SetDataSource(DT)
CrystalReportViewer1.ReportSource = cryRpt
End Using
Catch ex As EngineException
MsgBox("Report Load Error : " & ex.Message)
End Try
End Sub
Private Sub AssignConnection(rpt As ReportDocument)
Try
Dim ThisConnection As New ConnectionInfo()
With ThisConnection
.DatabaseName = ""
.ServerName = ""
.UserID = "admin"
.Password = "MyPassWord"
End With
For Each table As Table In rpt.Database.Tables
AssignTableConnection(table, ThisConnection)
Next
For Each section As Section In rpt.ReportDefinition.Sections
For Each reportObject As ReportObject In section.ReportObjects
If reportObject.Kind = ReportObjectKind.SubreportObject Then
Dim subReport As SubreportObject = DirectCast(reportObject, SubreportObject)
Dim subDocument As ReportDocument = subReport.OpenSubreport(subReport.SubreportName)
For Each table As Table In subDocument.Database.Tables
AssignTableConnection(table, ThisConnection)
Next
subDocument.SetDatabaseLogon(ThisConnection.UserID,
ThisConnection.Password,
ThisConnection.ServerName,
ThisConnection.DatabaseName)
End If
Next
Next
rpt.SetDatabaseLogon(ThisConnection.UserID,
ThisConnection.Password,
ThisConnection.ServerName,
ThisConnection.DatabaseName)
Catch ex As EngineException
MsgBox("Load Report Error : " & ex.Message)
End Try
End Sub
Private Sub AssignTableConnection(ByVal table As Table, ByVal connection As ConnectionInfo)
Try
Dim logOnInfo As TableLogOnInfo = table.LogOnInfo
connection.Type = logOnInfo.ConnectionInfo.Type
logOnInfo.ConnectionInfo = connection
With table.LogOnInfo.ConnectionInfo
.DatabaseName = connection.DatabaseName
.ServerName = connection.ServerName
.UserID = connection.UserID
.Password = connection.Password
.Type = connection.Type
End With
table.ApplyLogOnInfo(logOnInfo)
Catch ex As EngineException
MsgBox("Load Table Error : " & ex.Message)
End Try
End Sub
End Class

Related

SQL Server connection remains open, even after closing

I have a website that is designed to multi-tiered. My code works, but I have noticed that the larger my app becomes, the more SQL database connections start to stack up and remain open. This eventually causes this error:
System.InvalidOperationException: 'Timeout expired. The timeout
period elapsed prior to obtaining a connection from the pool. This
may have occurred because all pooled connections were in use and max
pool size was reached.'
My code is split into 3 layers. They are:
Application layer. Every time it wants to CRUD, is calls the Business Layer.
Business Layer - does business logic. When it wants to interface with the MS SQL db, it connects via ConnectionAdapter layer.
The ConnectionAdapter inherits from a SqlConnectionAdapter class and does the actual db interactions.
The following is pseudo code for each:
Application
My application may call the business layer multiple times. Particularly when doing AJAX requests. An example would be like:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
Dim dp As New DataProxy
Dim listOfObs As New List(Of MyObject)
dim someId as integer = 1
Try
If Not Page.IsPostBack Then
listOfObs = dp.ExampleReadFuncion(someId)
End If
Catch ex As Exception
Throw
Finally
dp.dispose()
dp = Nothing
SetMenue()
End Try
End Sub
DatatProxy (business layer)
Public Class DataProxy
Dim scConAdapter As New ConnectionAdapter
Public Sub New()
Try
scConAdapter.Connect()
Catch ex As Exception
Throw
End Try
End Sub
Public Sub dispose()
scConAdapter.Dispose()
End Sub
Private Shared Sub Main()
End Sub
Public Function ExampleReadFuncion(ByVal someId As Integer) As List(Of MyObject)
Dim successFactor As LogStatusEnum = LogStatusEnum.INFO
Dim newEx As Exception = Nothing
Dim conn As New ConnectionAdapter
Dim myObj As ActivityMarker
Dim listOfObs As New List(Of MyObject)
Dim dr As SqlDataReader = Nothing
Try
successFactor = LogStatusEnum.INFO
conn.Connect()
dr = conn.ExampleReadFuncion(someId)
Using dr
If (dr.HasRows = True) Then
While dr.Read
myObj = New myObj
myObj.Marker_Id = dr.Item("id")
myObj.Acitvity_Id = dr.Item("someValue")
listOfObs.Add(myObj)
End While
End If
End Using
Return listOfObs
Catch ex As Exception
successFactor = LogStatusEnum.ERRORS
Throw
Finally
dr.Close()
dr = Nothing
conn.Dispose()
conn = Nothing
End Try
End Function
End class
ConnectionAdapter
Public Class ConnectionAdapter
Inherits SqlConnectionAdapter
Public Sub New()
End Sub
Public Function ExampleReadFuncion(ByVal someId As Integer) As SqlDataReader
Try
Dim dr As SqlDataReader = Nothing
Dim selectString As New StringBuilder
Dim cmd As SqlCommand = Nothing
Try
cmd = CreateCommand()
selectString.Append("SELECT * " & vbCrLf)
selectString.Append("FROM " & vbCrLf)
selectString.Append("dbo.mytable " & vbCrLf)
selectString.Append("WHERE " & vbCrLf)
selectString.Append("id = #SOME_ID " & vbCrLf)
With cmd
.CommandType = CommandType.Text
.CommandText = selectString.ToString
.Parameters.Add("#SOME_ID", SqlDbType.Int).Value = someId
dr = .ExecuteReader
End With
Catch ex As Exception
Throw
Finally
cmd.Dispose()
End Try
Return dr
Catch ex As Exception
Throw ex
End Try
End Function
end class
SqlConnectionAdapter
Public MustInherit Class SqlConnectionAdapter
Protected CurrentTransaction As SqlTransaction
Public Property db As SqlConnection
Public Property Password As String
Public Property TNSName As String
Public Property User As String
Public Property DBName As String
Public Property PortNumber As Integer
Public Overridable Sub Dispose()
Try
If Not CurrentTransaction Is Nothing Then
CurrentTransaction.Commit()
End If
Catch ex As Exception
Throw
Finally
If Not db Is Nothing Then
db.Close()
db.Dispose()
db = Nothing
End If
End Try
End Sub
Public Overridable Sub Connect()
Try
Dim appSettings = ConfigurationManager.AppSettings
If (appSettings("releaseVersion") = "DEBUG") Then
Connect(appSettings("db_sqlHost"), appSettings("db_sqlDb"))
Else
Connect(appSettings("db_sqlHost"), appSettings("db_sqlPort"), appSettings("db_sqlDb"), appSettings("db_sqlUser"), appSettings("db_sqlPassword"))
End If
Catch ex As Exception
Throw
End Try
End Sub
Public Sub Connect(ByVal GetServername As String, ByVal GetDatabaseName As String)
Try
TNSName = GetServername
DBName = GetDatabaseName
db = New SqlConnection
db = SqlConnectionUtilities.GetConnection(GetServername, GetDatabaseName)
Catch ex As Exception
Throw
End Try
End Sub
Public Sub Connect(ByVal GetServerName As String, ByVal GetPort As Long, ByVal GetDatabase As String, ByVal GetUsername As String, ByVal Getpassword As String)
Try
User = GetUsername
Password = Getpassword
PortNumber = GetPort
DBName = GetDatabase
TNSName = GetServerName
db = New SqlConnection
db = SqlConnectionUtilities.GetConnection(GetServerName, GetPort, GetDatabase, GetUsername, Getpassword)
Catch ex As Exception
Throw
End Try
End Sub
Protected Function CreateCommand() As SqlCommand
Dim ret As SqlCommand = Nothing
Try
ret = db.CreateCommand
If Not CurrentTransaction Is Nothing Then
ret.Transaction = CurrentTransaction
End If
Catch ex As Exception
Throw
Finally
End Try
Return ret
End Function
Public Sub BeginTransaction()
If CurrentTransaction Is Nothing Then
CurrentTransaction = db.BeginTransaction
End If
End Sub
Public Sub CommitTransaction()
If Not CurrentTransaction Is Nothing Then
CurrentTransaction.Commit()
CurrentTransaction.Dispose()
CurrentTransaction = Nothing
End If
End Sub
Public Sub RollbackTransaction()
If Not CurrentTransaction Is Nothing Then
CurrentTransaction.Rollback()
CurrentTransaction.Dispose()
CurrentTransaction = Nothing
End If
End Sub
Protected Overrides Sub Finalize()
MyBase.Finalize()
End Sub
End Class
Utilities class
Public Class SqlConnectionUtilities
Public Shared Property connectionString As String
Public Shared Function GetConnection(ByVal ServerName As String, ByVal Port As String, ByVal Database As String, ByVal username As String, ByVal password As String) As SqlConnection
Dim connString As New StringBuilder
Dim con As SqlConnection
Try
connString.Append("Server=tcp:" & ServerName & "," & Port & ";")
connString.Append("Initial Catalog = " & Database & "; Persist Security Info=False;")
connString.Append("User ID = " & username & ";")
connString.Append("Password = " & password & ";")
connString.Append("MultipleActiveResultSets = False;")
connString.Append("Encrypt = True;TrustServerCertificate=False;Connection Timeout=30;")
connectionString = connString.ToString
con = New SqlConnection(connString.ToString)
con.Open()
Return con
Catch ex As Exception
Throw
End Try
End Function
Public Shared Function GetConnection(ByVal Servername As String, ByVal DatabaseName As String) As SqlConnection
Dim ConnectString As String
Dim con As SqlConnection
Try
ConnectString = "Data Source=" & Servername & ";Initial Catalog=" & DatabaseName & ";Integrated Security=True"
connectionString = ConnectString
con = New SqlConnection(ConnectString)
con.Open()
Return con
Catch ex As Exception
Throw
End Try
End Function
End class
I can tell that connections are remaining open by running this SQL statement:
SELECT
DB_NAME(dbid) as DBName,
COUNT(dbid) as NumberOfConnections,
loginame as LoginName
FROM
sys.sysprocesses
WHERE
dbid > 0
GROUP BY
dbid, loginame
I set up break points when my DataProxy class is called. I run the SQL code and can see a new connection is opened. Then, I run the code again when I dispose of the DataProxy class and I can see the connection remains. This will build up until it hits 101 connections, then it causes the above error. How am I not handling the connections correctly?
System.InvalidOperationException: 'Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.'
How am I not handling the connections correctly?
You are "leaking" connections. IE you have some code path that opens a SqlConnection, and doesn't Close/Dispose it. The SqlConnection remains open and is sitting on the managed heap. Eventually it will be GC'd and its Finalizer will close the connection. But if you leak 100 connections before that happens, you get this error.
So you need to ensure that your SqlConnections are always closed using a USING block, or are managed by some other object that's closed with a USING block.
Note that if you are returning a SqlDataReader from a function, there's a special CommandBehavior that will close the SqlConnection when the SqlDataReader is closed.
No, even this code not work and it wait a few minutes to remove sql connection from sql server.
using (var conn = new SqlConnection(connStr))
{
conn.Open();
conn.Close();
}
GC.Collect();
GC.WaitForPendingFinalizers();

Getting SQL Server error: "There is already an object named '<my table>' in the database. " when table is NOT in database

In my Visual Basic 2013 ASP.NET web application project running on Windows 7 Pro, I get this error every time I run it.
If I drop my table before running it, my app creates table, but I get error.
If table exists before running it, app tries to create table, ignores error and continues, but I get error.
The Page_Load function steps through as expected, without error, to the end.
And then the error occurs.
Imports System.Data.SqlClient
Public Class WebForm2
Inherits System.Web.UI.Page
Private ConnectionString As String = "Integrated Security=SSPI;" + "Initial Catalog=;" + "Data Source=localhost;"
Private reader As SqlDataReader = Nothing
Private conn As SqlConnection = Nothing
Private cmd As SqlCommand = Nothing
Private sql As String = Nothing
Public Const DEBUG_DEFAULT_CLIENT_ID = "NATIONS_BURGERS"
Public Const DEBUG_DEFAULT_JOB_ID = "FRY_COOK_2014_07_05"
Public client_ID
Public job_ID
Public client_job_table
' InitializeS the job application page.
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
' Initialize data:
client_ID = DEBUG_DEFAULT_CLIENT_ID
job_ID = DEBUG_DEFAULT_JOB_ID
client_job_table = client_ID + "_" + job_ID
' App selects client job table :
Dim command_successful =
ExecuteSQLStmt(" select * from " + client_job_table)
' Create table if it doesn't exist:
If Not command_successful Then
ExecuteSQLStmt("CREATE TABLE " + client_job_table + _
"(" + _
"FIRST_NAME varchar(255)," + _
"LAST_NAME varchar(255)," + _
"PHONE varchar(255)" + _
");")
End If
set_22_button.Visible = GridView1.Visible
set_333_button.Visible = GridView1.Visible
End Sub
' Sends sql command to ehires database.
Private Function ExecuteSQLStmt(ByVal sql As String)
' Open the connection
ConnectionString = "Data Source=<my IP>;Initial Catalog=<my database name>;Persist Security Info=True;User ID=Doug;Password=ThankYou!!"
Dim connection As New SqlConnection(ConnectionString)
connection.ConnectionString = ConnectionString
connection.Open()
cmd = New SqlCommand(sql, connection)
Dim command_successful = True
On Error Resume Next
cmd.ExecuteNonQuery()
If Err.Number Then
command_successful = False
Dim reason = Err.Description
Else
command_successful = True
End If
connection.Close()
Return command_successful
End Function 'ExecuteSQLStmt
Your connection string doesn't specify the catalog name (the database name) so your query is executed against the "MASTER" database. If you look there probably you will find the table that you think is not present
Private ConnectionString As String = #"Integrated Security=SSPI;" & _
"Initial Catalog=.....database name here;" & _
"Data Source=localhost;"
The problem was that I was using a GridView UI control to look at the table, but the GridView was not being updated, so never showed that table was already there.
Problem solved by updating GridView.

Insert data from uploaded Excel document to database using ASP.net (Vb.net)

Im working on a web application, I want to Know if there is a possibility to insert the data fields information of an Excel file into my SqlServer database after uploading it, using Asp.net(VB.net) ??
Thank's
Try this code in VB.NET:
Protected Sub btnExport(ByVal sender As Object, ByVal e As System.EventArgs)
Dim TheFile As FileInfo = New FileInfo(MapPath(".") & "\" & "filename.xls")
' Connection String to Excel Workbook 2010 (xlsx)
' Dim excelConnectionString As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + Server.MapPath("~\directory\filename.xlsx") + ";Extended Properties=""Excel 12.0 Xml;HDR=YES;"""
' Connection String to Excel Workbook 2003 (xls)
Dim excelConnectionString As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + Server.MapPath("~\directory\filename.xls") + ";Extended Properties=""Excel 8.0;HDR=YES;"""
' Create Connection to Excel Workbook
Using connection As New OleDbConnection(excelConnectionString)
Dim command As New OleDbCommand("Select * FROM [sheetname$] ", connection)
connection.Open()
' Create DbDataReader to Data Worksheet
Using dr As DbDataReader = command.ExecuteReader()
' SQL Server Connection String
Const sqlConnectionString As String = "Data Source=server; Initial Catalog=database; Persist Security Info=True;User ID=userid;Password=password"
' Bulk Copy to SQL Server
Using bulkCopy As New SqlBulkCopy(sqlConnectionString)
bulkCopy.DestinationTableName = "SqlServerTableName"
bulkCopy.WriteToServer(dr)
End Using
End Using
End Using
End Sub
Additional tip: try to set IIS to run 32-bit applications.
Yes it is possible. Here is the bird's view of possible basic steps:
After uploading - save Excel file under temporary unique name
Open OLEDB connection to the uploaded file
Read it (either via OleDbDataReader - if it's a huge file, so you don't have to load it into memory at once, or into DataTable if it's small)
Run your queries, Stored procedures to update SqlServer DB with acquired data
Delete uploaded file
Try this
public void export(string excelfilepath)
{
string ssqltable = "tdatamigrationtable";
string myexceldataquery = "select student,rollno,course from [sheet1$]";
try
{
//create our connection strings
string sexcelconnectionstring = #"provider=microsoft.jet.oledb.4.0;data source=" + excelfilepath +
";extended properties=" + "\"excel 8.0;hdr=yes;\"";
string ssqlconnectionstring = "server=mydatabaseservername;user
id=dbuserid;password=dbuserpassword;database=databasename;connection reset=false";
//series of commands to bulk copy data from the excel file into our sql table
oledbconnection oledbconn = new oledbconnection(sexcelconnectionstring);
oledbcommand oledbcmd = new oledbcommand(myexceldataquery, oledbconn);
oledbconn.open();
oledbdatareader dr = oledbcmd.executereader();
sqlbulkcopy bulkcopy = new sqlbulkcopy(ssqlconnectionstring);
bulkcopy.destinationtablename = ssqltable;
while (dr.read())
{
bulkcopy.writetoserver(dr);
}
oledbconn.close();
}
catch (exception ex)
{
//handle exception
}
}
Imports System.Data.Common
Imports System.Data.SqlClient
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim fname As String
Using ofd As New OpenFileDialog
If ofd.ShowDialog = Windows.Forms.DialogResult.OK Then
fname = ofd.FileName
End If
End Using
Dim olecon As String = "Provider=Microsoft.ACE.OLEDB.12.0 ;Data Source=" & fname & ";Extended Properties=""Excel 12.0;IMEX=1;HDR=YES;"""
Dim dBaseConnection As New System.Data.OleDb.OleDbConnection(olecon)
dBaseConnection.Open()
SSQL = "select [LOT],[IMAGE],[STYLENO],[VENDOR] from [Sheet1$]"
Dim cmd As New OleDbCommand(SSQL, dBaseConnection)
Dim da As New OleDbDataAdapter(cmd)
Dim ds As New DataSet
da.Fill(ds)
Using dr As DbDataReader = cmd.ExecuteReader
If SHCONNECTION.State = ConnectionState.Closed Then
Call SHconn(MCONNECTIONSTRING)
End If
Using bulkCopy As New SqlBulkCopy(MCONNECTIONSTRING)
bulkCopy.DestinationTableName = "DBimage"
bulkCopy.WriteToServer(ds)
End Using
End Using
End Sub
End Class

Uploading files to SQL Server 2012 with ASP.NET/VB.NET

I followed a tutorial an ran the below code without any errors. The file "uploads", however no data is inserted into my SQL Server table.
Data should be inserted into the content table.
Content Table:
Document.aspx
Imports System.Data.SqlClient
Imports System.Data
Imports System.IO
Partial Class Documents
Inherits System.Web.UI.Page
Protected Sub btnUploadContent_Click(sender As Object, e As EventArgs) Handles btnUploadContent.Click
Dim filePath As String = FileUpload.PostedFile.FileName
Dim filename As String = Path.GetFileName(filePath)
Dim ext As String = Path.GetExtension(filename)
Dim contenttype As String = String.Empty
Select Case ext
Case ".doc"
contenttype = "application/vnd.ms-word"
Exit Select
Case ".docx"
contenttype = "application/vnd.ms-word"
Exit Select
Case ".xls"
contenttype = "application/vnd.ms-excel"
Exit Select
Case ".xlsx"
contenttype = "application/vnd.ms-excel"
Exit Select
Case ".jpg"
contenttype = "image/jpg"
Exit Select
Case ".png"
contenttype = "image/png"
Exit Select
Case ".gif"
contenttype = "image/gif"
Exit Select
Case ".pdf"
contenttype = "application/pdf"
Exit Select
End Select
If contenttype <> String.Empty Then
Dim fs As Stream = FileUpload.PostedFile.InputStream
Dim br As New BinaryReader(fs)
Dim bytes As Byte() = br.ReadBytes(fs.Length)
'insert the file into database
Dim strQuery As String = "INSERT INTO content (content_name, content_type, content_file) VALUES (#Name, #ContentType, #Data)"
Dim cmd As New SqlCommand(strQuery)
cmd.Parameters.Add("#Name", SqlDbType.VarChar).Value = filename
cmd.Parameters.Add("#ContentType", SqlDbType.VarChar).Value() = contenttype
cmd.Parameters.Add("#Data", SqlDbType.Binary).Value = bytes
InsertUpdateData(cmd)
lblMessage.ForeColor = System.Drawing.Color.Green
lblMessage.Text = "File Uploaded Successfully"
Else
lblMessage.ForeColor = System.Drawing.Color.Red
lblMessage.Text = "File format not recognised." + " Upload Image/Word/PDF/Excel formats"
End If
End Sub
Public Function InsertUpdateData(ByVal cmd As SqlCommand) As Boolean
Dim strConnString As String = System.Configuration.ConfigurationManager.ConnectionStrings("ConnStringDb1").ConnectionString()
Dim conn As New SqlConnection("Data Source=BRIAN-PC\SQLEXPRESS;Initial Catalog=master_db;Integrated Security=True;")
cmd.CommandType = CommandType.Text
cmd.Connection = conn
Try
conn.Open()
cmd.ExecuteNonQuery()
Return True
Catch ex As Exception
Response.Write(ex.Message)
Return False
Finally
conn.Close()
conn.Dispose()
End Try
End Function
End Class
Can anyone tell me what's going on ?
EDIT: Debug Breakpoint # InsertUpdateData(cmd) :
SqlDbType.Binary Binary {1} System.Data.SqlDbType
+ bytes {Length=4136752} Byte()
+ cmd {System.Data.SqlClient.SqlCommand} System.Data.SqlClient.SqlCommand
+ cmd.Parameters {System.Data.SqlClient.SqlParameterCollection} System.Data.SqlClient.SqlParameterCollection
I have created empty database and added table content just like you have and I used code almost the same as you and it worked fine.
Again, if no exception occurs, please check your connection string and see whether the rows been added to the table in the db specified in connection string.
Here is my code (which is working fine), a bit modified from yours:
Imports System.Data.SqlClient
Imports System.IO
Public Class _Default
Inherits System.Web.UI.Page
Protected Sub btnUploadContent_Click(sender As Object, e As EventArgs) Handles btnTest1.Click
Dim fs As Stream = FileUpload.PostedFile.InputStream
Dim br As New BinaryReader(fs)
Dim bytes As Byte() = br.ReadBytes(fs.Length)
'insert the file into database
Dim strQuery As String = "INSERT INTO content (content_name, content_type, content_file) VALUES (#Name, #ContentType, #Data)"
Dim cmd As New SqlCommand(strQuery)
cmd.Parameters.Add("#Name", SqlDbType.VarChar).Value = "filename"
cmd.Parameters.Add("#ContentType", SqlDbType.VarChar).Value() = "jpg"
cmd.Parameters.Add("#Data", SqlDbType.Binary).Value = bytes
InsertUpdateData(cmd)
End Sub
Public Function InsertUpdateData(ByVal cmd As SqlCommand) As Boolean
Dim conn As New SqlConnection("Data Source=(local);Initial Catalog=test;Integrated Security=True;")
cmd.CommandType = CommandType.Text
cmd.Connection = conn
Try
conn.Open()
cmd.ExecuteNonQuery()
Return True
Catch ex As Exception
Response.Write(ex.Message)
Return False
Finally
conn.Close()
conn.Dispose()
End Try
End Function
End Class
I add sample of SQL to test on DB:
INSERT INTO [master_db].[dbo].[content]
([content_name]
,[content_type]
,[content_file])
VALUES
('test'
,'png'
,0x111111111111111)
SELECT * FROM [master_db].[dbo].[content]
I came across this post looking looking for an example. I used the example code you posted and had the same problem. I found and resolved the following issues and got it working:
I created the db table as pictured. content_type of nchar(5) was the first problem since you were inserting something like "application/vnd.ms-word" which was too big.
The next error was because I had not defined the content_id to be an identity column and since it wasn't listed in the insert statement it failed.
Next I had an error as my db user didn't have insert privileges.
The biggest problem is that the return message was always a success message because even though the InsertUpdateData function was catching errors it was not notifying the calling code. This made me think things were okay. doh! Using a breakpoint on the ExecuteNonQuery allowed me to see the errors.
Hope that helps the next person that stops by....

Error "ExecuteReader: connection property has not been initialized."

Here's my code. I can't seem to figure out what's causing this error. The error itself pointed to the Do While myReader.read line of code, but I'm not sure that's what's causing the problem.
Here is a more detailed error message:
executereader: connection property has not been initialized. at system.data.oledb.oledbcommand.validateconnection(string method) at system.data.oledb.oledbcommand.validateconnectionandtransaction(string method)
Code:
Imports System.Data.OleDb
Imports System.Data
Partial Class Customer_6_OrderHistory
Inherits System.Web.UI.Page
Private myDB As OleDbConnection
Private sqlCmd As OleDbCommand
Private myReader As OleDbDataReader
Private myConnection As String = ConfigurationManager.ConnectionStrings("ConnString10").ToString
Private myDataFile As String = ConfigurationSettings.AppSettings("DBFile")
Private LegoNameList As New ArrayList
Private ShipmentDateList As New ArrayList
Private CostList As New ArrayList
Private NumberPurchasedList As New ArrayList
Private RecipientList As New ArrayList
Private TotalCostList As New ArrayList
Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init
myDB = New OleDbConnection(myConnection)
sqlCmd = New OleDbCommand("exec qry_OrderHistory")
sqlCmd.Parameters.AddWithValue("#CustomerName", Session("myCart").GetCustomerName())
Try
myDB.Open()
myReader = sqlCmd.ExecuteReader
Do While myReader.Read
LegoNameList.Add(myReader("Lego Name"))
ShipmentDateList.Add(myReader("Date"))
CostList.Add(myReader("Cost"))
NumberPurchasedList.Add(myReader("Number Purchased"))
RecipientList.Add(myReader("Recipient"))
TotalCostList.Add(myReader("Total Cost"))
Loop
myReader.Close()
Catch ex As Exception
MsgBox(ex.ToString)
Finally
myDB.Close()
End Try
Dim myDataTable As New DataTable
myDataTable.Columns.Add("Lego Name")
myDataTable.Columns.Add("Date")
myDataTable.Columns.Add("Cost")
myDataTable.Columns.Add("Number Purchased")
myDataTable.Columns.Add("Recipient")
myDataTable.Columns.Add("Total Cost")
For i = 0 To LegoNameList.Count - 1
Dim myRow As DataRow = myDataTable.NewRow
myRow.Item("Lego Name") = LegoNameList.Item(i)
myRow.Item("Date") = FormatDateTime(ShipmentDateList.Item(i), DateFormat.ShortDate)
myRow.Item("Cost") = FormatCurrency(CostList.Item(i), 2, TriState.True, TriState.False, TriState.True)
myRow.Item("Number Purchased") = NumberPurchasedList.Item(i)
myRow.Item("Recipient") = RecipientList.Item(i)
myRow.Item("Total Cost") = FormatCurrency(TotalCostList.Item(i), 2, TriState.True, TriState.False, TriState.True)
myDataTable.Rows.Add(myRow)
Next
gvwOrderHistory.DataSource = myDataTable
gvwOrderHistory.DataBind()
End Sub
End Class
You have created your connection, and then you create your command, but you never assign the connection to your command, which is why you're getting the error. You can either assign the connection to your OleDbCommand, like this:
sqlCmd.Connection = myDB
Or you can specify in the OleDbCommand constructor, like this:
sqlCmd = New OleDbCommand("exec qry_OrderHistory", myDB)
Then you can open the connection and execute the command.
You have to initialize your Connective instance myConnection before use it

Resources