How to get DB instance status via .net - c#

Is there any way to check DB instance is up or not. It is like health check monitoring. I need to connect to Database server using c# .net and should check the DB instance status and display the results.

Why not just try connecting to the DB and see if it's up or not like
public string GetDBStatus(string connectionString)
{
string status = string.Empty;
try
{
//connecting to your DB
status = "Up";
}
catch(Exception ex)
{
status = "Down";
//log error to somewhere
}
return status;
}

Related

C# Connecting to Rest Service to retrieve information

I’m relatively new to c# and working with API’s. I’ve created a simple windows form in VS and I’m trying to connect t a rest service to retrieve information based on a search condition (e.g ID number) and display everything in a data grid. I’ve been looking for examples of what I’m trying to achieve with very little success. The idea is to enable a user to enter an ID number inside a text box and click a “search” button which will then connect to the rest service and retrieve all the information related to that specific ID number and display it all in a data grid with column names. Is this possible? Can anyone advise me on how to establish my connection to the rest service?
Try this. Path1 is your connection:
The Class ApiResult is just a class with a List of ArticleApiModel.
public static List<ArticleApiModel> GetArticles (int id)
{
try
{
var task = Task<List<ArticleApiModel>>.Run(async () =>
{
using (HttpClient client = new HttpClient())
{
var response = await client.GetAsync(path1 + "/api/articles/",id);
if (response != null)
{
var jsonString = await response.Content.ReadAsStringAsync();
var result = JsonConvert.DeserializeObject<ApiResult>(jsonString);
return result.Result;
}
}
return null;
});
task.Wait();
return task.Result;
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
return null;
}

Terminating a function after a specified time

Im working on an EConnect integration Windows form app in C#. Im having a lot of trouble testing my connection string. Basically I give the user the option to change the connection string so I want to be able to test it. As far as I know EConnect doesnt have any built in functions that test the connection so I'm writing a pretty crude function to do it myself. Just for everyones information the connection string consists of a server name that the GP databases are located on and a database name.
The particulars of the actual test function I dont think are that important but the main issue is within that function I call an eConnect method called getEntity, this method uses the connection string and if the connection string is right it will pull information. If the database name is wrong the getEntity method will return an eConnect exception which is easy enough to catch, however if the server name is wrong the getEntity method will just spin and my app gets stuck.
Im trying to write something where I can possibly run my test function asynchronously and simultaneously check for a timeout or the econnect exception. This is where I get stuck, I cant for the life of me get it to work. Here is the first thing I tried (this is in my TestConnection method):
task = Task.Factory.StartNew(() => requester.GetEntity(GPCongfigSettings.GPConnectionString, myXmlDocument.OuterXml), token);
try
{
if (!task.Wait(timeOut, token))
{
Console.WriteLine("The server name is incorrect - task timed out");
return false;
}
}
catch (ThreadInterruptedException)
{
return false;
}
catch (AggregateException ae)
{
ae.Handle((x) =>
{
if (x is eConnectException) // This we know how to handle.
{
Console.WriteLine("Incorrect Database Name! -- " + x.Message);
return false;
}
return false; // Let anything else stop the application.
});
}
This would catch the cases where the server was wrong and if my econnect method would just time out. But it never caught the eConnect exception, Visual Studio would break the app and tell me I had an unhandled exception.
Here is what Im trying now, this is the full class I have for my form. Here I'm trying to use IAsyncResult and using a WaitHandle to check to see if the function completes or times out. This seems to work sometimes, it works for a correct string and for when the database is wrong, and sometimes it works for when the server is wrong, but once I test for a wrong server name it doesnt work correctly for anything else anymore. Is there something I'm missing or is there a better way to run the getentity method in TestGPConnection and check to see if it hasnt completed after a certain time period and if it hasnt kill that method and have the user reenter a server name?
public partial class UpdateGPConnection : Form
{
Task task;
AsyncCallback cb;
public delegate string startProcessToCall();
startProcessToCall sp2c;
public UpdateGPConnection()
{
InitializeComponent();
this.txtDatasourceName.Text = ConfigurationManager.AppSettings.Get("GPDataServer");
this.txtDatabaseName.Text = ConfigurationManager.AppSettings.Get("GPDatabase");
cb = new AsyncCallback(startProcessCallback);
sp2c = new startProcessToCall(TestGPConnection);
}
public void startProcessCallback(IAsyncResult iar)
{
startProcessToCall mc = (startProcessToCall)iar.AsyncState;
bool result = mc.EndInvoke(iar);
Console.WriteLine("Function value = {0}", result);
}
private void btnUpdate_Click(object sender, EventArgs e)
{
var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
config.AppSettings.Settings["GPDataServer"].Value = txtDatasourceName.Text.ToUpper();
config.AppSettings.Settings["GPDatabase"].Value = txtDatabaseName.Text.ToUpper();
config.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection("appSettings");
GPCongfigSettings.GPConnectionString = #"data source=" + txtDatasourceName.Text.ToUpper() + ";initial catalog=" + txtDatabaseName.Text.ToUpper() + ";integrated security=SSPI;persist security info=False;packet size=4096";
IAsyncResult asyncResult = null;
asyncResult = sp2c.BeginInvoke(cb, null);
timer1.Enabled = true;
Thread.Sleep(0);
bool test = asyncResult.AsyncWaitHandle.WaitOne(15000);
if (test)
{
try
{
string testResult = sp2c.EndInvoke(asyncResult);
}
catch (Exception exc)
{
Console.WriteLine(exc.Message);
}
}
bool result = asyncResult.IsCompleted;
asyncResult.AsyncWaitHandle.Close();
this.Close();
}
public string TestGPConnection()
{
eConnectMethods requester = new eConnectMethods();
try
{
// Create an eConnect document type object
eConnectType myEConnectType = new eConnectType();
// Create a RQeConnectOutType schema object
RQeConnectOutType myReqType = new RQeConnectOutType();
// Create an eConnectOut XML node object
eConnectOut myeConnectOut = new eConnectOut();
// Populate the eConnectOut XML node elements
myeConnectOut.ACTION = 1;
myeConnectOut.DOCTYPE = "GL_Accounts";
myeConnectOut.OUTPUTTYPE = 2;
myeConnectOut.FORLIST = 1;
myeConnectOut.WhereClause = "(ACTNUMST = '99-9999-99-999')";
// Add the eConnectOut XML node object to the RQeConnectOutType schema object
myReqType.eConnectOut = myeConnectOut;
// Add the RQeConnectOutType schema object to the eConnect document object
RQeConnectOutType[] myReqOutType = { myReqType };
myEConnectType.RQeConnectOutType = myReqOutType;
// Serialize the eConnect document object to a memory stream
MemoryStream myMemStream = new MemoryStream();
XmlSerializer mySerializer = new XmlSerializer(myEConnectType.GetType());
mySerializer.Serialize(myMemStream, myEConnectType);
myMemStream.Position = 0;
// Load the serialized eConnect document object into an XML document object
XmlTextReader xmlreader = new XmlTextReader(myMemStream);
XmlDocument myXmlDocument = new XmlDocument();
myXmlDocument.Load(xmlreader);
string reqDoc = requester.GetEntity(GPCongfigSettings.GPConnectionString, myXmlDocument.OuterXml);
return "Correct Connection";
}
catch (eConnectException exc)
{
Console.WriteLine(exc.Message);
return "eConnect Excpetion";
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return "Excpetion";
}
}
private void btnExit_Click(object sender, EventArgs e)
{
this.Close();
}
}
You are not handling the eConnectException. You are showing a message in the Console and then essentially rethrowing the exception by returning false.
If you do handle an exception then you should return true to avoid rethrowing it:
catch (AggregateException ae)
{
ae.Handle((x) =>
{
if (x is eConnectException) // This we know how to handle.
{
Console.WriteLine("Incorrect Database Name! -- " + x.Message);
}
return x is eConnectException; //rethrow anything that is not an eConnectException
});
}

Exception handling (I want to check if the connection.Open() runs)

I'd like my code to give a warning or something whenever the database is not available.
(That's why I commented the connection string), but my website just crashes.
I created this class cause there were many parts of the program using this connection string (login page, register page, user panel page, etc), so if I want to change something in the future, this is the only string I have to change.
namespace Fatture.Data.User
{
public class DbConnection
{
public MySqlConnection ConnessioneDb()
{
MySqlConnection conn = new MySqlConnection(/*ConfigurationManager.ConnectionStrings["ConnectionStringloginDb"].ConnectionString*/);
try
{
conn.Open();
}
catch (Exception ex)
{
throw new Exception("I can't connect to the database", ex);
}
return conn;
}
}
}
Use exception handling...
var connector = new DbConnection();
try
{
var connection = connector.ConnessioneDb();
}
catch (Exception ex)
{
// show message to user: database not available
}
Though you'll have to put this in place everywhere you access the database. Instead you can also just set up error handling for your entire site.
Catch the exception...
try
{
var conn = new DbConnection().ConnessioneDb();
}
catch (Exception ex)
{
// Notify user here
}

Connect to server with connect async

Is there any possible that I can ensure that the application does not fall if app can not connect to the server using await socket.ConnectAsync(server) I get this exc:
But the biggest problem is I get this exception only occasionally and randomly. Try and catch completely unresponsive and applications fall. So I need something if I cannot connect firts time dont go to exception but try it again.
My code:
public async Task _connect(string token, string idInstalation, string lang)
{
try
{
if (token != null)
{
socket.SetRequestHeader("Token", token);
socket.SetRequestHeader("Lang", lang);
socket.SetRequestHeader("idInstallation", idInstalation);
}
await socket.ConnectAsync(server);
System.Diagnostics.Debug.WriteLine("Connected");
writer = new DataWriter(socket.OutputStream);
messageNumber = 1;
}
catch (Exception)
{
var dialog = new MessageDialog("Cannot connect to UNIAPPS server", "Error").ShowAsync();
}
}

Testing an Entity Framework database connection

I have an app that connects to a MYSQL database through the entity framework. It works 100% perfectly, but I would like to add a small piece of code that will test the connection to the database upon app startup.
I had the idea of simply running a tiny command to the database and catching any exceptions, however if there is a problem (eg App.Config missing or Database server down) the app takes a huge amount of time to run this code and then throw the exception (~1 min). I imagine this is due to connection timeouts etc but I have fiddled with such properties to no avail.
Would anyone be able to assist with any ideas as to where to go?
Are you just wanting to see if the DB connection is valid? If so take a look at the
using (DatabaseContext dbContext = new DatabaseContext())
{
dbContext.Database.Exists();
}
http://msdn.microsoft.com/en-us/library/gg696617(v=vs.103).aspx
and for checking if a server machine is up, DB server or web services server , try this:
public PingReply Send( string hostNameOrAddress )
http://msdn.microsoft.com/en-us/library/7hzczzed.aspx
The solution as #Danilo Breda pointed out is to call the DbContext.Database.Connection.Open()
It is tested with EF6.
My implementaion:
public static bool CheckConnection()
{
try
{
MyContext.Database.Connection.Open();
MyContext.Database.Connection.Close();
}
catch(SqlException)
{
return false;
}
return true;
}
In EntityFramework Core you can simply call: Database.CanConnect();.
(using EF Core 2.2.1)
Summary: Determines whether or not the database is available and can be connected to.
Note that being able to connect to the database does not mean that it is up-to-date with regard to schema creation, etc.
I use this code for my project:
private bool TestConnectionEF()
{
using (var db = new SistemaContext())
{
db.Database.Connection.Open();
if (db.Database.Connection.State == ConnectionState.Open)
{
Console.WriteLine(#"INFO: ConnectionString: " + db.Database.Connection.ConnectionString
+ "\n DataBase: " + db.Database.Connection.Database
+ "\n DataSource: " + db.Database.Connection.DataSource
+ "\n ServerVersion: " + db.Database.Connection.ServerVersion
+ "\n TimeOut: " + db.Database.Connection.ConnectionTimeout);
db.Database.Connection.Close();
return true;
}
return false;
}
}
I know this is an old question, but here is my answer for anyone looking for a newer implementation.
I was able to use CanConnect to check the status of the database:
_database.Database.CanConnect();
# Async too
await _database.Database.CanConnectAsync(_cancellationTokenSource.Token);
I hope this helps others as well. Cheers!
I used the answer from #Sandor and did an extension method to use with EntityFramework Core.
Here's the code:
using Microsoft.EntityFrameworkCore;
using System.Data.Common;
namespace TerminalInventory
{
public static class ExtensionMethods
{
public static bool TestConnection(this DbContext context)
{
DbConnection conn = context.Database.GetDbConnection();
try
{
conn.Open(); // Check the database connection
return true;
}
catch
{
return false;
}
}
}
}
Now you just have to call:
if (!context.TestConnection())
{
logger.LogInformation("No database connection. Check the connection string in settings.json. {0}", configuration["connectionString"]);
return;
}
I am using the following code for MS SQL connection. Maybe, it will be useful for MySQL too. You don’t even need to use an EF or EF Core.
public bool IsDbConnectionOK()
{
SqlConnectionStringBuilder conStr = new SqlConnectionStringBuilder
{
DataSource = ButtonServerName.Text, // <-- My Form Elements
InitialCatalog = ButtonDBName.Text, // <-- My Form Elements
UserID = EditUserName.Text, // <-- My Form Elements
Password = EditPassword.Text, // <-- My Form Elements
IntegratedSecurity = false,
ConnectTimeout = 30
};
string connectionstring = conStr.ToString();
try
{
using (System.Data.SqlClient.SqlConnection connection = new System.Data.SqlClient.SqlConnection(connectionstring))
{
connection.Open();
return true;
}
}
catch (System.Data.SqlClient.SqlException ex)
{
MessageBox.Show(ex.Message + Environment.NewLine +
"Error line: " + ex.LineNumber + Environment.NewLine +
"Procedure name: " + ex.Procedure);
return false;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
return false;
}
}

Categories