Elmah works on localhost, but not on production? - asp.net-mvc-3

In my ASP.NET MVC 3 app, I've configured Elmah, and then Elmah.MVC for error logging. Both of which log just fine when running on localhost (Windows 7, IIS 6.1). On a production server (2008 R2, IIS 6.1), no errors are logged. I can browse to the /elmah directory in the site without problem (I've allowed remote access for now.) I've set the proper permissions to a folder for XML logging but nothing logged. I back-tracked to use the "in memory" logger, still no log. I've made sure modules and handlers were referenced correctly in both system.web and system.webserver.
I've browsed a lot of posts related to Elmah config issues, permissions, etc., but have not yet found the cause of this.
Are there other security/permissions issues that I'm missing on the production server related to Elmah? What else could be causing this?

Make sure you do NOT have "Read Only" checked on the folder. thanks

Not sure if this is still current but I was having a similar issue: it all worked perfectly on my local computer and on the web server when you had customErrors mode="Off" but if you changed customErrors to RemoteOnly then it would only work if you accessed the website locally.
The solution was to add a new Elmah filter on the FilterConfig section that guarantees elmah will always log the errors regardless of the customErrors mode. Here is the post with details: http://forums.asp.net/t/1687875.aspx?Elmah+Error+Log+is+not+working+my+production+Server
Here is the code snippet (credit to the person on the post):
public class FilterConfig {
public static void RegisterGlobalFilters(GlobalFilterCollection filters) {
filters.Add(new ElmahHandledErrorLoggerFilter());
filters.Add(new HandleErrorAttribute());
}
}
public class ElmahHandledErrorLoggerFilter : IExceptionFilter {
public void OnException(ExceptionContext context) {
//if (context.ExceptionHandled) // Log only handled exceptions, because all other will be caught by ELMAH anyway.
//We want elmah to log ALL exceptions
ErrorSignal.FromCurrentContext().Raise(context.Exception);
}
}

Related

Web API works locally but doesn’t work on azure

I have created a web API connected to azure sql server in .net core using visual studio for Mac đź’». Then I created a web app in azure and then published by project directly in visual studio for Mac to azure.
After I published I try to access the api using postman and chrome (URL/api/menu) but I got 500 server error which is generic and doesn’t tell me anything.
In visual studio for Mac I got the green light it said published and directly took me to the new url.
So, what do you guys thing is the problem.
This is my first time using azure so I didn’t change any setting or anything
Since many different problems can cause this error page, I can strongly recommend the following in order to determine the root cause quickly and easily, without struggling with Azure (or any server/platform for that matter) to get logs.
You can enable extremely helpful error messages at startup by setting the .UseSetting("detailedErrors", "true") and .CaptureStartupErrors(true) actions in your Program.cs file.
For ASP.NET CORE 2.1
public class Program
{
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.CaptureStartupErrors(true)
.UseSetting("detailedErrors", "true")
.UseStartup<Startup>()
.Build();
}
Add these commands in your startup.cs class:
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
app.UseBrowserLink();
also enable stdoutLog in your web.config file
stdoutLogEnabled="true" stdoutLogFile=".\logs\stdout"
Error code 500 in web api,usually, means problems with a configuration in Startup.cs - the most common problems include an issue with DB itself, an issue with migrations (if you are using Code First approach), problems with appsettings.js.
Please refer to the log file in .\logs\stdout.
Hope it helps.

MiniProfiler with ASP.NET WebForms Classic Mode

We're trying to configure MiniProfiler with an ASP.NET WebForms app that runs in a classic mode app pool (cannot change it to integrated). We couldn't get the handlers to work so loading the resources failed.
To solve this we included the .js, .css, .tmpl, and .html from https://github.com/SamSaffron/MiniProfiler/tree/master/StackExchange.Profiling/UI After doing that these resources get loaded, but we still don't see anything.
The initialization script is rendered in the final html, but the ... block never gets generated. I'm assuming because the script never runs. We tried loading jQuery v1.7.1 and a newer version; neither worked.
There are no 404s or anything in the console (Chrome or FireFox). Any ideas? Thanks.
Are you having the issue running the profiler in IIS on your local machine or on a server?
The quick code sample on the miniprofiler.com site suggests wrapping the MiniProfile.Start() call in a Request.IsLocal condition (code below), this would prevent the profiler from being rendered on the server (unless you were viewing the page from the server itself). Try removing the Request.IsLocal code and see if that helps.
protected void Application_BeginRequest()
{
if (Request.IsLocal)
{
MiniProfiler.Start();
}
}

How to create a custom Maintenance page returning 503 for Azure?

I'm trying to set up a custom Maintenance page on MVC 3 but specifically on Azure. Basically to keep it SEO friendly i need to return a 503 (Service Unavailable). All my other custom error pages work in Azure (eg 404) following the usual
<customErrors mode="On">
<error statusCode="404" redirect="404.htm"/>
<error statusCode="503" redirect="503.htm"/>
</customErrors>
The 404 page works but the 503 is not followed and i simply get an ugly service unavailable page. I have the 500 error working fine through error.cshtml and the standard HandleErrorAttribute.
I even try returning my own ActionResult from an ActionFilter by using the following
public class SiteDownForTestingResult : ActionResult
{
public SiteDownForTestingResult() : base()
{
}
public override void ExecuteResult(ControllerContext context)
{
var path = System.Web.Hosting.HostingEnvironment.MapPath("~/app_testing.htm");
var response = context.HttpContext.Response;
response.Clear();
response.StatusCode = (int)HttpStatusCode.ServiceUnavailable;
response.StatusDescription = "Service Unavailable.";
response.WriteFile(path);
response.End();
}
}
were app_testing is my custom page, and then setting the filterContext.Result = new SiteDownForTestingResult(); from OnActionExecuting of an ActionFilter and still i'm greeted by the plain 503 'service unavailable' page
Is this something to do with application.config on Azure locking something or other i don't know about. This works fine on IIS7 and my local box, but the Emulator and Cloud both give no joy.
Any help would be appreciated.
Based on my understanding custom 503 error is generated directly from https.sys mostly when app pool is not available. And now when there is no app pool none of your setting is going to work at your custom error settings will be specific to app pool. Also most of the search engine depend on 503 error code in return so display search result properly and that's why customization of this error is not typically done at application level.
As you referenced Windows Azure Emulator, I believe you are using Windows Azure Web Role. With Windows Azure Web Role you can customize IIS with AppCmd.exe in a StartUp task, which is your maximum level of customization. You can not reach HTTP.sys level of customization in Windows Azure so customization 503 error may not work on Windows Azure.

