0

Short urls containing product categories like

http://example.com/Computers

Should used in ASP.NET MVC 4 shopping cart. If there is no controller, Home Index method with id parameter as Computers should called.

I tried to add id parameter to home controller using

public class HomeController : MyControllerBase
{
    public ActionResult Index(string id)
    {
        if (!string.IsNullOrWhiteSpace(id))
        {
            return RedirectToAction("Browse", "Store", new
            {
                id = id,
            });

        }
            return View("Index", new HomeIndexViewModel());
    }

but http://example.com/Computers causes 404 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: /Computers

Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.6.1073.0

How to force some controller call if there is no controller defined after slash in http://example.com/....

MVC default routing is used:

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
        routes.IgnoreRoute("{*favicon}", new { favicon = @"(.*/)?favicon.ico(/.*)?" });
        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );
    }
}

It looks like MVC ignores routing parameter:

defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }

Howe to fix this ?

Andrus
  • 26,339
  • 60
  • 204
  • 378
  • The default route means that the first segment of the url (in your case `Computers`) will search for a controller named `ComputerController` –  Sep 07 '16 at 13:46
  • Refer [this answer](http://stackoverflow.com/questions/37358416/routing-in-asp-net-mvc-showing-username-in-url/37359345#37359345) for one example of how you can handle this. –  Sep 07 '16 at 13:50
  • So it looks like route constraint should created. How to force route contraint to check if controller exists in application ? In this case all other paths can routed to Store/Browse without database lookup. Or should route contraint make database call to find which categories are present ? – Andrus Sep 07 '16 at 14:17
  • @StephenMuecke Or maybe attribute-based routing can used for this – Andrus Sep 07 '16 at 14:22
  • Attribute routing wont necessarily help. Your route need to be uniquely identifiable, and if you want a route with only one segment, then you need a constraint, otherwise it will also match other routes. The constraint need to look up if the parameter is in the `Categories` table (refer the last paragraph of my answer I linked to) –  Sep 07 '16 at 22:52

1 Answers1

0

your problem is because aspnet mvc is trying to find a controller with the name Computers, and your controller is Home, you can add a new route like this before the route with name Default:

routes.MapRoute(
            name: "Computers",
            url: "Computers",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );

In the above case, you are creating a route with match with the url http://domain.com/Computers and this route will be manage by the HomeController.

Also, according to your comment, you can have a route like:

routes.MapRoute(
                name: "Default",
                url: "{id}",
                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
            );
Julito Avellaneda
  • 2,335
  • 2
  • 17
  • 25
  • Cart has hundreds of categories and those categories are changed in database frequently. Is it reasonable to add hundres of routes ? How to delete and add new routes if categories are changed in database ? Or maybe it is possible to use single controller which handles all categories which does not match to controller name ? – Andrus Sep 07 '16 at 14:07
  • But one thing is your question and other thing is your project requirements, I answer a possible solution to your problem...I update my answer to show you other way – Julito Avellaneda Sep 07 '16 at 14:20
  • I changed MapRoute as second sample in your answer. Now `http://example.com/Computers` returns `No route in the route table matches the supplied values.` and `http://example.com` returns not found. How to fix this ? – Andrus Sep 07 '16 at 14:28
  • Leave only one route, in this case, the latest route of my answer, I test it locally – Julito Avellaneda Sep 07 '16 at 14:29
  • I added `routes.MapRoute( name: "categories", url: "{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } ); ` before default route. It seems to work. in your answer `{category}` should changed to `{id}` – Andrus Sep 07 '16 at 14:35
  • fine, I updated the answer to change category for id, I test it with a simple example – Julito Avellaneda Sep 07 '16 at 14:37
  • Using this requires /Index specified in url to call Index method in controller. Otherwize controller name is treated as category name. How to to add routes for all controllers in application to allow call them without using /Index in url ? – Andrus Sep 07 '16 at 14:44