Adding a database to an ASP.NET Web Service - asp.net

Okay this question could either be very broad or very specific because I am not sure if I am going about this in a fundamentally wrong way or if I am close to correct.
First an overview: What I am trying to do it create a server application for all of the clients in my organization to connect to. I think the best way to do this is to use a web service. Please correct me if I am wrong!
Anyway, if I use a web service I need the web service(server) to connect to the database. In MS Visual studio when you add a web service project the data menu disappears and you can't add a data source to the project. There may be a workaround for this by hand coding this, but I am not sure how to do it. This is my first time working with a web service and ASP.NET so I am a real noob in this area.
Any help would be greatly appreciated!!!

Add your database connection string to the <connectionStrings/> section of the web service web.config file. Check this web site for a list of the most common database connection strings: Connectionstrings.com

You would use standard ADO.Net commands and SQL statements, rather than using the dataset designer. Example (IN VB)
<WebMethod()> _
Public Function DoesOpenCallExist(ByVal CustID As String, ByVal CallType As String, ByVal SubCallType As String) As Boolean
Dim returnvalue As Boolean = False
' first, entry validation
' snip - code deleted
Dim conn As New System.Data.SqlClient.SqlConnection
conn.ConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings("HEATConnectionString").ConnectionString
Dim cmd As New SqlClient.SqlCommand
cmd.Connection = conn
cmd.CommandType = CommandType.StoredProcedure
cmd.CommandText = "sp_GetCallCount"
cmd.Parameters.AddWithValue("#CustID", CustID)
' Etc...
Try
conn.Open()
returnvalue = cmd.ExecuteScalar() > 0
Catch ex As Exception
Throw New Exception(ex.ToString())
Finally
conn.Close()
End Try
Return returnvalue
End Function

*This should be done
web.config file*
here the datsource is the servername,initial catlog is the databasename and the userid ur sql userid and the password is as same.
And then in the class we want to get connect with the database......
****class.cs****
public class connect
{
public static SqlConnection con()
{
String con= ConfigurationManager.AppSettings["connections"].ToString();
SqlConnection cn = new SqlConnection(con);
cn.Open();
return cn;
}
}
here the connection is the keyname......
ok i think its sufficient............

Related

How I do a WCF service with two methods: one that waits and insert data into the DB and another to poll the DB?

This is the scenario:
I'm doing a web service in WCF and a client application in ASP.NET. The language is VB.NET.
I want a method than send "jobs" to the server. I'm trying to simulate this kind of jobs as long running processes that wait up to 20-30 seconds with thread sleeping and inserting a row into a JOBS table in the DB.
I want another method that polls the database every 5 seconds with client postbacks to get the jobs lists from the JOBS table (finished and currently running)
This is what i've got so far, both methods are working, except when a long running job is sleeping, then the client can't retrieve the list of jobs with another call. I've tried "PerCall" in the but it didn't work out. I suspect the thread is somewhat locking the service or maybe I have to use async calls. I'm using HttpBasicBinding at web.config ... I'm a little lost and I have not found any code doing something similar.
Here is the code in the service side:
iServiceJobs.vb
<ServiceContract()>
Public Interface IServiceJobs
<OperationContract(IsOneWay:=True)>
Sub SendJob(ByVal runTime As Integer, ByVal id As String)
<OperationContract>
Function GetJobsList() As List(Of ClassJob)
ServiceJobs.vb
Public Class ServiceJobs Implements IServiceJobs
Public SendJob(ByVal runTime As Integer, ByVal id As String) Implements IServiceJobs.SendJob
Dim connStr As String = "..."
Dim conn As New OracleConnection(connStr)
conn.Open()
Dim query As String = "INSERT INTO JOBS(...)"
Dim cmd As New OracleCommand(query, conn)
cmd.ExecuteNonQuery()
Threading.Thread.Sleep(runTime* 1000)
cmd = New OracleCommand(query, conn)
cmd.ExecuteNonQuery()
End Sub
Public Function GetJobList() As List(Of ClassJob) Implements IServiceJobs.GetJobsList
Try
Dim jobList As New List(Of ClassJobs)
Dim connStr As String = "..."
Dim conn As New OracleConnection(connStr)
conn.Open()
Dim query As String = "SELECT * FROM JOBS"
Dim cmd As New OracleCommand(query, conn)
Dim dr As OracleDataReader
Dim job As ClassJob
dr = cmd.ExecuteReader
While dr.Read
job = New ClassJob
job.id = dr(0)
job.lock = dr(3)
...
jobList.Add(job)
job = Nothing
End While
Return jobList
Catch ex As Exception
Return Nothing
End Try
End Function
End Class
The code in the client is very simple, just two buttons, one with a ws call for insert jobs and another to get the job list.
I'm open to any suggestion on how to do a better implementation of this scenario.
EDIT:
I've tried
<ServiceBehavior(ConcurrencyMode:=ConcurrencyMode.Multiple, InstanceContextMode:=InstanceContextMode.PerCall)>
But it doesn't work, GetJobList() returns Nothing while SendJob() is working on this thread.
SOLVED: Apparently, I was using an outdated version of Oracle libraries. When I used Oracle.ManagedDataAccess from NuGet everything went OK.
SOLVED: Apparently, I was using an outdated version of Oracle libraries. When I used Oracle.ManagedDataAccess from NuGet everything went OK.

