How to determine whether a web application is currently running - c#

I have a ASP.NET web application running under IIS 6, and another process that is responsible to monitor and report status.
I'd like to sample the web application by the monitoring process in order to check its status by accessing a dedicated handler on the web application, BUT i don't want to "wake up" the web application in case it is not running.
Is there an option to determine whether a specific web application is currently running? if there is such an option, i would be able to first check if the application is running, and only then to access the handler to check its status.
Thanks.

I had to do something similar earlier this year for IIS7, not sure if this would work for IIS6 but here's what I did.
var iis = new DirectoryEntry("IIS://" + Environment.MachineName + "/w3svc");
foreach (DirectoryEntry site in iis.Children)
{
if (site.SchemaClassName.ToLower() == "iiswebserver")
{
Console.WriteLine("Name: " + site.Name);
Console.WriteLine("State: " + site.Properties["ServerState"].Value);
}
}
ServerState returns 2 for started and 4 for stopped.

You can use the HTTP HEAD request to check if the site is up or not. Here is an example to do the same.
http://www.eggheadcafe.com/tutorials/aspnet/2c13cafc-be1c-4dd8-9129-f82f59991517/the-lowly-http-head-reque.aspx

I would include in the ASP.NET website an asmx file, a web service with a simple Ping function, but it will still wake up the application pool of the website.

You could analyse the IIS log file, to see if there are recent entries.
If your application is not used much, it is possible the latest "entry" still needs to be flushed.
Or you could update a file/database to indicate "still active".
If you really do not want a delay, in the Application_Start and Application_End, create and destroy a system mutex.

This is my solution:
try
{
WebRequest request = WebRequest.Create("http://localhost/");
WebResponse response = request.GetResponse();
}
catch (WebException ex)
{
// ex.Status will be WebExceptionStatus.ConnectFailure
// if the site is not currently running
}

We used to use Nagios to monitor our site and it would target the favicon of our website. If it could pull back the icon, we knew the site was up.

Related

ASP .Net MVC Download Error and Require to Recycle IIS Application Pool

I currently maintain a nearly 3 years old ASP .Net MVC website, the application is running above IIS (now in IIS 7) and using ASP .Net 4 Framework. It used by client almost everyday and had a lot of upload-download file transaction. It also use ELMAH as Unhandled Exception Handling. The application running well until a few past month, there are a lot of report from user that they cannot do download the file, but without any error message, the download process just not doing anything while there is also no log in Browser Console. After doing several checking, all menu that have download function are using http response
Response.Clear();
Response.Cache.SetCacheability(HttpCacheability.Private);
Response.Expires = -1;
Response.Buffer = true;
Response.ContentType = "application/octet-stream";
Response.AddHeader("Content-Length", Convert.ToString(file_in_bytes.Length));
Response.AddHeader("Content-Disposition"
, string.Format("{0};FileName=\"{1}\"", "attachment", fileName));
Response.AddHeader("Set-Cookie", "fileDownload=true; path=/");
Response.BinaryWrite(hasil);
Response.End();
And nothing seems wrong (there are no Compile or Runtime Error in Development Server). We've also checked Elmah's log, but there no related error message appear in there. And This problem is temporarily disappear after our Server Management Team do Recycling the Application Pool in IIS.
This Web is also share Application Pool with another web, and when that error occurred, both application are affected, only the download function that affected, the other function like data retrieval from database, insert/edit/delete data is working fine.
I also checked the Web Server Event Viewer but there is nothing error in there. The very odd thing for us is that this error temporary disappear after we Recycling the Application Pool and after several days or weeks or months the error suddenly appear again.
Is there any log that we've missed to trace? or perhaps there is wrong with the Download code? And why its temporarily fixed after Recycling Application Pool?
Another Note : The data that need to be download by user is at average 500kb to 2MB in zip format contains several PDF files
Update : After few more hour investigating, I found that this web application using different method to Download, some are using the Http.Response like above code, and some are use FileContentResult as return value. But both using jquery.FileDownload in client-side. I also found this method in several Controller that has Download File method in this app,
private void CheckAndHandleFileResult(ActionExecutedContext filterContext)
{
var httpContext = filterContext.HttpContext;
var response = httpContext.Response;
if (filterContext.Result is FileContentResult)
{
//jquery.fileDownload uses this cookie to determine that
//a file download has completed successfully
response.AppendCookie(new HttpCookie(CookieName, "true")
{ Path = CookiePath });
}
else
{
//ensure that the cookie is removed in case someone did
//a file download without using jquery.fileDownload
if (httpContext.Request.Cookies[CookieName] != null)
{
response.AppendCookie(new HttpCookie(CookieName, "true")
{ Expires = DateTime.Now.AddYears(-1), Path = CookiePath });
}
}
}
Actually I'm not really sure is that method related to this error or not, but it is called in a method that override System.Web.MVC.Controller OnActionExecuted, and it contain the line off adding Cookie for file download if using FileContentResult or delete Cookie if is not using FileContentResult and file Download Cookie is exists. It is Possible if Cookie is Accidentally not deleted / cleared after it created? And because the download method is frequently called by nearly 100 user everyday, it is possible that the Cookie is pile up and cause IIS Worker Process Crash?
I've also checked some references about Cookie and its relation to IIS Session State (My Apps using In-Proc State). Am I Close? Or did I miss something?
Is there a reason why Response.Buffer is set to true? When buffering is enabled, the response is sent only after all processing is completed. Can you disable it by setting to false and see if this works? This could be the reason for having to recycle the app pool. You can also check if you are facing these issues - Help link

