-->

Map route asp.net mvc

2019-06-05 02:48发布

问题:

I'm trying to make my url seo friendly. I need to make url with this structure

www.domainname.com/article123.

And with this route

routes.MapRoute(
        "articlename", // Route name
        "aaaa/{articleID}", // URL with parameters
         new {action="DetailsByName",controller="Article"},
        new string[] { "bssnew.Controllers" } // Parameter defaults);

It doesn't work. MY route link looks like this

 @Html.RouteLink("aaa ","articlename", new {articleID="CentralPark",},new { @class = "item-link" })

But when I add controller and action in route it works

 routes.MapRoute(
        "articlename", // Route name
        "aaaa/{controller}/{action}/{articleID}", // URL with parameters
         new {action="DetailsByName",controller="Article"},
        new string[] { "bssnew.Controllers" } // Parameter defaults);

回答1:

If you need an ID only specific route, the following should work

routes.MapRoute(
    "articlename", // Route name
    "{articleID}", // URL with parameters
    new { action="DetailsByName",controller="Article" }, // parameter defaults 
    new[] { "bssnew.Controllers" } // controller namespaces
);

Assuming you have a controller which looks like

namespace bssnew.Controllers
{
    public class Article : Controller
    {
        public ActionResult DetailsByName(string articleID)
        {
            ...
        }
    }
}


回答2:

I was responding to you via James' comment. One problem could be is that you route looks like this:

routes.MapRoute(
    "articlename", // Route name
    "{articleID}", // URL with parameters
    new { action="DetailsByName",controller="Article" }, // parameter defaults 
    new[] { "bssnew.Controllers" } // controller namespaces
);

When a route is generated (not using named route) your link should look like: http://www.example.com/Article/DetailsByName?articleId=123 where 123 is your article ID.

THe condition for the above link to be generated like this is to place it before "Default" route. Also, check if the namespace registration is causing a problem for you. Try first removing the namespace if it is not needed.

Here is a quick sample which I created based on your question. The result was that even after putting named route below the default one I managed to generate a proper route. Here is the contents of the RouteConfig.cs:

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: "CalculationRoute", // Note that it is below the default route
            url: "{controller}/{action}/{x}/{y}", // using both controller and action
            defaults: new { controller = "Home", action = "Calculate"}
        );
    }
}

In my HomeController I added the following action:

public ActionResult Calculate(int x, int y)
{
    return Content(String.Format("x:{0} + y:{1} = {2}", x, y, (x + y)));
}

Now, here is the contents of the Index view

<table>
    <thead>
        <tr>
            <th>Method used</th>
            <th>Result</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>@@Html.ActionLink("Sample link", "Calculate", "Home", new {x = 1, y = 2})</td>
            <td>@Html.ActionLink("Sample link", "Calculate", "Home", new {x = 1, y = 2})</td>
        </tr>
        <tr>
            <td>@@Html.RouteLink("Sample link", new {controller = "Home", action = "Calculate", x = 1, y = 2}, null)</td>
            <td>@Html.RouteLink("Sample link", new {controller = "Home", action = "Calculate", x = 1, y = 2}, null)</td>
        </tr>
        <tr>
            <td>@@Html.RouteLink("Sample link", "CalculationRoute", new {controller = "Home", action = "Calculate", x = 1, y = 2})</td>
            <td>@Html.RouteLink("Sample link", "CalculationRoute", new {controller = "Home", action = "Calculate", x = 1, y = 2})</td>
        </tr>
        <tr>
            <td>@@Url.RouteUrl(new {controller = "Home", action = "Calculate", x = 1, y = 2})</td>
            <td>@Url.RouteUrl(new {controller = "Home", action = "Calculate", x = 1, y = 2})</td>
        </tr>
        <tr>
            <td>@@Url.RouteUrl("CalculationRoute", new {controller = "Home", action = "Calculate", x = 1, y = 2})</td>
            <td>@Url.RouteUrl("CalculationRoute", new {controller = "Home", action = "Calculate", x = 1, y = 2})</td>
        </tr>
    </tbody>
</table>

The above code generates what is expected. For example (BTW I am using some dummy link as SO does not allow localhost to be used):

  • Html.ActionLink result is: http://www.example.com/Home/Calculate?x=1&y=2
  • Html.RouteLink (not named route) result is: http://www.example.com/Home/Calculate?x=1&y=2
  • Html.RouteLink (using named route) result is: http://www.example.com/Home/Calculate/1/2
  • Url.RouteUrl (not named route) result is: /Home/Calculate?x=1&y=2
  • Url.RouteUrl (using named route) result is: /Home/Calculate/1/2

If I remove {controller}/{action} from my calculation route, it would generate the link (with named routes) as http://www.example.com/1/2.

So to summarize, if you plan to use named route to generate SEO friendly URLs, configure your route with {controller}/{action}/{articleId}. If it is not too important then generate your routes with RouteLink but do not specify route name.

UPDATE: If you don't plan to use {controller}/{action} in your route and only {articleId}, you should place your route before the Default and do not use named route when generating links. In my example above that would look like:

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

        routes.MapRoute(
            name: "", // Note that it is below the default route
            url: "{x}/{y}", // using both controller and action
            defaults: new { controller = "Home", action = "Calculate"}
        );

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

Now when you generate a link using @Html.RouteLink you would do it this way:

@Html.RouteLink("My Link", new {controller = "Home", action = "Calculate", x = 1, y = 2 })

and this will generate something like:

http://www.VirtuoZ.com/Home/Calculate?x=1&y=2

UPDATE 2: Regarding you request about other routes, you can always rely on Default route to generate information, however, you cannot have generated routes like you state in a comment:

http://www.example.com/abc for articles and http://www.example.com/def for products

The problem is that the routes are the same and routing system will pick the first route that can serve your request. It can happen that both requests are served by the same route. You need to distinguish between the two routes. So, for your articles use your new route that you defined and for other things where one parameter is expected you would use the Default route.



回答3:

[Named Routes with ASP.NET MVC][1]

http://dotnet.dzone.com/articles/named-routes-aspnet-mvc



回答4:

Try this:

routes.MapRoute(
"articlename", // Route name
"", // URL with parameters
new { action="DetailsByName",controller="Article" id="articleID"}, // parameter defaults 
new[] { "bssnew.Controllers" } // controller namespaces
);


回答5:

I got it working like this. I think the implementation is a little cleaner and easier to understand this way (using parameter names and no namespaces). The route code appears above the default route like so:

routes.MapRoute(
  name: "BlogPost",
  url: "{postId}",
  defaults: new { action = "Index", controller = "Blog" });

And the controller looks like this:

public class BlogController : Controller
{
    public ActionResult Index(string postId)
    {
        ...
    }
}