Migrating ADODB connection from ASP to ASPX

I have to migrate some Classic ASP pages to .NET. I've got the problem with ADODB connection that has been used in ASP App. Here is the code of old db.asp
<%
Option Explicit
' Declare variables...
Dim cnn ' ADO connection
Dim rst ' ADO recordset
Dim strTitle 'Title for each page
Sub OpenDatabase()
' Create an ADO Connection.
Set cnn = Server.CreateObject("ADODB.Connection")
' We're using SQL Server connection string
cnn.Open Session("SQLConnectString")
cnn.CommandTimeout = 0
Server.ScriptTimeout = 3000
' Create an ADO Recordset object
Set rst = Server.CreateObject("ADODB.Recordset")
End Sub
Sub RunSQL(strSQL)
'Open a recordset from the strSQL.
rst.Open strSQL, cnn
End Sub
Sub CloseDatabase()
rst.Close
Set rst = Nothing
cnn.Close
Set cnn = Nothing
End Sub
%>
I want to use this code on every page for connection to DB. know that I have to remove Option Explicit from my code and add header as <%# Page Language="VB" %> I've copied this code to the new aspx page and now I'm getting errors:
1) VS ask me to put End Sub before Sub OpenDatabase(), but there is no Open Sub that need to be closed.
2) VS don't see those variables cnn, rst, strTitle
3) Now I'm storing ConnectionString in Web.config, so I've replaced open with the following code:
cnn.Open(System.Configuration.ConfigurationManager.ConnectionStrings("SQLConnectString").ConnectionString)
What else should I change to fix it? Any advise=) Thanks
You do not use ADODB in DotNet. Technically, you can, but that's not the way to do.
You use ADO.Net, IDataReaders, DataSets (loose or strongly-typed, I prefer strongly-typed).
ASP.NET is not ASP.
Don't feel bad, I was trying the same thing you are (albeit, back in 2002).
Until someone told me differently.
Here is a tutorial...probably at the right level for where you are now.
http://www.aspsnippets.com/Articles/Difference-between-ExecuteReader-ExecuteScalar-and-ExecuteNonQuery.aspx
Rule #1 in NET: connection string better be in web.config or other config files. Or in some cases in OS registry.
Using connection string defined in each and every page in NET is bad practice from security, maintenance and lot of other reasons and on top of that it show low qualification of a programmer who build it.
Rule #2. You can use inline SQL statement but for the same reason as in rule #1 it is a bad idea. Use parametrized stored procedures unless you do not have any like while working with access or Excel or plain text files as data storage.
So in your web.config you should have following entry:
<connectionStrings>
<add name="DBCS"
connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|ProjectDatabases.mdf;Integrated Security=True;User Instance=True"
providerName="System.Data.SqlClient" />
</connectionStrings>
then in your code you call
Public void main()
{
String CONN
String SQLString
CONN = String.Format(ConfigurationManager.ConnectionStrings["DBCS"].ConnectionString, rootPath);
SQLString=/// your stored procedure and parameters if any
SqlCommand cmd = new SqlCommand();
cmd.CommandType = CommandType.StoredProcedure;
cmd = new SqlCommand(SQLString), CONN);
CONN.Open();
SqlDataReader reader = cmd.ExecuteReader();
/// do what ever you need to work with your data like build a string, html document etc
closeConn();
}
public void closeConn()
{
if (reader != null)
{
reader.Close();
}
if (CONN!= null)
{
CONN.Close();
}
}
You do not need Option Explicit for simple reason: C# will not allow you to use any undeclared variable

