views:

248

answers:

2

I need to pass a url string from the view to the controller, a url that is retrieved via jquery. I tried just using the id parameter in the default routing, but that didn't work. It didn't accept a url string.

Calling the Controller through jquery works fine, like this:

$('#result').load('Home/Files/' + url);

This calls the correct action method, but unless I feed a simple text string it won't work (I tested feeding the url variable a simple string just to make sure the method was called at all).

So how can I get this url string to the controller? I am trying to think about how to do this the "MVC" way, and not break that way of thinking, so I don't want to utilize a hidden input with runat server. Could it be done with ViewData? I couldn't think of any way though, I only know how to set ViewData in the controller and fetch the value from the view, not the other way around...

I also tried adding a custom route (before the default route):

routes.MapRoute(
    "FileManager", // Route name
    "Home/{action}/{url}", // URL with parameters
    new { controller = "Home", action = "Files", url = "" } // Parameter defaults
);

But that didn't work either, same problem with not getting the url to the controller. I only did it because I had seen suggestions for it for people with similar problems here, but to be honest I don't see how this could work, because how is this any different from the default route? I have no idea why the {id} parameter only seems to accept certain strings (id format strings I suppose), but unless I could specify somehow what type the url parameter should be I don't see how adding this route should make any difference...

If someone could enlighten me I would be very grateful!

EDIT: When I think about it, since I'm getting the content through an ajax call with jquery, I'm not sure a ViewData type solution would work anyway, because the entire page isn't posted, or am I wrong? Keep in mind that I'm just learning MVC and jquery at the moment, so please don't assume I have all the basics clear to me yet :-). Basically I just want to be able to pass any type of string (and possibly other types of data that is not an id) to the controller from the view...

EDIT 2: I tried the suggested encodeURIComponent, but that didn't work either, unless I'm doing something wrong. Here's my code:

The url (doesn't matter if I try it as a relative path or an absolute one using file:///)

<li><a href="#" rel="visual studio 2010/Projects/JsTree/JsTree/">Some text</a>

The jquery:

var url;
$(document).ready(function () {
    $("a").click(function () {
        url = encodeURIComponent($(this).attr("rel"));
        $('#result').load('Home/Files/' + url);
    });
});

I'm calling an action method with a string id parameter. Note again that it works fine if I pass a simple string, and the call to the action is made. But if I use the url above, the action method is never even called... I have a breakpoint there that is never reached if there is a url in the parameter!

A: 

Try encoding the URL before you pass it via encodeURICompoenent() like this:

$('#result').load('Home/Files/' + encodeURIComponent(url));

This encodes any complex strings for passing as the last parameter, if I'm understanding your issue correctly, this should help.

Nick Craver
Ok, I'll check that out. I'm assuming you mean I should do this with the default route using the {id} parameter? But what about other parameters one might want to pass? I tried passing a string with spaces, for instance. And it gets passed to the action method, but is cut off at the first space. If I needed to pass system file paths that might be an issue for instance. So how would one generally be able to pass any type of string (or other type for that matter)?
Anders Svensson
+1  A: 

It's most likely that the URL is not being encoded properly - try using encodeURIComponent().

Another tip is to generate the URL of the action using MVC routing itself - URL.ForAction() IIRC - That way, if you ever change your routing information, all your JQuery will continue to work

Basiclife
Same comment as for Nick above: what I'm really asking about is how would you be able to pass other types of strings, not only urls, but strings with spaces, system file paths, what have you...?
Anders Svensson
Exactly the same mechanism. The URI referenced in the name refers to the facct that it's being passed in a URL _NOT_ that it's a url which is being encoded - So any data can be encoded in this way. The generic javascript method for this is escape() but that doens't handle unicode well. See http://xkr.us/articles/javascript/encode-compare/ for more info
Basiclife
What you'd end up with is something like:<blah>.load('Home/Files/' + encodeURIComponent(url) + '/' + encodeURIComponent(SomeOtherParameter));
Basiclife
Ok, thanks, I got it working now with this encodeURI and by actually passing the parameter as a querystring instead...
Anders Svensson
You're welcome :)
Basiclife