Click here to Skip to main content
15,565,474 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I have been following this tutorial, hoping to understand ASP.NET better (I've worked with it for years, but never learned how it is set up).

I am having trouble understanding how routing works. In the following code I have set up three routings to variations of the pages created in the tutorials.

In each routing, there are defaults set for the controller, action and id, but only the first routing lets those values default. The ViewData and ViewBag routes will not accept anything other than a fully filled in URL. Why not?

Also, in each, the id is marked as optional, but again, only the first routing will let id be omitted. The other two won't accept /Index as the end of the URL. Why not?

What I have tried:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;

namespace FirstMVCDemo
{
    public class RouteConfig
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            // accepts localhost:{port}
            //         localhost:{port}/Home
            //         localhost:{port}/Home/Index
            //         localhost:{port}/Home/Index/{num}
            routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
            );

            // accepts localhost:port/ViewData/HomeVD/Index/{num}
            // rejects localhost:{port}/ViewData              (why?)
            //         localhost:{port}/ViewData/HomeVD       (why?)
            //         localhost:{port}/ViewData/HomeVD/Index (why?)
            routes.MapRoute(
                name: "ViewData",
                url: "ViewData/{controller}/{action}/{id}",
                defaults: new { controller = "HomeVD", action = "Index", id = UrlParameter.Optional }
            );

            // accepts localhost:port/ViewBag/HomeVB/Index/{num}
            // rejects localhost:{port}/ViewBag              (why?)
            //         localhost:{port}/ViewBag/HomeVB       (why?)
            //         localhost:{port}/ViewBag/HomeVB/Index (why?)
            routes.MapRoute(
                name: "ViewBag",
                url: "ViewBag/{controller}/{action}/{id}",
                defaults: new { controller = "HomeVB", action = "Index", id = UrlParameter.Optional }
            );
        }
    }
}
Posted
Updated 29-Jul-21 4:36am

1 solution

It's down to the order in which you register the routes.

/ViewData has two potential matches: it could match the second MapRoute call, calling the Index action on the VDHome controller; or it could match the first MapRoute call, calling the Index action on the (non-existent) ViewData controller. When that happens, the first registered route wins - it will call the Index action on the ViewData controller.

Similarly, /ViewData/HomeVD/Index could match either the Index action on the HomeVD controller, or the HomeVD action on the ViewData controller, passing Index as the id.

You can use Phil Haack's route debugger tool to debug problems like this:
ASP.NET Routing Debugger | You’ve Been Haacked[^]

If you move the default route to the end of the RegisterRoutes method, your other routes should work.

You might also want to consider using areas:
Walkthrough: Organizing an Application using Areas | Microsoft Docs[^]
 
Share this answer
 
v2
Comments
C Pottinger 29-Jul-21 11:49am    
Thank you, Richard. That worked - and better yet: I understand why it worked!

And thanks for the links - I will be looking into utilizing both suggestions.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900