Enterprise Library 5.0 Connection Pool Timeout

I have an old web application written in ASP.Net 2.0 Web Forms. I use the Data Access Block in Enterprise Library and have recently updated to version 5.0. The application is tiered, ie, UI layer, Service Layer, Data Layer. It also uses SQL Server 2008 for the data storage.
I have recently noticed that the following error is appearing when I run the application and browse to particular pages.
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.
This tends to happen on pages that do a lot of separate reads from the database, maybe up to as many as 20 on one page.
Below shows snippets of my Data Access Class.
Public Class DataAccess
' create a private instance of the database factory
Private db As Database = DatabaseFactory.CreateDatabase()
Public Function ExecuteNonQuery(ByVal params() As SqlParameter, ByVal strSproc As String) As Integer
Dim intReturnValue As Integer = 0
Dim i As Integer
Dim cmd As DbCommand
cmd = db.GetStoredProcCommand(strSproc)
cmd.CommandTimeout = 120
For i = 0 To params.Length - 1
db.AddInParameter(cmd, params(i).ParameterName.ToString, params(i).DbType, params(i).Value)
Next
db.AddParameter(cmd, "return_value", DbType.Int32, ParameterDirection.ReturnValue, "", DataRowVersion.Default, 0)
db.ExecuteNonQuery(cmd)
intReturnValue = Int32.Parse(db.GetParameterValue(cmd, "#return_value"))
Return intReturnValue
End Function
Public Function ExecuteDataReader(ByVal params() As SqlParameter, ByVal SProc As String) As SqlDataReader
Dim i As Integer
Dim dr As SqlDataReader = Nothing
Dim cmd As DbCommand
cmd = db.GetStoredProcCommand(SProc)
cmd.CommandTimeout = 120
For i = 0 To params.Length - 1
db.AddInParameter(cmd, params(i).ParameterName.ToString, params(i).DbType, params(i).Value)
Next
dr = TryCast(DirectCast(db.ExecuteReader(cmd), RefCountingDataReader).InnerReader, SqlDataReader)
Return dr
End Function
Throughout my code, once I have finished with an SqlDataReader I always do something like this
If Not (drSource Is Nothing) Then
drSource.Close()
End If
Is there anything you folk can see that I am missing? Does it look like my code could be leaking connections or not closing properly?
I always thought the Garbage collector got rid of any open connections.
Any feedback or help would be greatly appreciated.
Thanks.
Your code is closing the data reader, but not the data connection associated with it.
Since your data reader is a SqlDataReader, it has a Connection property. You should be able to use that to close and dispose of the connection.

Query about Oracle Connections

