14

I'm currently developing an ASP.NET MVC3 application in VS2010 and I'm having some troubles with @Url.Action helper. I have an ajax request where I use this helper:

var url = '@Url.Action("Action", "Controler", new { a = "a", b = "b" })';
$.post(url).success(function(data) { 
    ... 
});

The problem is that the value of url after this is /Controller/Action?a=a&b=b, note the & between the route values. This isn't working, but if I do:

var url = '@Url.Action("Action", "Controler", new { a = "a", b = "b" })'.replace('amp;', '');

it works perfectly!!!

My action is something like this:

public JsonResult Action(string a, string b) 
{
    ...
}

I have debugged my app and the action gets called and even a is "a", but b is null.

Is this the desired behavior of Url.Action? I don't think so. Please help me, what am I doing wrong? Should I add another parameter to my Url.Action call? Thanks in advance.

1
  • I don't think this is an issue with Url.Action but rather jQuery HTML encoding your url. Commented Mar 15, 2013 at 4:21

6 Answers 6

8

The issue here is that when you're using razor syntax: @... the razor engine is encoding the result of Url.Action (which is a string) as an MvcHtmlString. This results in ampersands being encoded as &. To get around this, use Html.Raw (Returns markup that is not HTML encoded.)

var url = '@Html.Raw(Url.Action("Action", "Controller", new { a = "a", b = "b" }))';

Resulting in: '/Controller/Action?a=a&b=b'

Thanks to @GSerg (See comment in Dave Alperovich's answer)... but the desired result isn't javascript encoding. Using HttpUtility.JavaScriptStringEncode("&") results in '\u0026'

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

Comments

3

It's not you. Javascript identifies the & as a protected character and "encodes it"

You found one way to get around it, I've seen others. As this question is NOT asking the best way, but whether or not it's you, I can assure you that it's NOT YOU. You did nothing clearly wrong. This is the natural behavior of Javascript.

If we are discussing best approached, I prefer to use @Url.Action only to get my URL, and to pass params as params to my JQuery method (the .Ajax method is my favorite).

example borrowed from e.camper

$.post(url, { a: "a", b: "b"}).success(...)

4 Comments

so you would do something like this: var url = '@Url.Action("Action", "Controler")'; and then $.post(url, { a: "a", b: "b"}).success(...)??
@e.campver, yes, thats a great example
I hate to disprove the it's NOT YOU bit, but it is actually you @ecampver - you are generating values for JS strings, this should be done properly: var url = '@HttpUtility.JavaScriptStringEncode(Url.Action("Action", "Controler", new { a = "a", b = "b" }))';. Also it's wrong that Javascript identifies the & - it is the Razor engine that outputs result of Url.Action, which is a string as opposed to MvcHtmlString, so it is encoded at the point of generating the HTML response. To prevent this one uses Html.Raw, but because we're generating a JS string, we use JavaScriptStringEncode.
@GSerg: Thank's for taking the trouble of commenting this old post, it's always good to learn better ways, greetings :)
3

every thing said in the above answer is great, i want to add something to the way you are sending the ajax request, when you want to send additional data, send it like

var url = '@Url.Action("Action", "Controler")';
$.post(url,{a:'a',b:'b'}).success(function(data) { 
    ... 
});

1 Comment

check my comment in the accepted answer, thanks anyway, I'll give you +1 ;)
2

Like I mentioned in my comment, this is a JavaScript encoding issue. The best way to prevent having to do any UrlDecoding or character replacement is to define a route that matches the parameters that you are trying to pass

routes.MapRoute(
            "MyCustomRoute",
            "{Controller}/{Action}/{a}/{b}",
            new {controller = "Controller", action = "Action"}

Place this in your global.asax file above your default route. Now, when you call

var url = '@Url.Action("Action", "Controler", new { a = "a", b = "b" })';

The output will be /Controller/Action/a/b

3 Comments

this is an ajax post, does ASP.NET MVC3 uses the routes collection to map this kind of url too??
Anytime you call a Url helper, MVC will run that through the routing table and try to match. In your example, it appears that you are passing your parameters are part of the URL and not in an actual form POST (which is OK and nothing wrong with doing it that way if you are passing simple items back to the controller).
+1 @Tommy thanks a lot, didn't know that, I'll keep it in mind ;)
0

I know this is a old question but I had a similar issue so I ending doing this:

$.ajax({
        type: "Post",
        url: "@Url.Action("Action", "Controller")",
        data:{ param1 : "@Model.param1", param2 : "@Model.param2", param3:"@Model.param3",......,param20 : "something" },
        success: function (response) {
            $("#yourDiv").html(response);
       }
    });

I hope this can be useful for someone else.

Comments

0

if a method has more than one "route", when calling Url.Action, give null values to any parameters you don't want.

My sample method is below

[Route("carousel/p/{playlistId}/s/{streamId}")]
[Route("carousel/p/{playlistId}")]
public IActionResult Carousel(string playlistId, string streamId)
{
   ...
}

when creating url, i am using like

Url.Action("Carousel", "Viewer", new { playlistId = "35", streamId = "" });

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.