Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Escaped Characters in URI generated by call to URL.Action with jQuery Script

I have the following code as part of a jquery script to open a jqueryui dialog (the id value is hard-coded for testing purposes):

        open: function (event, ui) {

            $(this).load("@Url.Action("Edit", "Person",
                new
                {
                    id = Guid.Parse("28769371-7518-49db-a5ea-b9c62621a609"),
                    selectedPersonFor = Model.SelectedPersonFor,
                    selectedPersonForId = Model.SelectedPersonForId,
                    clientAccountId = Model.ClientAccountId
                })");
        },

The problem I have is that, even though my dialog opens, the controller action is never hit.

If I view the source in my browser the output produced is:

open: function (event, ui) {

            $(this).load("/Person/Edit/28769371-7518-49db-a5ea-b9c62621a609?selectedPersonFor=ClientAccount&selectedPersonForId=2a2dd3b9-a73b-4afa-8237-5a4f37736f8a&clientAccountId=00000000-0000-0000-0000-000000000000");
        },

I have found that if I hardcode the URI above into my script and replace the escaped ampersand (&) with a non-escaped ampersand (&) then my controller action gets hit.

I have tried adding a call to the replace method in my script to get rid of the escaped ampersand, but this does not help. When I look at other URI's within the same page that are generated to call controller actions, but not within a script, I note that they have escaped ampersands within them.

There seems to be some difference in how the browser is processing the call to the controller action from the script as to how it is doing it from outside the script - and all related to the escaped ampersand.

Can someone direct me in how to overcome this problem?

Further info:

I have also tried passing the query parameters to the load function as follows:

open: function (event, ui) {

            $(this).load("@Url.Action("Edit", "Person")",
                {
                    id: @Guid.Parse("28769371-7518-49db-a5ea-b9c62621a609"),
                    selectedPersonFor: Model.SelectedPersonFor,
                    selectedPersonForId: Model.SelectedPersonForId,
                    clientAccountId: Model.ClientAccountId
                });
        },

However when I do it this way my dialog does not even open.

Edit:

In response to request to show route I provide the following (hopefully this is what was being requested):

routes.MapRoute(
            "Default", // Route name
            "{controller}/{action}/{id}", // URL with parameters
            new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
        );

I'm just using the default routes provided with my asp.net mvc3 project.

like image 754
daveywc Avatar asked Jan 07 '12 07:01

daveywc


1 Answers

In Razor the @ operator is used to HTML encode the output => & becomes &. If you don't want this to happen you could use the Html.Raw helper:

var url = '@Html.Raw(Url.Action("Edit", "Person", new {
    id = Guid.Parse("28769371-7518-49db-a5ea-b9c62621a609"),
    selectedPersonFor = Model.SelectedPersonFor,
    selectedPersonForId = Model.SelectedPersonForId,
    clientAccountId = Model.ClientAccountId
}))';
$(this).load(url);

Now let's consider your second code snippet:

$(this).load("@Url.Action("Edit", "Person")", {
    id: @Guid.Parse("28769371-7518-49db-a5ea-b9c62621a609"),
    selectedPersonFor: Model.SelectedPersonFor,
    selectedPersonForId: Model.SelectedPersonForId,
    clientAccountId: Model.ClientAccountId
});

If you look at the rendered HTML you will see this:

$(this).load("@Url.Action("Edit", "Person")", {
    id: 28769371-7518-49db-a5ea-b9c62621a609,
    selectedPersonFor: Model.SelectedPersonFor,
    selectedPersonForId: Model.SelectedPersonForId,
    clientAccountId: Model.ClientAccountId
});

which obviously doesn't work because Model.SelectedPersonForId is probably not a valid javascript variable so your are getting a javascript error. Also 28769371-7518-49db-a5ea-b9c62621a609 is not a valid javascript expression as you haven't wrapped in in quotes.

If you want this to work make sure you generate proper contents:

$(this).load("/Person/Edit", {
    id: '@Guid.Parse("28769371-7518-49db-a5ea-b9c62621a609")',
    selectedPersonFor: '@Model.SelectedPersonFor',
    selectedPersonForId: '@Model.SelectedPersonForId',
    clientAccountId: '@Model.ClientAccountId'
});

Notice the @ operator used before each server side variable and not only in front of the Guid. Also notice that the values are wrapped as javascript strings.

like image 173
Darin Dimitrov Avatar answered Nov 15 '22 05:11

Darin Dimitrov