I seem to be getting intermittent problems with my Oracle connection indicating something about a problem with semaphores which suggest that Oracle is somehow holding onto the connections instead of removing them after they have been used.
Here's the code and connection string I use:
Connection string: user id=user;password=password;data source=dataSource; Validate Connection=true;Min Pool Size=10;Connection Lifetime=5;Connection Timeout=60;Incr Pool Size=5;
And the code I use is this:
Dim OracleConn As New OracleConnection()
Dim DataTable As DataTable
Dim queryOracle As OracleCommand
Dim OracleDataAdapter As OracleDataAdapter
Dim connStr As String = "user id=user;password=password;data source=dataSource; Validate Connection=true;Min Pool Size=10;Connection Lifetime=5;Connection Timeout=60;Incr Pool Size=5;"
OracleConn.ConnectionString = connStr
Try
OracleConn.Open()
queryOracle = OracleConn.CreateCommand()
queryOracle.CommandText = "select * from table1"
DataTable = New DataTable()
OracleDataAdapter = New OracleDataAdapter(queryOracle)
OracleDataAdapter.Fill(DataTable)
table1.DataSource = DataTable.DefaultView
table1.DataBind()
Catch OracleEx As OracleException
Throw
Catch ex As Exception
Throw
Finally
If Not OracleConn Is Nothing And OracleConn.State = ConnectionState.Open Then
OracleConn.Close()
End If
End Try
Now my questions are:
Is this the best way of doing this?
I only "Close" my connection do I need to "Dispose" of it also?
I'm using Oracle.DataAccess.Client by the way.
Any help will be much appreciated
Try to put everything between Using.
Using oracleConn as OracleConnection = new OracleConnection()
'Your stuff goes here
End Using
the same goes for Commands.
P.S. There's is no need to catch Exception if they are just thrown again.
I suggest you to use using block (Execute Dispose in the end)
Using connection As New OracleConnection()
....
End Using
2 An application can call Close more than one time. No exception is generated.
If you called Dispose method SqlConnection object state will be reset. If you try to call any method on disposed SqlConnection object, you will receive exception.

Is TableAdapter/DataSet safe from SQL injection?

In my ASP.NET(3.5) project, I am using inbuilt TableAdapters/Dataset for all Data Access. Does it provide the same security as SQLDataSource does from SQL injection? I am using parameters as follows.
Dim myDAL As New ABCTableAdapters.XYZTableAdapter
Label1.Text = myDAL.getDatafromDB(myParameter)
Update 1:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim myParameter As String = getSafeURL(Request.QueryString("MS_Code")) 'getsafeurl encodes querystring using HttpUtility.UrlEncode
Dim myDAL As New ABCTableAdapters.XYZTableAdapter
Label1.Text = myDAL.getDatafromDB(myParameter)
End Sub
getDatafromDB corresponds to following query present in app_code/DAL.xsd
SELECT something FROM sometable where fieldname = #parameter
Update 2:
If I 'View Code' of XSD I am able to see following
<SelectCommand>
<DbCommand CommandType="Text" ModifiedByUser="true">
<CommandText>SELECT pageContent FROM [content] where name = #name</CommandText>
<Parameters>
<Parameter AllowDbNull="true" AutogeneratedName="name" ColumnName="name" DataSourceName="iseac.dbo.[content]" DataTypeServer="nchar(100)" DbType="String" Direction="Input" ParameterName="#name" Precision="0" ProviderType="NChar" Scale="0" Size="100" SourceColumn="name" SourceColumnNullMapping="false" SourceVersion="Current" />
</Parameters>
</DbCommand>
</SelectCommand>
It depends.
You could get SQL injection if you badly use tableAdapters.
The main thing is to use SqlParameters for all data that is gathered from users.
Can you show some of your data access code ?
Look up here How To: Protect From SQL Injection in ASP.NET
using System.Data;
using System.Data.SqlClient;
using (SqlConnection connection = new SqlConnection(connectionString))
{
DataSet userDataset = new DataSet();
SqlDataAdapter myDataAdapter = new SqlDataAdapter(
"SELECT au_lname, au_fname FROM Authors WHERE au_id = #au_id",
connection);
myCommand.SelectCommand.Parameters.Add("#au_id", SqlDbType.VarChar, 11);
myCommand.SelectCommand.Parameters["#au_id"].Value = SSN.Text;
myDataAdapter.Fill(userDataset);
}
The important part here is that user entered data (what comes in from web request) is passed to DB inside database parameters like #au_id. In that case you are protected from SQL injection.
BAD WAY would be this (DON'T USE THIS):
myCommandText = string.Format(
"SELECT au_lname, au_fname
FROM Authors WHERE au_id = {0}", SSN.Text)
This way user can manipulate what is send to DB and if your connection to DB has enough privileges it can drop tables or database. Or it can silently modify your data and that is even worse.
So, always use database parameters.
Additionally if you do you gain in performance, because DB will cache execution plan and if you later execute same SQL with only different values for parameters, DB already have execution plan and it doesn't need to parse sql again.

Resources