I am having a bit of an issue here. I have an MVC application that has been deployed to IIS 7 on Windows Server 2008. In Visual Studio 2012, whenever an internal server error occurs i.e. http 500, it shows the page I designed for it. However, when I deploy it to IIS, it shows a blank page which could be very annoying because one does not see the application's page at all. All I need is for the error page to display instead of the blank page that it currently displays as a deployed application in the client's site. I can then work on fixing the error in Visual Studio. Kindly pardon me if I broke any rules of S.O.
Here is what I have setup in my ErrorController.cs
public ActionResult ForbiddenPage()
{
Response.StatusCode = 403;
Response.TrySkipIisCustomErrors = true; // add this line
return View();
}
//
// GET: /Error/
public ActionResult PageNotFound()
{
Response.StatusCode = 404;
Response.TrySkipIisCustomErrors = true; // add this line
return View();
}
//
// GET: /Error/
public ActionResult InternalServerError()
{
Response.StatusCode = 500;
Response.TrySkipIisCustomErrors = true; // add this line
return View();
}
In web.config, this is what I have:
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<modules runAllManagedModulesForAllRequests="true" />
<handlers>
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." ...
</handlers>
<httpErrors errorMode="Custom" existingResponse="Replace">
<remove statusCode="403" />
<error statusCode="403" responseMode="ExecuteURL" path="/Error/ForbiddenPage" />
<remove statusCode="404" />
<error statusCode="404" responseMode="ExecuteURL" path="/Error/PageNotFound" />
<remove statusCode="500" />
<error statusCode="500" responseMode="ExecuteURL" path="/Error/InternalServerError"/>
</httpErrors>
</system.webServer>
My RouteConfig.cs Looks like this
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "LogIn",id = UrlParameter.Optional }
);
routes.MapRoute(
"403-ForbiddenPage",
"{*url}",
new { controller = "Error", action = "ForbiddenPage" }
);
routes.MapRoute(
"404-PageNotFound",
"{*url}",
new { controller = "Error", action = "PageNotFound" }
);
routes.MapRoute(
"500-InternalServerError",
"{*url}",
new { controller = "Error", action = "InternalServerError" }
);
The View that should be displayed is below:
#{
ViewBag.Title = "Internal Server Error";
Layout = "~/Views/Shared/_LayoutError.cshtml";
}
<h2></h2>
<div class="list-header clearfix">
<span>Internal Server Error</span>
</div>
<div class="list-sfs-holder">
<div class="alert alert-error">
An unexpected error has occurred.... click<a href ="/Home/LogIn"><i><u>here</u></i>
</a> to login again..
</div>
</div>
If there is any thing that I should have included to aid you in proffering a solution, please let me know in the comments.
Yes I found the solution,
Thanks ppittle, your link to Kev's answer helped. I tried the suggestion in the answer but it didn't work in my scenario. However, the link posted by Kev in the answer helped alot. What worked was the setting in the applicationHost.config in your production server [where IIS is].
Look for a file called applicationHost.config at this location:
C:\Windows\System32\inetsrv\config
Change the "overrideModeDefault" setting below from Deny to Allow.
This is what worked for me. Thanks StackOverflow!
I had this same issue, but didn't see this answer anywhere:
The user my application was running under didn't have permission to access the database that was configured in the web.config. There was no indication that this was the problem that I could find.
The way I found this was by deploying in DEBUG instead of Release, which then showed me the error message.
Related
I'm trying to set up 500 and 404 pages for an ASP.NET 4.5.2 Web Forms project. I've got the 404 working when the non-existent page is a .ASPX page. - I have code written to serve up a custom NotFound.aspx page in response.
My problem occurs when I am using the Web.config to serve up a 404.html page for non-existent HTML pages. My 404.html page is in the root folder. If I test this with a non-existent HTML page in the root folder, 404.html renders correctly. However, if I test it with a non-existent HTML page in a non-existent sub-folder, the 404.html is served up, but the CSS/JS paths are no longer correct? It's like it's treating the CSS/JS paths as being relevant to the non-existent sub-folder I'm specifying as part of the test?
Global.asax.cs:
void Application_Error(object sender, EventArgs e)
{
Exception ex = Server.GetLastError();
if (ex != null && ex is HttpUnhandledException)
{
Server.ClearError();
Server.Transfer("~/Error.aspx", true);
}
if (ex != null)
{
var httpException = ex as HttpException;
if (httpException.GetHttpCode() == 404)
{
Server.ClearError();
Server.Transfer("~/NotFound.aspx", true);
}
}
}
Web.config:
<httpErrors errorMode="Custom" existingResponse="Replace">
<remove statusCode="404" />
<error statusCode="404" path="404.html" responseMode="File" />
</httpErrors>
Use absolute URLs for the CSS/JS paths. For example, in your 404.html (bootstrap and jquery are just examples):
<link href="/Content/bootstrap.min.css" rel="stylesheet" />
<script src="/Scripts/jquery-3.0.0.min.js"></script>
<script src="/Scripts/bootstrap.min.js"></script>
Another setup would be to set responseMode="Redirect":
<httpErrors errorMode="Custom" existingResponse="Replace">
<remove statusCode="404" />
<error statusCode="404" path="/Errors/404.html" responseMode="Redirect" />
</httpErrors>
In this example, 404.html is in folder Errors and the URLs can be relative:
<link href="../Content/bootstrap.min.css" rel="stylesheet" />
<script src="../Scripts/jquery-3.0.0.min.js"></script>
<script src="../Scripts/bootstrap.min.js"></script>
and that will work because the redirect URL is no longer relative to whatever URL you've requested.
I was able to solve it as follows:
<httpErrors errorMode="Custom" existingResponse="Replace">
<remove statusCode="404" />
<error statusCode="404" path="http://localhost/myproject/404.html"
responseMode="File" />
</httpErrors>
The key takeaway is that the path must be absolute for this version to work. So my next step would be to try and set the path programmatically so that in debug mode it would go to my local and in release mode go to the production URL. I don't want to mess with Web.config transform files.
If anyone has any further info, please feel free.
I have the following code inside my action methods:-
public ActionResult ManageCustomerVLANs(string customerName)
{
if (!repository.IsCustomerExsists(customerName))
{
throw new HttpException(404, "Your error message");//RedirectTo NoFoundPage
}
And I have defined the following inside my web.config, to handle any 404 http code:-
<caching>
<outputCacheSettings>
<outputCacheProfiles>
<add name="NoCache" noStore="true" duration="0" varyByParam="*"/>
</outputCacheProfiles>
</outputCacheSettings>
</caching>
<!--<customErrors mode="RemoteOnly"/>-->
<customErrors mode="RemoteOnly">
<error statusCode="404" redirect="~/Home/" />
</customErrors>
But currently if the action method return “throw new HttpException”, nothing is actually returned and the execution will continue after this “throe new HttpException”.
so can anyone advice, how I can return an http 404 ?
You can return 404 like this.
return new HttpStatusCodeResult(HttpStatusCode.NotFound);
I am using HTTPContext.RewritePath for a path that has no extension and does not exist on the file system. I would like it to return my custom 404 page. I am using IIS 7.5, .Net 4, and Integrated Pipeline on Windows 7.
The rewrite happens in an HTTPModule called RewriteExampleModule. As shown below.
using System;
using System.Web;
public class RewriteExampleModule : IHttpModule
{
public RewriteExampleModule()
{
}
private void context_PostAuthorizeRequest(object sender, EventArgs e)
{
HttpContext context = ((HttpApplication)sender).Context;
String path = context.Request.RawUrl;
if (path.IndexOf("/edit/") > -1)
{
path = path.Replace("/edit/", "/");
context.RewritePath(path);
}
}
public bool IsReusable
{
get { return true; }
}
public void Dispose()
{
}
public void Init(HttpApplication context)
{
context.PostAuthorizeRequest += new EventHandler(context_PostAuthorizeRequest);
}
}
It is configured in the modules section as follows,
<modules runAllManagedModulesForAllRequests="true">
<add name="RewriteExampleModule" type="RewriteExampleModule" />
</modules>
The result of a request to /edit/asdf where /asdf doesn't not exist is a 500 error. It should be a 404 but it isn't.
Following,
IIS 7.5 – a breaking change in extensionless URIs handling after Windows Server 2008 R2 SP1 is applied?
I have removed the ExtensionlessUrlHandler and now get a 404. But, the body of the response is empty. Together with the rewrite module shown below is my complete web.config
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0"/>
</system.web>
<system.webServer>
<validation validateIntegratedModeConfiguration="true" />
<modules runAllManagedModulesForAllRequests="true">
<add name="RewriteExampleModule" type="RewriteExampleModule" />
</modules>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
</handlers>
<httpErrors existingResponse="Replace" errorMode="Custom">
<remove statusCode="404" subStatusCode="-1" />
<error statusCode="404" prefixLanguageFilePath="" path="/404error.aspx" responseMode="ExecuteURL" />
</httpErrors>
</system.webServer>
</configuration>
With this configuration a call to
/edit/asdf
where /asdf doesn't exist returns a 404 status code but no custom content as specified in web.config under httpErrors.
Why is the 404 body empty? Any other path without the rewrite of /edit/ is fine.
In case if error occurred on my web site I do the following:
Server.Transfer("/error.aspx");
and that page has code:
protected void Page_Load(object sender, EventArgs e)
{
...
Response.StatusCode = 404;
}
If I work on the localhost then together with 404 status returned for the page, page displays 'proper error description'.
Once I published the same code to the internet all pages with errors are still displayed with 404 status code, but the don't have the content. Instead, they have the standard 404 error message:
404 - File or directory not found.
if the line "Response.StatusCode = 404" commented out then the proper page is provided, but it has 200 status code.
Question: how to return user-friendly error page that in the same time has 404 error status code?
Any thoughts are welcome! Thanks a lot in advance!
P.S. ASP.NET 4.0
<customErrors mode="On" defaultRedirect="~/Error/GenericErrorPage.aspx">
<error statusCode="404" redirect="~/Error/404.aspx" />
</customErrors>
http://msdn.microsoft.com/en-us/library/h0hfz6fc(v=vs.71).aspx
http://msdn.microsoft.com/en-us/library/aa479319.aspx
A ha!
Try this:
Response.TrySkipIisCustomErrors = true;
Response.Status = "404 Not Found";
Response.StatusCode = 404;
I found as soon as I added Response.TrySkipIisCustomErrors=true before setting the status code, I would see the normal page copy AND a 404 is returned. Without this line the standard IIS 404 page is displayed.
Alternatively, this can be set in the web.config like so:
<system.webServer>
<httpErrors existingResponse="PassThrough">
// custom error page mappings
</httpErrors>
</system.webServer>
The key thing here is existingResponse="PassThrough"
This was added to IIS7 thus is required on sites running in Integrated Pipeline mode.
For more info: http://msdn.microsoft.com/en-us/library/system.web.httpresponse.tryskipiiscustomerrors.aspx
Update
Updating for clarrification/more info as people are still finding this useful.
It's worth noting that if you need a simple, generic 404 page use the web.config method (and best make it a plain HTML page).
The method I describe works best if you have a heavily dynamic or CMS driven site where any given page could potentially return a 404 but you want to show your visitor related info.
For example, a special offers page (offers/some-offer) could do a lookup for the offer (some-offer) and if it doesn't exist show alternative or related offers while returning a 404 under the bonnet. As far as the visitor is aware they've just been told the offer is no longer available but they're still in the offers section but we're also telling robots to un-index the URL.
This would be a lot harder to do if there was just one generic 404 page.
You can achieve this by configuring your web.config file. Please check the link below to an article, which explains at the bottom of the page, how to display different custom error pages for different HTTP error statuses.
Displaying a Custom Error Page
To show your own page with the correct 404 statuscode, you can use the following code:
1) In your web.config add the following:
<customErrors mode="On" redirectMode="ResponseRewrite">
<error statusCode="404" redirect="404.htm" />
</customErrors>
and:
<httpErrors errorMode="Custom">
<remove statusCode="404"/>
<error statusCode="404" path="404.htm" responseMode="File"/>
</httpErrors>
2) Add a 404.htm file to the root of your website:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>404 - Not Found</title>
<meta http-equiv="refresh" content="5;url=/404-PAGE" />
</head>
<body>
CONTENT
</body>
</html>
You can either add content to the body of this file and remove the META refresh or simply use the META refresh to open a page within your CMS.
Combining Jag's and adt's answers, I still had a problem. When a 404 was handled by the static file handler (as opposed to ASP.NET), I got a blank response. (The status was correctly 404.)
To fix it, I had to add errorMode="Custom" to the <httpErrors> element. If your error page uses ASP.NET, you need to include responseMode="ExecuteURL".
<system.web>
<customErrors mode="On" defaultRedirect="~/Error.aspx" redirectMode="ResponseRewrite" />
</system.web>
<system.webServer>
<httpErrors errorMode="Custom">
<remove statusCode="404" />
<error statusCode="404" path="/Error.aspx" responseMode="ExecuteURL" />
</httpErrors>
</system.webServer>
<httpErrors errorMode="Custom">
<remove statusCode="404"/>
<error statusCode="404" path="ErrorPages/error404.htm" responseMode="Redirect"/>
</httpErrors>
This works for me if I don't use the tilde (~) in the path attribute
For anyone wondering in ASPNET 6.0+ you can now use the following official solution [1]
In Program.cs:
app.UseStatusCodePagesWithReExecute("/StatusCode", "?statusCode={0}");
In StatusCode.cshtml.cs
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public class StatusCodeModel : PageModel
{
public int OriginalStatusCode { get; set; }
public string? OriginalPathAndQuery { get; set; }
[ViewData]
public string Code { get; set; } = "";
public void OnGet(int statusCode)
{
OriginalStatusCode = statusCode;
Code = statusCode.ToString();
var statusCodeReExecuteFeature =
HttpContext.Features.Get<IStatusCodeReExecuteFeature>();
if (statusCodeReExecuteFeature is not null)
{
OriginalPathAndQuery = string.Join(
statusCodeReExecuteFeature.OriginalPathBase,
statusCodeReExecuteFeature.OriginalPath,
statusCodeReExecuteFeature.OriginalQueryString);
}
}
}
In StatusCode.cshtml (here is where you can customize to your sites theme)
#page
#model StatusCodeModel
Its a Custom Page for Status Code: #ViewData["Code"]
[1] https://learn.microsoft.com/en-us/aspnet/core/fundamentals/error-handling?view=aspnetcore-6.0#usestatuscodepageswithreexecute
To create & access 404 page in asp.net C# follow the steps:
1)create an 404.html file & add your content
<html>
<head>
<meta charset="utf-8" />
<title>404 - Not Found</title>
<link href="bootstrap/css/bootstrap.css" rel="stylesheet" />
<link href="bootstrap/css/bootstrap.min.css" rel="stylesheet" />
<style>
body {
color: #797979;
background: #eaeaea;
font-family: 'Ruda', sans-serif;
padding: 0px !important;
margin: 0px !important;
font-size: 13px;
}
.p404 img {
margin-top: 120px;
}
.centered {
text-align: center;
}
.p404 h1 {
font-weight: 900;
}
</style>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-lg-6 col-lg-offset-3 p404 centered">
<img src="assets/img/404.png" alt="">
<h1>DON'T PANIC!!</h1>
<h3>The page you are looking for doesn't exist.</h3>
<br>
<div class="row">
<div class="col-md-8 col-md-offset-2">
<a class="btn btn-success" href="Default.aspx">Back To Home</a>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
in web config add this code
<system.web>
<customErrors mode="On" redirectMode="ResponseRewrite">
<error statusCode="404" redirect="404.html" />
</customErrors>
</system.web>
<system.webServer>
<httpErrors errorMode="Custom">
<remove statusCode="404"/>
<error statusCode="404" path="404.html" responseMode="File"/>
</httpErrors>
</system.webServer>
I'm trying to get custom HttpHandler working in my sample web application. I've been experiencing a lot of issues, but finally got stuck with error 500. Application pool is being run in Classic ASP.NET 2.0 mode. Server is IIS 7.5, OS is Win 7 Pro.
Here's a code of my handler:
public class SampleHandler : IHttpHandler
{
public SampleHandler()
{
}
public bool IsReusable
{
get
{
return true;
}
}
public void ProcessRequest(HttpContext context)
{
context.Response.Clear();
context.Response.ContentType = "text/html";
context.Response.Write("This is a sample content.");
context.Response.Expires = 0;
context.Response.End();
}
}
Here is a web.config file content:
<?xml version="1.0"?>
<configuration>
<system.web>
<httpHandlers>
<add verb="*" path="*.shc" type="SampleHandler"/>
</httpHandlers>
</system.web>
<system.webServer>
<handlers>
<add resourceType="Unspecified" verb="*" path="*.shc" name="SampleHandler" type="SampleHandler" modules="IsapiModule" scriptProcessor="c:\Windows\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll\aspnet_isapi.dll"/>
</handlers>
</system.webServer>
</configuration>
Here is a link to the screenshot of an error : http://bit.ly/cmPk4i
Could anybody please tell me what I did wrong? Thanks in advance!
Try setting
<validation validateIntegratedModeConfiguration="false" />
in
<system.webServer>
I had 500 error and this fixed it.
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<handlers>
<add .... />
</handlers>
</system.webServer>
From the list of "things you can try", did you install the .Net Extensibility Feature?
You can also enable the Failed Requests logging feature on the application, which provides detailed information on request processing.
The good news, at least, is that your registered handler is recognized as the handler to be executed.