IIS 7 Custom Error Page without Web.config

Is there any way to set a custom error page in IIS 7 without creating a web.config?
Unfortunately researching this particular topic has been very difficult because there are SO many articles on how to do it with a web.config. What I'm looking for is either buried beneath the 8 million results I don't want or it's not possible.
Yes, there is. It involves either subscribing to the Application_Error event in Global.asax or by writing a custom ErrorHandlerAttribute.
Darin already gave the correct answer, but I want to go into a little more depth.
In any ASP.NET application, given it is Web Forms, MVC, or raw ASP.NET, you can always use Application_Error Global.asax. If your ASP.NET application does not have a Global.asax, all you need to do is right-click your project in Solution Explorer, Add New Item, and choose Global Application Class. You should only have this option available if you don't already have one.
In your Global.asax, if you don't already see it, you can add Application_Error as shown below:
protected void Application_Error(object sender, EventArgs e) {
}
This will be called automatically by ASP.NET whenever there is an error. But as stated here, this is not perfect. Specifically:
An error handler that is defined in the Global.asax file will only
catch errors that occur during processing of requests by the ASP.NET
runtime. For example, it will catch the error if a user requests an
.aspx file that does not occur in your application. However, it does
not catch the error if a user requests a nonexistent .htm file. For
non-ASP.NET errors, you can create a custom handler in Internet
Information Services (IIS). The custom handler will also not be called
for server-level errors.
In Application_Error you can process the uncaught exception with Server.GetLastError(). This will provide you the Exception that was thrown, or null. I am not sure why this handler would be called if an exception didn't occur, but I believe that it is possible.
To redirect the user, use Response.Redirect(). Whatever you pass for the url is going to be sent directly to the browser without any further processing, so you can't use application-relative paths. To do that I would use this method in combination with VirtualPathUtility.ToAbsolute(). For example:
Response.Redirect( VirtualPathUtility.ToAbsolute( "~/Error.aspx" ) );
This redirect will be a 302 (temporary redirect) rather than a 301 (permanent), which is what you want in the case of handling errors. It's worth noting that this overload of Response.Redirect is the same as calling the overload Response.Redirect(url, endResponse: true). This method works by throwing an exception, which is not ideal in terms of performance. Instead, call Response.Redirect(url, false) immediately followed by Response.Complete​Request().
If you're using ASP.NET MVC, [HandleError] is also an option. Place this attribute on your Controller or on an Action within a controller. When this attribute is present, MVC will display the Error view, found in the ~/Views/Shared folder.
But you can make this even easier for yourself. You can automatically add this attribute to call Controllers in your project by creating a FilterConfig class in your project. Example:
public class FilterConfig {
public static void RegisterGlobalFilters(GlobalFilterCollection filters) {
filters.Add(new HandleErrorAttribute());
}
}
And then add FilterConfig.RegisterGlobalFilters( GlobalFilters.Filters ); to your Application_Start() in Global.asax.
You can read more about the HandleErrorAttribute at https://msdn.microsoft.com/en-us/library/system.web.mvc.handleerrorattribute(v=vs.118).aspx.
But as stated above, both of these methods will never cover absolutely all errors that can occur during the processing of your application. It's not possible to provide the best user experience for all possible errors without using Web.config or configuring IIS manually.

MVC3 Application Inside Webforms Application Routing is throwing a HttpContext.SetSessionStateBehavior Error in IIS7.5

I'm running a mixed MVC Application inside a sub folder of a web forms application.
Everything worked great in VS 2010 debug (Cassini) but when I deployed to IIS7.5
I got the following error:
'HttpContext.SetSessionStateBehavior' can only be invoked before
'HttpApplication.AcquireRequestState' event is raised.
It errors on the last line (httpHandler.ProcessRequest(HttpContext.Current);) in the default.aspx file of the MVC application sub folder.
public void Page_Load(object sender, System.EventArgs e)
{
string pathToRewriteTo = Request.Path.ToLowerInvariant().Replace("default.aspx", "Home/Index");
HttpContext.Current.RewritePath(pathToRewriteTo, false);
IHttpHandler httpHandler = new MvcHttpHandler();
httpHandler.ProcessRequest(HttpContext.Current);
}
However if I manually navigate to Home/Index from the MVC root folder I can see my application fine from there.
I've looked up the error being thrown and I only find answers dealing with server transfers and not MVC routes.
I have also already checked my IIS7.5 configuration for the route handling module, Application pool running in integrated mode, etc.
Any help would be appreciated.
We faced a similar issue. There are changes to MVCHttpHandler in MVC2 and above.
You need to change it to use httpContext.Server.TransferRequest.
Try the below snippet:
var httpContext = HttpContext.Current;
httpContext.Server.TransferRequest(Url, true); // change to false to pass query string parameters if you have already processed them

Resources