Show custom error for "504 Gateway Timeout error" - c#

I am working to ASP.net MVC-5 project and I am a beginner. As of now I know the basics of MVC and able to display pages and make post and get request. But I am stuck with one issue where I get "504 gateway time out error" and I need to implement one functionality where if the client gets `504 gateway timeout error" I should be able to show a particular page like "Something is wrong" instead of standard error. To start with below is what I did.
<system.web>
<compilation debug="true" targetFramework="4.5.1" />
<httpRuntime targetFramework="4.5" />
<customErrors mode="On" redirectMode="ResponseRewrite">
</customErrors>
</system.web>
But what else I need to change or add. Can someone guide me here. I am lost.

If your ASP.NET MVC application is hosted by the IIS (or another proxy server), then the 504 error is returned by the IIS and sent to the browser, because your application does not respond to the request in a timely manner. The IIS has got a timeout (configurable for each web site) and if this is reached, then 504 is returned.
In this scenario you cannot define a custom error page inside your application, because it is not reacting.
You can configure the IIS to server custom error pages. This video tutorial shows how to do this.

ASP doesn't actually return those pages, that's actually IIS.
Check out this SO on configuring IIS to let you return custom error pages
Basically you'll need to configure these settings:
<system.web>
<customErrors mode="On" defaultRedirect="~/Error">
<!--Use whatever paths you need here, along with the accompanying status code -->
<error redirect="~/Error/NotFound" statusCode="404" />
</customErrors>
</system.web>
And create a controller to handle the errors, like so:
public class ErrorController : Controller
{
public ViewResult Index()
{
return View();
}
public ViewResult NotFound()
{
Response.StatusCode = 404;
return View();
}
}
Along with whatever view you need to match the Action.

Related

Custom Error Page handled by Application when file not found

In asp.net mvc is it possible to redirect to a custom error page when a static file is is not found rather than have IIS serve an error page?
The example below, adding this to System.Web in the web.config file will redirect the user to an Error controller and return an Error page view.
<customErrors mode="RemoteOnly" defaultRedirect="~/Error" redirectMode="ResponseRedirect">
<error statusCode="404" redirect="~/Error" />
</customErrors>
That is fine if the url resembels a controller and action but if a static file was typed into the url such as mysite.com/myFile.html, the custom error page isn't returned and IIS serves an Error page. Is it possible to have this handled within the mvc application, perhaps by redirecting the user to the same Error controller that the above custom error handler redirects to?

Is there a simple way to replace the ASP.NET Web API HTML error page with a simple Error.json file?

I feel like I may be over complicating things with a guide like this one:
How to override all standard error pages in WebAPI
I couldn't get it to work because I think the version of ASP.NET Web API that I'm using has deprecated the context.Request.CreateErrorInfoResponse()
All I want to do is display an HTTP 403 Forbidden as a single static file located in ~/Error.json
I've tried doing this to my Web.config file:
<system.web>
<customErrors mode="RemoteOnly">
<error statusCode="403" redirect="~/Error.json" />
</customErrors>
</system.web>
And I've tried this too:
<system.web>
<customErrors mode="On">
<error statusCode="403" redirect="~/Error.json" />
</customErrors>
</system.web>
It doesn't seem to have any effect at all when this exception is thrown:
throw new APIException(HttpStatusCode.Forbidden, new MessageError("foobar"));
In my application, there will be only one situation where a Forbidden response is received, and I don't want my RESTful API to be returning an HTML response in this event.
What can I do to fix this?
The reason why I need to do this is to render the Web Application useless if a customer tries to crack or pirate this web application. I would like to do all of this within Startup.cs if it's possible to crash the app and to return a json response of the error rather than an HTML response that the throw new Exception method does by default.

ASP.NET MVC customError page doesn't get displayed for some of the 400 errors

I'm having quite an interesting issue with the custom error pages management for a new ASP.NET MVC application.
This issue is like this:
- if I'm calling an URL (doesn't matter which) with a "bad" argument at the end of URL, like ..../c<, the application is displaying the correct server error page as instructed in the web.config;
- if I'm changing the URL to a more nasty one, like .../<c (to look more like an HTML tag, there is no more server error page displayed in the browser and instead of that, I'm getting a plain YSOD with a message like An exception occurred while processing your request. Additionally, another exception occurred while executing the custom error page for the first exception. The request has been terminated.
According to ELMAH, both requests ended with a 400 status code and the message being:
- for the first one: System.Web.HttpException (0x80004005): A potentially dangerous Request.Path value was detected from the client (<).
at System.Web.HttpRequest.ValidateInputIfRequiredByConfig()
at System.Web.HttpApplication.PipelineStepManager.ValidateHelper(HttpContext context)
- for the second one: System.Web.HttpException (0x80004005): A potentially dangerous Request.Path value was detected from the client (<).
at System.Web.HttpRequest.ValidateInputIfRequiredByConfig()
at System.Web.HttpApplication.PipelineStepManager.ValidateHelper(HttpContext context)
So, both errors are the same, the status code is the same, but for one of the errors, the custom error page is not getting displayed. I've also went to global.asax in debug mode and checked the Server.GetLastError() in protected void Application_Error(object sender, EventArgs e) and again, both errors were the same, nothing is different.
In web.config, this is how my <customErrors> tag looks like:
<customErrors mode="On" defaultRedirect="/ServerError.aspx" redirectMode="ResponseRewrite">
<error statusCode="500" redirect="/ServerError.aspx" />
<error statusCode="404" redirect="/PageNotFound.aspx" />
</customErrors>
Can please someone tell me why the behavior is different in these two cases?
Thank you very much for your time.
There's a lot of misinformation and/or out-of-date solutions regarding error handling in IIS 7+. The main things to understand are:-
.NET 4.0 made breaking changes to ASP.NET's request validation.
IIS 7+ introduced a new way of handling custom error pages.
Most people are using hodge-podge solutions involving all of customErrors, httpErrors the Application_Error handler, and often setting requestValidationMode="2.0" on the httpRuntime property and/or disabling request validation entirely! This makes it really difficult to use other people's solutions because any and all of these can affect the behaviour. I had a quick search around and I found several semi-duplicates without accepted answers, probably for this reason.
The reason that these two errors give you different behaviour is that they occur at different stages in the request pipeline. The customErrors node in your web.config interacts with errors "inside" your application, while request validation takes place "outside" your application. IIS rejects the dangerous request before it gets to your application code, and so your customErrors replacement doesn't happen.
So how do we fix that?
Ideally you want a solution with as few moving parts as possible. IIS7 gives us a new way to specify error page replacement at the IIS level instead of at the application level - the httpErrors node. This lets us catch all our errors in one place:-
<configuration>
...
<system.webServer>
...
<httpErrors errorMode="Custom" existingResponse="Replace">
<clear />
<error statusCode="400" responseMode="ExecuteURL" path="/ServerError.aspx"/>
<error statusCode="403" responseMode="ExecuteURL" path="/ServerError.aspx" />
<error statusCode="404" responseMode="ExecuteURL" path="/PageNotFound.aspx" />
<error statusCode="500" responseMode="ExecuteURL" path="/ServerError.aspx" />
</httpErrors>
...
</system.webServer>
...
</configuration>
If you care about SEO (and you should!), you still have to make sure that your controller/page sets an appropriate status code:-
this.Response.StatusCode = 500; // etc.
You should remove your customErrors node entirely. It is normally used for backwards-compatibility. You should also ensure that requestValidationMode is not set on the httpRuntime node.
This should catch most errors (excluding, obviously, errors in parsing your web.config!)
Related:- ASP.NET MVC Custom Errors
MSDN Documentation:- http://www.iis.net/configreference/system.webserver/httperrors
Note: in your case, if you want to set defaultPath on the httpErrors node, you'll get a lock violation because of ApplicationHost.config settings. You can either do as I did and just set path individually for the error codes you care about, or you can have a look at unlocking the node:-
http://www.iis.net/learn/get-started/planning-your-iis-architecture/introduction-to-applicationhostconfig
http://forums.iis.net/t/1159721.aspx
My intuition is that it's more trouble than it's worth in low-control environments like Azure App Service / Azure Web Sites. You might as well set the paths for individual status codes.
I've put a full working example of using httpErrors for custom error pages up on github. You can also see it live on azure web sites.

MVC3 app redirects to ReturnUrl=%2f

I am using Form Authentication in my MVC3 web app. I have added following in root web.config:
<authentication mode="Forms">
<forms name=".FormsAuth" loginUrl="~/Home/Index" timeout="2880" />
</authentication>
<authorization>
<deny users="?"/>
</authorization>
When I launch my app, it redirects to http://localhost:22888/Home/Index?ReturnUrl=%2f instead http://localhost:22888. If I remove line <deny users="?"> then it redirects correctly but then Context.User.Identity.Name gives no value after login.
Please help.
Take a look at Securing your ASP.NET MVC 4 App and the new AllowAnonymous Attribute.
You cannot use routing or web.config files to secure your MVC application (Any Version). The only supported way to secure your MVC application is to apply the Authorize attribute ...
Quote
MVC uses routes and does not map URLs to physical file locations like WebForms, PHP and traditional web servers. Therefore using web.config will definitely open a security hole in your site.
The product team will have a communication if this changes in the future, but for now it is without exception the rule.
Examples:
Start with the default ASP.Net MVC project (internet/intranet).
Edit the web.config adding:
<location path="Home">
<system.web>
<authoirzation>
<deny users="*">
</authoirzation>
</system.web>
</location>
Run the project, by default you will use the Default route /Home/Index and you see content, simply bypassing the web.config with no changes to the default template. Why? Because the ASP.Net pipeline is comparing the URL requested to the location specified in the web.config. However, after the Authorization Event has been executed in the pipeline the routing taking place (Default routing or custom routing) and allows access to the supposedly restricted area.
Additionally, any MVC Redirect() will also by-pass the same security measures as again the routing takes place after the Authorization Pipeline Event.
When I launch my app, it redirects to http://:22888/Home/Index?ReturnUrl=%2f instead http://:22888.
If you are using the default template, authorization stores the returnUrl and redirects back to /Home/Index with the value %2f which is /. You can update the RedirectToAction code in the AccountsController to not append the returnUrl if it is /.
This is correct behavior of the runtime.
You told the engine to deny the access to unauthenticated users and also that the login url is located at ~/Home/Index.
This is why when you navigate to the default url / the engine makes the browser go to the login page and passes the return url, encoded / in this case.
The question is then: what you want to do if the correct behavior bothers you.
I resolved this issue by performing two modifications:
I removed deny users='?' line from web.config file. But then I was getting null in Context.User.Identity.Name
In HttpPost Login method, I was redirecting user after successful authentication using return View("Home"). When I changed it to return RedirectToAction("Home") I got value in Context.User.Identity.Name
Although a little late to the show, if you're still having issues, remember to look down at the sections in your web.config for other authorization rules (correctly or incorrectly set). There are some situations where mis-configurations to a resource at the root or subdirectory could cause endless redirects.

How to Get Detailed Error Message From IIS 7.5 While Consuming MVC 4 WebAPI Restful Service?

Assume I have a working Method in a Controller. Pseudo code could be:
public IEnumerable<ViewMP3> MyMP3(string token, string id)
{
using (ControlDbContext db = new MyDbContext())
{ List<ViewMP3> list = ...some list linq statement
return list;
}}
I consume the WebAPI using HttpClient and no error is produced.
Now, suppose I throw an error on purpose:
throw new ArgumentException("hello"); //inserted in method above
How can I get a real detailed error message. All I can get is IIS 7.5 Detailed Error - 500.0 - Internal Server Error. Note: not to confuse the issue, I pass the error output of the WebAPI service back to the client in a string. The error is originating inside the service but will only produce the 500.0 error. Normally JSON is returned but when a known error condition is set, I change my code to grab the response in a string format and pass on to the client. That is how I know what the error contains.
I have tried enabling "Send Errors to Browser". I have changed IIS Error Pages Feature Settings to Detailed Errors. I have changed Web.Config to include
<customErrors mode="Off" />
<compilation debug="true" targetFramework="4.0" />
and
<httpErrors errorMode="Detailed">
<remove statusCode="500" subStatusCode="-1" />
</httpErrors> .
I have granted IIS_IUSRS rights to the folder with the web files.
I had a real error earlier in the day that was nearly impossible to troubleshoot because of the generic 500.0 error. Any idea what else I could do to get detailed error messages?
Thanks!

Categories