2

I have a blogging system that I'm building and I can't seem to get ASP.NET MVC to understand my route.

the route I need is /blogs/student/firstname-lastname so /blogs/student/john-doe, which routes to a blogs area, student controller's index action, which takes a string name parameter.

Here is my route

routes.MapRoute(
    name: "StudentBlogs",
    url: "blogs/student/{name}",
    defaults: new { controller = "Student", action="Index"}
);

My controller action

public ActionResult Index(string name)
{
    string[] nameparts = name.Split(new char[]{'-'});
    string firstName = nameparts[0];
    string lastName = nameparts[1];

    if (nameparts.Length == 2 && name != null)
    {
      // load students blog from database
    }
    return RedirectToAction("Index", "Index", new { area = "Blogs" });            
}

But it won't seem to resolve...it works fine with /blogs/student/?name=firstname-lastname, but not using the route I want, which is /blogs/student/firstname-lastname. Any advice on how to fix this would be greatly appreciated.

My RouteConfig

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

        routes.MapRoute(
         name: "StudentBlogs",
         url: "blogs/student/{name}",
         defaults: new { controller = "Student", action = "Index"},
         constraints: new { name = @"[a-zA-Z-]+" },
          namespaces: new string[] { "IAUCollege.Areas.Blogs.Controllers" }
     );

        routes.MapRoute(
            name: "Sitemap",
            url :"sitemap.xml",
            defaults: new { controller = "XmlSiteMap", action = "Index", page = 0}
        );

        //CmsRoute is moved to Gloabal.asax

        // campus maps route
        routes.MapRoute(
            name: "CampusMaps",
            url: "locations/campusmaps",
            defaults: new { controller = "CampusMaps", action = "Index", id = UrlParameter.Optional }
        );


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

        // error routes
        routes.MapRoute(
            name: "Error",
            url: "Error/{status}",
            defaults: new { controller = "Error", action = "Error404", status = UrlParameter.Optional }
        );


        // Add our route registration for MvcSiteMapProvider sitemaps
        MvcSiteMapProvider.Web.Mvc.XmlSiteMapController.RegisterRoutes(routes);
    }
}
2
  • Which route is it actually matching? You've only shown us one of your mapped routes. Commented Jan 21, 2014 at 21:56
  • Just throws a 404, when trying /blogs/student/firstname-lastname, but if I use /blogs/student/?name=firstname-lastname it resolves /blogs/student/ controller's index action, which has a string parameter name. Commented Jan 21, 2014 at 21:58

3 Answers 3

3

You have to declare custom routes before the default routes. Otherwise it will be mapping to {controller}/{action}/{id}.


Global.asax typically looks like this:

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();
    RouteConfig.RegisterRoutes(RouteTable.Routes);
}

If you created an Area named Blogs, there is a corresponding BlogsAreaRegistration.cs file that looks like this:

public class BlogsAreaRegistration : AreaRegistration 
{
    public override string AreaName 
    {
        get 
        {
            return "Blogs";
        }
    }

    public override void RegisterArea(AreaRegistrationContext context) 
    {
        context.MapRoute(
            "Admin_default",
            "Blogs/{controller}/{action}/{id}",
            new { action = "Index", id = UrlParameter.Optional }
        );
    }
}

Hyphens are sometimes treated like forward slashes in routes. When you are using the route blogs/students/john-doe, my guess is that it is matching the Area pattern above using blogs/students/john/doe, which would result in a 404. Add your custom route to the BlogsAreaRegistration.cs file above the default routes.

Sign up to request clarification or add additional context in comments.

2 Comments

I have, please see my added RouteConfig
Typically Area Routes get created before your other routes. If you truly created an Area named blogs, chances are that there is a BlogsAreaRegistration.cs file in your area with a conflicting route that is preceding this one. Is there a reason you are not creating this route in the BlogsAreaRegistration.cs file to begin with?
0

Try adding the parameter to the route:

routes.MapRoute(
    name: "StudentBlogs",
    url: "blogs/student/{name}",
    defaults: new { controller = "Student", action="Index", name = UrlParameter.Optional}
);

Comments

0

Try adding a constraint for the name parameter:

routes.MapRoute(
    name: "StudentBlogs",
    url: "blogs/student/{name}",
    defaults: new { controller = "Student", action="Index" },
    constraints: new { name = @"[a-zA-Z-]+" }
);

Dashes are a bit weird in MVC at times.. because they are used to resolve underscores. I will remove this answer if this doesn't work (although.. it should).

This has the added benefit of failing to match the route if a URL such as /blogs/student/12387 is used.

EDIT:

If you have controllers with the same name.. you need to include namespaces in both of your routes in each area. It doesn't matter where the controllers are.. even if in separate areas.

Try adding the appropriate namespace to each of the routes that deal with the Student controller. Somewhat like this:

routes.MapRoute(
    name: "StudentBlogs",
    url: "blogs/student/{name}",
    defaults: new { controller = "Student", action="Index" },
    namespaces: new string[] { "Website.Areas.Blogs.Controllers" }
);

..and perhaps Website.Areas.Admin.Controllers for the one in the admin area.

8 Comments

makes sense, but still throws a 404.
Do you perhaps have another controller called Student in another area?
I do in the admin area, but I have added area="Blogs" to the route defaults, and it still 404's.
If I add the route to Global.ascx instead of the RouteConfig, I get The view 'Index' or its master was not found or no view engine supports the searched locations. The following locations were searched: ~/Views/Student/Index.aspx ~/Views/Student/Index.ascx ~/Views/Shared/Index.aspx ~/Views/Shared/Index.ascx ~/Views/Student/Index.cshtml ~/Views/Student/Index.vbhtml ~/Views/Shared/Index.cshtml ~/Views/Shared/Index.vbhtml It's not looking in the area for the view.
I have updated my answer. Try explicitly passing the namespace to both of your routes that involve the Student controller.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.