How to verify network files and folders from IIS applications

We have an Intranet web application (ASP.NET 4.5) on SERVER-B. It's on the same domain as SERVER-A. How can I check if a file exists on SERVER-A from the Intranet application? I tried using File.Exits/Directory.Exis, FileWebRequest, cannot get it to work. Is there an IIS setting to allow?
Note: I can browse the files on Server-A from Server-B using file explorer.
Note: HttpWebRequest 'does' work for finding files on our external website but that method does not work for our intranet to network.
Method A (result is always false)
File.Exists("\\xyz-123\Shipping\State\ca.doc")
Directory.Exists("\\xyz-123\Shipping\State")
Method B (result is always false and doesn't return an error)
'url = "file://xyz-123/Shipping/State/ca.doc"
Private Function FileExist(url As String) As Boolean
Dim response As WebResponse = Nothing
Try
Dim request = DirectCast(WebRequest.Create(url), FileWebRequest)
request.Method = "HEAD"
response = DirectCast(request.GetResponse(), WebResponse)
FileExist = True
Catch ex As Exception
Finally
If response IsNot Nothing Then response.Close()
End Try
End Function
The Method A will work if you share the \\xyz-123\Shipping\State folder with the user running the code.
Almost certainly your problem is permissions related. Your IIS website runs as an "IIS Application" belonging to an Application Pool in IIS. That Application Pool has a windows login associated with it. That login needs to have permission to acces the files on the second machine.
To fix the problem, look at the application pool setup in IIS and find out what user the application pool is running under, and change the permissions on the file share to allow them access. To debug this you can try assigning your own credentials to the IIS Application Pool your website is running under and you might find it works, becasue you personally do have rights to access the files.

How to Programatically Start IIS 6.0 SMTP Virtual Server?

I would like to know how to programatically restart IIS 6.0 SMTP server.
The SMTP server I have setup crashes every now and then. I don't notice it for a couple days, but that is by far way too late to do anything about it.
I want to set up a scheduled task every 30 minutes or so to test if the SMTP server is running, and if its not, the Scheduled task with automatically start it back up.
I have found a way to check if the SMTP server is up and running, but I have not figured out how to restart the process if it crashes.
That way is posted here: Testing SMTP server is running via C#
Any help would be brilliant!
Thank you.
Im developing the Console application in C# to check if its running or not, so any code examples would be great too.
A ServiceController can help you, as it has start and stop methods. Look at the sample in the msdn page.
Another sample is taken from the ServiceControllerStatus Enumeration is nearly what you need (just replace the service name).
ServiceController sc = new ServiceController("Telnet");
Console.WriteLine("The Telnet service status is currently set to {0}",
sc.Status.ToString());
if ((sc.Status.Equals(ServiceControllerStatus.Stopped)) ||
(sc.Status.Equals(ServiceControllerStatus.StopPending)))
{
// Start the service if the current status is stopped.
Console.WriteLine("Starting the Telnet service...");
sc.Start();
}
else
{
// Stop the service if its status is not set to "Stopped".
Console.WriteLine("Stopping the Telnet service...");
sc.Stop();
}
// Refresh and display the current service status.
sc.Refresh();
Console.WriteLine("The Telnet service status is now set to {0}.",
sc.Status.ToString());
Maybe I'm missing something, or something changed, but when you install SMTP service on Windows 2012R2, there is no dedicated service for it. So, for recent version of Windows the advice above won't work.
Luckily there's a way to do it much easier. Powershell:
([ADSI]'IIS://LOCALHOST/SMTPSVC/1').Start() #to start
([ADSI]'IIS://LOCALHOST/SMTPSVC/1').Stop() #to ... you guess
The weirdest thing is that you control smtp service through AD, but it works.
And of course this should be run elevated.
If you have several virtual SMTP servers, you may need to identify your server by index or by some property (e.g. .ConnectionTimeout) first.
in c# you can write:
enum StatusVirtualServerSMTP
{
Started = 2,
Stopped = 4
}
DirectoryEntry dir = new DirectoryEntry("IIS://localhost/SMTPSVC/1");
if (Convert.ToInt32(dir.Properties["SERVERSTATE"].Value) == (int)StatusVirtualServerSMTP.Stopped)
{
dir.Properties["SERVERSTATE"].Value = (int)StatusVirtualServerSMTP.Started;
dir.CommitChanges();
}

How to ping URL from code behind

I have one issue that i want to ping URL from code behind (EXE project) by which i can know environment of Azure application on which my EXE is running.
string dep = RoleEnvironment.DeploymentId.ToString();
WebRequest req = WebRequest.Create("http://" + dep + ".cloudapp.net");
HttpWebResponse rep= null;
try
{
rep = (HttpWebResponse)req.GetResponse();
}
catch (Exception)
{
//if environment is production then this URL will not work
//do some functionality
}
So by above code i would like to do some functionality when it will production environment
,above logic is works well but would like to get some perfect solution like ping command that if URL exist then return true otherwise false.
Please suggest me some good logic here
Thanks in advance.
No, I don't think that will work - if you have production code running then the check will always be successful, even if you call it from staging.
Check the answer to this:
Azure Detect Staging vs Production
which provides a more robust answer to your real question.
How about initiating a socket that tries to connect to the server over port 80 (HTTP)?
that'll be a good indication whether the site is up or not.
The only way to "ping" a resource is to get an error code. just make sure it's just a get operation so that no change occurs on the server.
You know when you deploy whether the app is deployed to live or test/staging so why don't you just set something on the web.config. Then you can just do
If (ConfigurationManager.AppSettings["Envirmonment"] == "Live")
{
//do live stuff
}
else
{
//do testing stuff.
}

Asp.net web app shows me as the logged in user on someone elses pc

OK, I really don't know what to search for this, so hopefully someone can help me.
I've just published an asp.net web application, and after much messing about finally got it to load in my browser.
The issue however is that when I got my mate who is sitting next to me to open the site in his browser, the page showed me as the logged in user.
In the default.aspx I run some code that grabs the users windows identity
LDAPDetails LDAPUser = new LDAPDetails(WindowsIdentity.GetCurrent().Token);
LDAPDetails then does this.
_UserName = windowsId.Name.Substring(windowsId.Name.IndexOf('\\') + 1);
_DomainName = windowsId.Name.ToString().Remove(windowsId.Name.IndexOf('\\'));
//Get users information from active directory
DirectorySearcher search = new DirectorySearcher("LDAP://DCHS");
search.Filter = String.Format("(SAMAccountName={0})", _UserName);
SearchResult result = search.FindOne();
if (result != null)
{
_FullName = result.Properties["givenName"][0].ToString() + ' ' + result.Properties["sn"][0].ToString();
_Email = result.Properties["mail"][0].ToString();
_FirstName = result.Properties["givenName"][0].ToString();
_SSID = windowsId.User.ToString();
_errMsg = "";
}
These values are then put into session variables.
It seems that WindowsIdentity.GetCurrent().Token is still using my details even though its on a machine that i'm not logged into.
Thoughts?
Agree with Tim - WindowsIdentity.GetCurrent() will be executing on server and will return the windows user under which the server process (worker process in IIS) is running which happens to be your account.
What you need to do is to set up windows/integrated authentication in both IIS and ASP.NET (web.config) and then use HttpContext.Current.User.Identity instead of WindowsIdentity.GetCurrent().
The Web application is running on a web server that you are logged into (probably your machine), so the code WindowsIdentity.GetCurrent().Token is executed on the web server, and of course that will return your credentials.
There are a bunch of different mechanisms for Web app authentication, you need to do some googling.
You are likely getting the identity of the process running on the server. If you are using IIS, this is the account setup in the application pool. Follow the instructions at this MSDN link http://msdn.microsoft.com/en-us/library/aa292114(v=vs.71).aspx for configuring Integrated Windows Authentication on IIS.
Have you tried using User.Identity.Name to get the user name?
It uses the IIdentiy interface

Categories