ASP .net core time out error using Oracle - asp.net

I'm new to ASP .Net Core and am working my way through a demo project to learn the tech stack.
My project is using .net core 2.2 and Oracle.ManagedDataAccess.Core and Oracle.EntityFramework.Core.
I created a model and then went and scaffolded my view and controller through VS 2019. I've set up ConfigureService(...) to use Oracle. I added an HTML link on my main index page to hook into the view created for my model. When it calls the Controller::Index() function, I end up getting the following timeout error
OracleException: Connection request timed out
OracleInternal.ConnectionPool.PoolManager<PM, CP, PR>.Get(ConnectionString csWithDiffOrNewPwd, bool bGetForApp, OracleConnection connRefForCriteria, string affinityInstanceName, bool bForceMatch)
Any help or guidance as to what I could be doing wrong would be greatly appreciated!

It looks like a error connecting to the database.
There are some things you should check:
Make sure the connection string to the database, stored in the appsettings.json is correct.
Make sure to have a firewall rule which allows inbound traffic to the port from where the Oracle db is listening.
If the problem persists then you should provide the code you are using to access the database.

Related

Having trouble connecting to iSeries from .NET Core

Cross-posting with this on the IBM forums: https://www.ibm.com/mysupport/s/forumsquestion?id=0D50z00006egDnsCAE. Follow-up question located here: Having trouble connecting to iSeries from .NET Core
Hi all,
I'm very new to this whole thing, so let me know if there's any info which would help, that I'm not providing.
At the moment I'm just trying to get the very basics working - getting the connection to open. I have a stripped-down .NET Core project, which is simply exposing a button I can press that opens a connection for DB2. My code is as follows:
using IBM.Data.DB2.Core;
...
DB2Connection DB2Connection = new DB2Connection(connectionString);
DB2Connection.SystemNaming = true;
DB2Connection.Open();
My connection string is as follows:
"Server=###.###.###.###;Database=AAAA;UID=BBBB;PWD=CCCC;LibraryList=DDDD,EEEE;"
I'm getting the following exception:
IBM.Data.DB2.Core.DB2Exception (0x80004005): ERROR [08001] [IBM] SQL30081N A communication error has been detected. Communication protocol being used: "TCP/IP". Communication API being used: "SOCKETS". Location where the error was detected: "###.###.###.###". Communication function detecting the error: "connect". Protocol specific error code(s): "10061", "*", "*". SQLSTATE=08001
I really don't know how to proceed from here. For context - I'm using "IBM Navigator for i" to query the info directly, and that works just fine for the IP, User ID, and Password I used above.
I've done some reading up, and attempted a few different solutions, but none really helped. I did see that in "Integrating DB2 Universal Universal Database for iSeries with for iSeries with Microsoft ADO .NET", it suggested looking in the Work Management section of the navigator, and check under Server Jobs to see whether there was any added info - however, it does not appear there is anything there to see.
I do understand that I may require a license for this connection to work properly, and accept that if that ends up being the problem, I'll need to get the license - but I don't think I've reached that stage yet. For now I just want to make sure the connection itself works properly.
Any help or insights are greatly appreciated. Thank you.
The symptom SQL30081N with 10061 was resolved by including the PORT=xxx; in the connection string, where xxx is the correct TCP/IP port number on which the Db2-for-i-series is listening for connections.

EntityException: The underlying provider failed on Open. Can one server closing a db connection, make another server fail on opening?

