I have asp.net mvc RouteConfig as below, it's default one
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Home", id = UrlParameter.Optional }
);
}
In the web.config I have enabled the customerrors as below
Web.config
<customErrors mode="On" defaultRedirect="/Error/Error">
<error statusCode="404" redirect="/Error/NotFound" />
<error statusCode="500" redirect="/Error/Error" />
</customErrors>
Error Controller
public class ErrorController : Controller
{
public ActionResult Error()
{
if (!string.IsNullOrEmpty(Request.QueryString["aspxerrorpath"]))
{
return RedirectToAction("Error");
}
return View();
}
public ActionResult NotFound()
{
if (!string.IsNullOrEmpty(Request.QueryString["aspxerrorpath"]))
{
return RedirectToAction("Home", "Home");
}
return View();
}
}
When I hit the URL https://localhost:44351/a/a/a getting 404 and it's coming to Error controller, NotFound action from there it's redirecting to "Home" controller and "Home" action.
But when I hit the URL with more slashes in deep like https://localhost:44351/a/a/a/a getting default HTTP Error 404.0 - Not Found It's not routing to Error Controller, NotFound Action.
How to handle any level deep path to handle the custom 404?
Related
I have been searching a lot for the way that I can handle 404 error for redirect it to a page designed and named 404 error.
Some of the articles say that I should do some changes in Route config. I changed it and now below codes are my route.config but still, it does not work properly
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "Default2",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
//404 ERRORS:
routes.MapRoute(
name:"404-PageNotFound",
url: "{}",
new { controller = "Home", action = "Pagenotfound" }
);
}
I mean still, when I run the project and I type the wrong address, it shows default 404 page not the one I designed - Pagenotfound.cshtml.
Copy and paste the following code between <sytem.web> tags in web.config page. When occuring 404 error, it redirect to Pagenotfound.cshtml page.
<customErrors mode="On">
<error statusCode="404" redirect="/Error/Pagenotfound"/>
</customErrors>
Also, add [HandleError] attribute on top of Controller pages.
I have an ASP.NET MVC 5.2.7 web application which is getting a 404 HTTP code.
System.Web.HttpException: at System.Web.Mvc.Controller.HandleUnknownAction (System.Web.Mvc, Version=5.2.7.0,Culture=neutral, PublicKeyToken=31bf3856ad364e35)
The application is hosted in Azure and the error is only occurring for some of the end users, not everyone. I have been unsuccessful in my attempts to recreate this error in any test environment which also resides in Azure. Has anyone encountered this issue before and how were you able to resolve it ? The application receives this error when attempting to execute GET Surveys/Submit when only a POST Surveys/Submit is present in the code. I understand that the HTTP 404 is because the GET method doesn't exist. My question is what would cause the attempted execution of the GET when it is not coded anywhere to perform that request ?
This is my controller / action method which is decorated with the HttpPost attribute:
public class SurveysController : Controller
{
[HttpPost]
public ActionResult Submit()
{
try
{
// some stuff...
}
catch (Exception ex)
{
throw;
}
}
}
Code from my .cshtml:
<form id="survey" role="form" method="post" action="#Url.Action("Submit", "Surveys")">
RouteConfig
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
I have implemented exception handling as mentioned in below link
How to pass error message to error view in MVC 5?
It is working fine. But I have requirement to handle 404 Error.
How can I do that?
if I use below code,
<customErrors mode="On">
<error statusCode="404" redirect="/Home/Error"></error>
</customErrors>
it works well when any 404 error occurs. But in case any other exception occurs then my error.cshtml call twice and show same exception two times.
web.config
Turn off custom errors in system.web
<system.web>
<customErrors mode="Off" />
</system.web>
configure http errors in system.webServer
<system.webServer>
<httpErrors errorMode="Custom" existingResponse="Auto">
<clear />
<error statusCode="404" responseMode="ExecuteURL" path="/NotFound" />
<error statusCode="500" responseMode="ExecuteURL" path="/Error" />
</httpErrors>
</system.webServer>
Create simple error controller to handle those requests ErrorContoller.cs
[AllowAnonymous]
public class ErrorController : Controller {
// GET: Error
public ActionResult NotFound() {
var statusCode = (int)System.Net.HttpStatusCode.NotFound;
Response.StatusCode = statusCode;
Response.TrySkipIisCustomErrors = true;
HttpContext.Response.StatusCode = statusCode;
HttpContext.Response.TrySkipIisCustomErrors = true;
return View();
}
public ActionResult Error() {
Response.StatusCode = (int)System.Net.HttpStatusCode.InternalServerError;
Response.TrySkipIisCustomErrors = true;
return View();
}
}
configure routes RouteConfig.cs
public static void RegisterRoutes(RouteCollection routes) {
//...other routes
routes.MapRoute(
name: "404-NotFound",
url: "NotFound",
defaults: new { controller = "Error", action = "NotFound" }
);
routes.MapRoute(
name: "500-Error",
url: "Error",
defaults: new { controller = "Error", action = "Error" }
);
//..other routes
//I also put a catch all mapping as last route
//Catch All InValid (NotFound) Routes
routes.MapRoute(
name: "NotFound",
url: "{*url}",
defaults: new { controller = "Error", action = "NotFound" }
);
}
And finally make sure you have views for the controller actions
Views/Shared/NotFound.cshtml
Views/Shared/Error.cshtml
If there are any additional error you want to handle you can follow that pattern and add as needed. This will avoid redirects and maintain the original http error status that was raised.
If you will define defaultRedirect attribute for customErrors then error.cshtml will be rendered only once in your case:
<customErrors mode="On" defaultRedirect="/Home/Error">
<error statusCode="404" redirect="/Home/Error"/>
</customErrors>
We have a multilingual website that has content in four languages.Every language is understood by the language name that we add at the first of our url.
This is our routeConfig.cs:
routes.MapRoute(
name: "Default",
url: "{lang}/{controller}/{action}/{id}/{title}",
defaults: new { lang = "fa", controller = "Home", action = "Index", id = UrlParameter.Optional,title = UrlParameter.Optional }
and this is generated the url: /en/ContactUs/Index
Also, in our controllers we get the language name from url and change the currentCulture and currentUiCulture based on it.
Now, we want to have a not found page in all of the languages. Normally, to make it happen we add an error contoller and a NotFound action and view, then we add this section in our web.config:
<customErrors mode="On" defaultRedirect="error">
<error statusCode="404" redirect="error/notfound" />
<error statusCode="403" redirect="error/forbidden" />
</customErrors>
We have added a NotFound page that we use .resx files in it to make rtl/ltr and to show the messages in four languages.
But the problem here is that in a multilingual website we are not allowed to use this address "error/notfound" because there is no languagename in it and we don't know how to add the language name in redirect="error/notfound" in the web.config file to create something like "en/error/notfound" or "fa/error/notfound".
every help would be highly appreciated
First of all, have a look at this answer for info about localizing your site via URL.
Next, <customErrors> is a catch-all for ASP.NET error messages. But in general, you have control over a 404 (routing miss) within ASP.NET MVC by using a catch-all route. In this case, you can simply localize the catch-all route and get rid of this configuration in web.config.
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Localized-Default",
url: "{lang}/{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
constraints: new { lang = new CultureConstraint(defaultCulture: "fa", pattern: "[a-z]{2}") }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { lang = "fa", controller = "Home", action = "Index", id = UrlParameter.Optional }
);
// Catch-all route (for routing misses)
routes.MapRoute(
name: "Localized-404",
url: "{lang}/{*url}",
defaults: new { controller = "Error", action = "PageNotFound" },
constraints: new { lang = new CultureConstraint(defaultCulture: "fa", pattern: "[a-z]{2}") }
);
routes.MapRoute(
name: "Default-404",
url: "{*url}",
defaults: new { lang = "fa", controller = "Error", action = "PageNotFound" }
);
}
}
ErrorController
public class ErrorController : Controller
{
public ActionResult PageNotFound()
{
Response.CacheControl = "no-cache";
Response.StatusCode = (int)HttpStatusCode.NotFound;
return View();
}
}
That takes care of the route misses within ASP.NET. For those that don't hit ASP.NET (assuming you are hosting using IIS), you should use the <httpErrors> section of web.config rather than <customErrors>. <httpErrors> is localizable via the prefixLanguageFilePath setting.
Optional string attribute.
Specifies the initial path segment when generating the path for a custom error. This segment appears before the language-specific portion of the custom error path. For example, in the path C:\Inetpub\Custerr\en-us\404.htm, C:\Inetpub\Custerr is the prefixLanguageFilePath.
<configuration>
<system.webServer>
<httpErrors errorMode="DetailedLocalOnly" defaultResponseMode="File" >
<remove statusCode="404" />
<error statusCode="404"
prefixLanguageFilePath="C:\Contoso\Content\errors"
path="404.htm" />
</httpErrors>
</system.webServer>
</configuration>
Which means you would need to set up a file structure with language prefix, and use static files as targets.
C:\Contoso\Content\errors\fa\404.htm
C:\Contoso\Content\errors\en\404.htm
AFAIK, this unfortunately means you need to have physical files at these locations. However, you could have the content of these pages setup to do both a meta-refresh redirect and a JavaScript redirect to the correct controller action.
<html>
<head>
<title>404 Not Found</title>
<meta http-equiv="refresh" content="1;http://www.example.com/fa/Error/PageNotFound" />
</head>
<body>
<!-- Add localized message (for those browsers that don't redirect). -->
<script>
//<!--
setTimeout(function () {
window.location = "http://www.example.com/fa/Error/PageNotFound";
}, 1000);
//-->
</script>
</body>
</html>
The customErrors section in web.config is the static data about some status-code and how they will be handled. The responsibility of this section can be generated dynamically by the Application_EndRequest method in Global.asax.
protected void Application_EndRequest()
{
if (Context.Response.StatusCode == 404)
{
Response.Clear();
var routeData = new RouteData();
HttpContextBase currentContext = new HttpContextWrapper(HttpContext.Current);
var lang = RouteTable.Routes.GetRouteData(currentContext).Values["lang"];
routeData.Values["lang"] = lang;
routeData.Values["controller"] = "CustomError";
routeData.Values["action"] = "NotFound";
IController customErrorController = new CustomErrorController();
customErrorController.Execute(new RequestContext(new HttpContextWrapper(Context), routeData));
}
}
I believe you can use a session variable to hold current user's ui-culture data.
I don't see a point but, if you don't want to do that, you can follow this tutorial to generate your own routes for MVC custom error page handling.
http://setiabud.blogspot.com.tr/2013/04/handling-404-error-in-aspnet-mvc.html
If we use this standard route:
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);
and within Windows 2008 IIS7 with MVC 2 setup we go to here:
"http://www.mywebsite.com/SomePageThatDoesNotExist.aspx"
and then under the Application_Error method we have this:
protected void Application_Error(object sender, EventArgs e)
{
Response.Clear();
RouteData routeData = new RouteData();
routeData.Values.Add("controller", "Error");
routeData.Values.Add("action", "Index");
Server.ClearError();
IController errorController = new ErrorController();
errorController.Execute(new RequestContext(
new HttpContextWrapper(Context), routeData));
}
Instead of getting a route and a page we expect, we get a nasty 404 Server error page. Any idea how to capture url errors and direct them to a page of our choice?
MVC has HandleErrorAttribute. You can customize it to handle only 404 or other types of error.
[HandleError(ExceptionType = typeof(ResourceNotFoundException),
View = "ResourceNotFound")]
You can associate different type of exception with different views. In the above example, when the action throw ResourceNotFoundException, it will render ResourceNotFound view.
Here is a link on how to handle 404 errors, the author provided a couple of ways to handle it.
You can do it in the web.config like this.
<customErrors mode="Off" defaultRedirect="~/Error/">
<error statusCode="403" redirect="~/Error/Forbidden" />
<error statusCode="404" redirect="~/Error/PageNotFound" />
</customErrors>