Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

@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

like image 619
birdus Avatar asked Mar 28 '13 17:03

birdus


People also ask

Is it possible to tag multiple URL to single action?

Yes, We can use multiple URLs to the same action with the use of a routing table. foreach(string url in urls)routes. MapRoute("RouteName-" + url, url, new { controller = "Page", action = "Index" });

What is difference between HTML ActionLink and URL action?

There is a difference. Html. ActionLink generates an <a href=".."></a> tag whereas Url. Action returns only an url.

What is a URL action?

A URL action is a hyperlink that points to a web page, file, or other web-based resource outside of Tableau. You can use URL actions to create an email or link to additional information about your data. To customize links based on your data, you can automatically enter field values as parameters in URLs.

How do I use MapControllerRoute?

MapControllerRoute(name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); The route names give the route a logical name. The named route can be used for URL generation. Using a named route simplifies URL creation when the ordering of routes could make URL generation complicated.


1 Answers

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
like image 90
nemesv Avatar answered Dec 12 '22 11:12

nemesv