I am experiencing database connection errors with an ASP.NET application written in VB, running on three IIS servers. The underlying database is MS Access, which is on a shared network device. It uses Entity Framework, code first implementation and JetEntityFrameworkProvider.
The application is running stable. But, approximately 1 out of 1000 attempts to open the database connection fails with either one of the following two errors:
06:33:50 DbContext "Failed to open connection at 2/12/2020 6:33:50 AM +00:00 with error:
Cannot open database ''. It may not be a database that your application recognizes, or the file may be corrupt.
Or
14:04:39 DbContext "Failed to open connection at 2/13/2020 2:04:39 PM +00:00 with error:
Could not use ''; file already in use.
One second later, with refreshing (F5), the error is gone and it works again.
Details about the environment and used code.
Connection String
<add name="DbContext" connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=x:\thedatabase.mdb;Jet OLEDB:Database Password=xx;OLE DB Services=-4;" providerName="JetEntityFrameworkProvider" />
DbContext management
The application uses public property to access DbContext. DbContext is kept in the HttpContext.Current.Items collection for the lifetime of the request, and is disposed at it’s end.
Public Shared ReadOnly Property Instance() As DbContext
Get
SyncLock obj
If Not HttpContext.Current.Items.Contains("DbContext") Then
HttpContext.Current.Items.Item("DbContext") = New DbContext()
End If
Return HttpContext.Current.Items.Item("DbContext")
End SyncLock
End Get
End Property
BasePage inits and disposes the DbContext.
Protected Overrides Sub OnInit(e As EventArgs)
MyBase.OnInit(e)
DbContext = Data.DbContext.Instance
...
End Sub
Protected Overrides Sub OnUnload(e As EventArgs)
MyBase.OnUnload(e)
If DbContext IsNot Nothing Then DbContext.Dispose()
End Sub
What I have tried
Many of the questions on SO which address above error messages, deal with generally not being able to establish a connection to the database – they can’t connect at all. That’s different with this case. Connection works 99,99% of the time.
Besides that, I have checked:
Permissions: Full access is granted for share where .mdb (database) and .ldb (locking file) resides.
Network connection: there are no connection issues to the shared device; it’s a Gigabit LAN connection
Maximum number of 255 concurrent connections is not reached
Maximum size of database not exceeded (db has only 5 MB)
Changed the compile option from “Any CPU” to “x86” as suggested in this MS Dev-Net post
Quote: I was getting the same "Cannot open database ''" error, but completely randomly (it seemed). The MDB file was less than 1Mb, so no issue with a 2Gb limit as mentioned a lot with this error.
It worked 100% on 32 bit versions of windows, but I discovered that the issues were on 64 bit installations.
The app was being compiled as "Any CPU".
I changed the compile option from "Any CPU" to "x86" and the problem has disappeared.
Nothing helped so far.
To gather more information, I attached an Nlog logger to the DbContext which writes all database actions and queries to a log file.
Shared Log As Logger = LogManager.GetLogger("DbContext")
Me.Database.Log = Sub(s) Log.Debug(s)
Investigating the logs I figured out that when one of the above errors occured on one server, another one of the servers (3 in total) has closed the db connection at exactly the same time.
Here two examples which correspond to the above errors:
06:33:50 DbContext "Closed connection at 2/12/2020 6:33:50 AM +00:00
14:04:39 DbContext "Closed connection at 2/13/2020 2:04:39 PM +00:00
Assumption
When all connections of a DbContext have been closed, the according record is removed from the .ldb lock file. When a connection to the db is being opened, a record will be added to the lock file. When these two events occur at the exact same time, from two different servers, there is a write conflict to the .ldb lock file, which results in on of the errors from above.
Question
Can anyone confirm or prove this wrong? Has anyone experienced this behaviour? Maybe I am missing something else. I’d appreciate your input and experience on this.
If my assumption is true, a solution could be to use a helper class for accessing db, which catches and handles this error, waiting for a minimal time period and trying again.
But this feels kind of wrong. So I am also open to suggestions for a “proper” solution.
EDIT: The "proper" solution would be using a DBMS Server (as stated in the comments below). I'm aware of this. For now, I have to deal with this design mistake without being responsible for it. Also, I can't change it in the short run.
I write this as an aswer because of space but this is not really an answer.
It's for sure an OleDb provider issue.
I think that is a sharing issue.
You could do some tries:
use a newer OleDb provider instead of Microsoft.Jet.OLEDB.4.0. (if you have try 64 bits you could already have try another provider because Jet.OLEDB.4.0 is 32 bits only)
Implement a retry mechanism on the new DbContext()
Reading your tests this is probaly not your case. I THINK that Dispose does not always work properly on Jet.OLEDB.4.0 connections. I noted it on tests and I solved it using a different testing engine. Before giving up I used this piece of code
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced, true);
GC.WaitForPendingFinalizers();
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced, true);
As you can understand reading this code, they are tries and the latest solution was changing the testing engine.
If your app is not too busy you could try to lock the db using a different mechanism (for example using a lock file). This is not really different from new DbContext() retries.
In late '90s I remember I had an issue related to disk sharing OS (I were using Novel Netware). Actually I have not experience in using mdb files on a network share. You could try to move the mdb on a folder shared with Windows
Actually I use Access databases only for tests. If you really need to use a single file database you could try other solutions: SQL Lite (you need a library, also this written by me, to apply code first https://www.nuget.org/packages/System.Data.SQLite.EF6.Migrations/ ) or SQL Server CE
Use a DBMS Server. This is for sure the best solution. As the writer of JetEntityFrameworkProvider I think that single file databases are great for single user apps (for this apps I suggest SQL Lite), for tests (I think that for tests JetEntityFrameworkProvider is great), for transfering data or, also, for readonly applications. In other cases use a DBMS Server. As you know, with EF, you can change from JetEntityFrameworkProvider to SQL Server or to MySql without effort.
You went wrong at the design stage: The MS Access database engine is unfit for ASP.Net sites, and this is explicitly stated on multiple places, e.g. the official download page under details.
The Access Database Engine 2016 Redistributable is not intended .... To be used by ... a program called from server-side web application such as ASP.NET
If you really have to work with an Access database, you can run a helper class that retries in case of common errors. But I don't recommend it.
The proper solution here is using a different RDBMS which exhibits stateless behavior. I recommend SQL Server Express, which has limitations, but if you exceed those you will be far beyond what Access supports, and wont cause errors like this.

How to construct ConnectionStrings

Could you explain me how to construct correct ConnectionStrings? I mean that one you can find in web.config file in MVC project. I understand that if you want to add a new connection string you have to write <add ... /> XML tag with parameters such as name, connectionString (it is the most interesting parameter for me) and providerName (perhaps some else?). What each parameter does and means? How to construct connectionString parameter? Where is the db engine indicated?
The questions above are only examples. I care about collecting the most amount of information about constructing ConnectionStrings.
Starting from NET 2.0 you have at your disposal a class named SqlConnectionStringBuilder
Its purpose is to help building dynamically the connection string. But the various properties available explain in great detail the functionality underlying to each possible setting
The SqlConnectionStringBuilder class is derived by a base class named DbConnectionStringBuilder and this allows all the ADO.NET provider to implement their own version of this class. In the link provided there are the references relative to other ADO.NET providers
If you are trying to construct entity framework connection string just use as follows.It will help you..
string connectionString = new System.Configuration.ConfigurationSettings.AppSettings["ConnectionString"]);
System.Data.SqlClient.SqlConnectionStringBuilder scsb = new System.Data.SqlClient.SqlConnectionStringBuilder(connectionString);
EntityConnectionStringBuilder ecb = new EntityConnectionStringBuilder();
ecb.Metadata = "res://*/Sample.csdl|res://*/Sample.ssdl|res://*/Sample.msl";
ecb.Provider = "System.Data.SqlClient";
ecb.ProviderConnectionString = scsb.ConnectionString;
UPDATED:
The easiest way to get the connection string is using the Server explorer window in Visual Studio (View-->Server Explorer menu) and connect to the server from that window. Then you can see the connection string in the properties of the connected server (F4 with your connection selected).
If you create the database in SQL Server Management Studio, that database will be created in a server instance, so that, to deploy your application you'll have to make a backup of the database and deploy it in the deployment SQL Server. Alternatively, you can use a data file using SQL Server Express (localDB in SQL Server 2012), that will be easily distributed with your app.
I.e. if it's an ASP.NET app, there's an App_Datafolder. If you right click it you can add a new element, which can be a SQL Server Database. This file will be on that folder, will work with SQL Express, and will be easy to deploy. You need SQL Express installed on your machine.

