How to handle HTTP 404 with ASP.NET MVC projects - asp.net-mvc

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.

Related

Some basic questions about Routing in ASP.NET MVC

I'm trying to learn ASP.NET MVC and have a few questions about routing.
Print is a controller, with a Show action, that takes a parameter and returns it back as string.
Consider the code
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional });
routes.MapRoute(
name: "Print",
url: "Print/{action}/{id}",
defaults: new { controller = "Print", action = "Show", id = UrlParameter.Optional });
}
Why do I get a 404 error when I try host:xxxxx/Print/xxx...? Shouldn't it take me to the Show action?
Also if I set url:Print, and try host:xxxxx/Print I get the same error. It should take me to the Show action.
Similarly if I set url:Print/{action}/{id} and try host:xxxxx/Print/Show it gives the same error, even though the parameter is optional, and should return blank?
But if I interchange the two routes such that the Print route is first in precedence and Home/Index in second, I do not get any errors in any cases? host:xxxxx/Print shows blank, host:xxxxx/Print/Show shows blank and host:xxxxx/Print/Show/xxx... returns some value.
Why do I get errors if I set it as the second route?
Change the routes register order to:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Print",
url: "Print/{action}/{id}",
defaults: new { controller = "Print", action = "Show", id = UrlParameter.Optional });
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
The routes in the RegisterRoutes() are analyzed in order they are added to the routes. The Default route pattern is universal, therefore the second doesn't work. The MVC trying to find the Show action in the Home controller and does not finding it. Therefore it report the 404 error.
If look at the RouteCollection declaration it is inherited from IList<T>. So, the routes analyzed in order they added to the routes table.
Any your routes should be added before the Default route.

Adding routing in MVC 5

I have a requirement in which I have to map the below url
/amer/us/en/ = Home controller
/amer/us/en/login/index = Home controller
/amer/us/en/confirmation = Confirmation controller
along with the regular default action.
Eg if user goes to
http:\\test.com --> http://test/home/index
http:\\test.com/amer/us/en/login/index --> http://test/home/index
http:\\test.com/amer/us/en/ --> http://test/home/index
I was looking into attribute routing and so I added the below code in HomeController
[RoutePrefix("amer/us/en/")]
[Route("{action=index}")]
public class HomeController : Controller
{
}
and I am getting this error
The route prefix 'amer/us/en/' on the controller named 'Home' cannot begin or end with a forward slash and also the default routing is not working now so http://test.com is not loading anything. Below is my default RouteConfig class.
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes();
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
Very new to MVC. Can someone tell me what I am doing wrong here.
Routing in MVC works either by defining your routes in the RouteConfig class or by attribute routing (or you can use Areas). Routing with RouteConfig works with the order you define the routes with. When a request comes, MVC will try your routes from top to bottom and execute the first one that it can match with the requested url. So the routing need in your example can be achieved by:
routes.MapRoute(
name: "RootLogin",
url: "amer/us/en/login/index/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "DefaultAmer",
url: "amer/us/en/{controller}/{action}{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
this will map login as a special route and all the other /amer/us/en/ routes will go to whatever controller comes after and whatever action of it. The last route, if the request does not start with /amer/us/en will perform the default behavior.
Looks like, however, you want to define /amer/us/en/ as an Area, so you might want to take a look into that as well.

Integrating a WebForm into an MVC application ASP.NET

My question has 2 parts:
1
My MVC project has folder structure like so:
I want to create a link in the 'Create' page that links to the 'Savings' WebForm
I've tried adding this to the RouteConfig:
routes.MapPageRoute(
"idea-savings-calculator",
"Idea/Savings",
"~/Views/Idea/Savings.aspx"
);
but the default MVC MapRoute function:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
maps to the URL localhost:xxxx/Idea/Savings first and throws an error because there isn't an action called savings in the Idea controller Savings.
Edit: RouteConfig Class:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.IgnoreRoute("{resource}.aspx/{*pathInfo}");
routes.MapPageRoute(
"idea-savings-calculator",
"Idea/Savings",
"~/Views/Idea/Savings.aspx"
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
2
Below is a cut from the 'Create' View of the 'Idea' Controller URL: http://localhost:51946/Idea/Create
(red box indicates where I'd like the link to the Savings WebForm)
The Savings WebForm is just a simple calculator; how would I pass the product from the calculations back to the above 'Create' page so that it can be displayed in the bottom text box? I'm guessing it would be as a parameter in the url that the Idea Controller can match? But... How?
Thanks!
So to solve my first problem I moved the WebForms page 'Savings.aspx' to the route of my project and used the MapPageRoute after the MapRoute method.
routes.MapPageRoute(
"idea-savings-calculator",
"Idea/Savings",
"~/Savings.aspx"
);

MVC RouteConfig allow /Controller/Action.html

I have an MVC application and am using the standard routeconfig that routes /Controller/Action/Id
I want it to additionally capture /Controller/Action.html as the url and as well and point to /controller/action also.
I am using a jquery library that I have no control over, and a function requires a url that points to a webpage or an image. However, it doesn't appear to understand that ends without an extension(.html, .php etc) is a link to html and throws an error.
Edit: I tried as the commenter below suggested, and still can't seem to get it to work. Here is my route config.
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute("routeWithHtmlExtension",
"{controller}/{action}.html",
new { controller = "Home", action = "Index" }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
This Url works:
http://localhost:14418/Album/Test
This one does not:
http://localhost:14418/Album/Test.html
In web.config
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
...
</system.webServer>
If you set up the following route, it will work:
routes.MapRoute("routeWithHtmlExtension",
"{controller}/{action}.html",
new {controller = "Home", action = "Index" }
);

ASP.NET MVC 4 Routing Query - Passing query-string to Index Action

I have a controller with an index action.
public ActionResult Index(int id = 0)
{
return view();
}
I wish to pass id into the index action, however it doesnt appear to work in the same way as the details action.
e.g. if I want to pass id 4 into the index action, I have to visit url:
http://localhost:8765/ControllerName/?id=4
With the details Action... I can do this.
http://localhost:8765/ControllerName/Details/4
What I want to do with Index is something like...
http://localhost:8765/ControllerName/4
When I visit this url, I get an error:
Server Error in '/' Application.
The resource cannot be found.
Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.
Requested URL: /fix/1
Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.17929
Is this possible? How can I get MVC to automatically treat the index action in the same way as the details one?
Thanks
UPDATE - MY CURRENT ROUTES CONFIG
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 }
);
}
}
UPDATE NEW RouteConfig Class still doesn't work when I visit localhost:1234/Fix/3
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 }
);
routes.MapRoute(
name: "FixIndexWithParam",
url: "Fix/{id}",
defaults: new { controller = "Fix", action = "Index", id = UrlParameter.Optional });
}
}
Update It's worth pointing out, /ControllerName/Index/4 should work with the default route.
With the default route there, it expects the second parameter to be the controller name.
So with the Default Route /ControllerName/4 is being interpereted as ControllerNameController Action 4, which of course does not exist.
If you add
routes.MapRoute(
name: "IndexWithParam",
url: "{controller}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional });
before the default one it would allow
/Home/4 to be routed to HomeController action Index with id=4
I have't tested this, it may conflict with the default. You may need to specify the controller explicitly in the route, ie:
routes.MapRoute(
name: "HomeIndexWithParam",
url: "Home/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional });
(Obviously, replace Home with whatever controller you're actually wanting to route to)

Resources