Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
886 views
in Technique[技术] by (71.8m points)

asp.net mvc routing - @Url.Action getting ?Length=2 appended

I have this at the top of each of several translations of the "Terms of Use" page:

<li><a href="@Url.Action("Index", "Terms")">English</a></li>
<li><a href="@Url.Action("Index", "Terms", "de")">Deutsch</a></li>
<li><a href="@Url.Action("Index", "Terms", "fr")">Fran?ais</a></li>
<li><a href="@Url.Action("Index", "Terms", "it")">Italiano</a></li>
<li><a href="@Url.Action("Index", "Terms", "nl")">Nederlands</a></li>
<li><a href="@Url.Action("Index", "Terms", "hu")">Maygar</a></li>
<li><a href="@Url.Action("Index", "Terms", "es")">Espa?ol</a></li>
<li><a href="@Url.Action("Index", "Terms", "zh")">简体中文</a></li>
<li><a href="@Url.Action("Index", "Terms", "pt-pt")">European Português</a></li>
<li><a href="@Url.Action("Index", "Terms", "pt")">Português</a></li>

This is the action that should handle the clicks:

public class TermsController : Controller
{
    public ActionResult Index(string id)
    {
        switch (id)
        {
            case "de":
                return View("de");
            case "fr":
                return View("fr");
            case "it":
                return View("it");
            case "nl":
                return View("nl");
            case "hu":
                return View("hu");
            case "es":
                return View("es");
            case "zh":
                return View("zh");
            case "pt":
                return View("pt");
            case "pt-pt":
                return View("pt-pt");
            default:
                return View();
        }
    }

and these are my routes:

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

    routes.MapRoute(
        "Terms",
        "{controller}/{id}",
        new { controller = "Terms", action = "Index" }
        );

    routes.MapRoute(
        "Default",
        "{controller}/{action}/{id}",
        new { controller = "Home", action = "Index", id = "" }
        );

    routes.MapRoute(
        "ThankYou",
        "{controller}/{action}/{email}/{id}"
        );
}

From the main (i.e., English) Terms page, the first (i.e., English) link looks correct:

http://localhost:65391/Terms/

Why do the other (i.e., foreign) generated URLs look like this?

http://localhost:65391/Terms/?Length=2

Also, oddly, if I manually type in

http://localhost:65391/Terms/de

for example, and go to the Terms page in German, then the first hyperlink (i.e., back to the English Terms page) looks like this:

http://localhost:65391/Terms/de

Go here to see the actual site:

http://inrix.com/traffic/terms

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You are using an overload of the Url.Action which treats the third argument as the routeValues object.

From the MSDN:

routeValues
Type: System.Object
An object that contains the parameters for a route. The parameters are retrieved through reflection by examining the properties of the object. The object is typically created by using object initializer syntax.

So you have passed strings "de", "fr" as the third argument so MVC have taken its properties and made key value pairs: that is where the Length=2 is coming, because the string class has one property Length and the value is 2 for your strings.

You can fix this easily with passing an anonymous object wrapping your strings:

<li><a href="@Url.Action("Index", "Terms" new { id = "" })">English</a></li>
<li><a href="@Url.Action("Index", "Terms", new { id = "de" })">Deutsch</a></li>
<li><a href="@Url.Action("Index", "Terms", new { id = "fr" })">Fran?ais</a></li>
...

Notes:

  • your annonymous object property name id should match your route segment name id and controller parameter name id
  • you need to expicilty pass new { id = "" } in the default case otherwise MVC will use the already given route values. This is what you have seen in the http://localhost:65391/Terms/de case. So the English link became http://localhost:65391/Terms/de because MVC already found the id value in the URL which was de and automatically reused it.
  • Last Note the correct spelling is Magyar and not Maygar

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...