The underlying provider failed on open entity framework

I am unsing entity framework in my web application. Earlier everything was working fine. But then I deleted database from Sql Server. After that whenever I run the application, I get the following exception :
The underlying provider failed on open entity framework
Isn't it true that if we delete the database from Sql Server and again run the application, database is again created?
Can you show some details about connection string. I basically want to check the authentication you are using.
Demo for setting a typical authentication : http://msdn.microsoft.com/en-us/library/ff649314.aspx
Another possibility can be with connection pooling. Try explicitly closing the connection(if there are any open connections)
db.Database.Connection.Close();
Entity framework will recreate your database on application start assuming the following:
You have permission to create databases in SQL
A connection string is specified correctly (if it was working before this should be fine)
You are using CodeFirst or ModelFirst strategies for databases (ie if you generated an EDMX off an existing database it wont recreate it for you)
I had a similar error and it was due to the connection problem.
Usually you need to open your *.EDPS file under your entity (EDML) and check your connection string and make sure it has got a correct setting especially your Default Oracle home.

What does error ORA-12571 (TNS:packet writer failure) mean in a Web Service?

Background: I'm calling a Web Service written in ASP.NET that queries an Oracle database. I know the Web Service itself works, because I've used it before other applications. So I have a web application in Visual Studio that I've been switching back and forth to point from a 'DEV' web service to a production configured version of the same web service for testing. Pointing to the 'DEV' configured web service is no problem, but calling the production version I always get an exception calling the service:
SoapException was unhandled by user code
Server was unable to process request. ---> could not execute query
[ SELECT this_.FIELD1 as FIELD1_18_0_, this_.FIELD2 as FIELD12_18_0_ FROM ABC.TABLE_A this_ WHERE this_.FIELD1 like :p0 ORDER BY this_.FIELD1 asc ]
Positional parameters: #0>00073%
[SQL: SELECT this_.FIELD1 as FIELD1_18_0_, this_.FIELD2 as FIELD12_18_0_ FROM ABC.TABLE_A this_ WHERE this_.FIELD1 like :p0 ORDER BY this_.FIELD1] ---> ORA-12571: TNS:packet writer failure
I ran the SQL queries against the appropriate database (cut and pasted straight out of the exception message) and the query came back with the expected data. I've tried updating and re-adding the Web Service reference both as a "Service Reference" (.NET 3.0+ way) and as a "Web Reference" (Older .NET way), and both give the same error.
Question: So, what does a "ORA-12571: TNS:packet writer failure" error mean in the context of a Web Service? Looking up the Oracle Error number gives some very vague possible causes such as "loose cable connection" or "IP address conflict". I'm fairly certain it's neither of these, since a different application is currently successfully using that Web Service. Possibly some kind of configuration error, or maybe something more subtle? Anyone else seen this vexing Oracle error number being attributed to something web-service related?
Your call is going from the ws client to the ws server to the oracle database.
Your error is an ORA error, which is generated by the database. So your problem is probably between the ws server and the database.
When you ran "the SQL queries against the appropriate database", did you do it from the web server? If not could you try that. Make sure that you are using the same connection configuration.
EDIT
As per the comment below, the real problem was a driver mismatch.
I would suggest re-examining your assumptions more carefully, as this is clearly an error in the web-service dialogue with the db and should be completely independent of the w/s caller.
If the w/s call is generating this specific exception, it should be doing so for all other invocations, so your 'other application' that's using the web service successfully is simply not executing the same code or there are outside factors at play.
Either way, it's unrelated to how the service is registered or invoked.

Resources