views:

74

answers:

3

Hi everyone. I'm having difficulty with the concept of Routing within the ASP.NET MVC Framework. For example, I have a controller method:

public class UploadController : Controller
{
    public ActionResult Index()
    {
        return View();
    }

   [AcceptVerbs(HttpVerbs.Get)]
   public ActionResult GetChildFolders(string id)
   {

       IEnumerable<MyModel> list = MyModelDataContext.GetChildFolders( new Guid(id) );

       IEnumerable<SelectListItem> listitems = list.Select(row => new SelectListItem
                                                           {
                                                               Value = row.FolderID.ToString(),
                                                               Text = row.FolderName
                                                           });

       return this.Json(listitems, JsonRequestBehavior.AllowGet);
   }
}

and here's my route:

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

Now, if I have two jQuery functions:

function TeamChange1() {
  var id = $('#TeamList').val();
  $.getJSON('/Upload/GetChildFolders/' + id, null, function(data) {
      bindOptionResults(data);
  });
}

function TeamChange2() {
  var id = $('#TeamList').val();
  $.getJSON('/Upload/GetChildFolders', id, function(data) {
      bindOptionResults(data);
  });
}

TeamChange1() will call the GetChildFolders() method with the id parameter properly wired up and filled in, however, with TeamChange2() the id parameter remains null in the controller method. This must be a routing issue that causes this. What is the explaination?

+1  A: 

Try this for the second func. The key thing is the structure of the post data {name : value}

function TeamChange2() {
  $.getJSON('/Upload/GetChildFolders', {id : $('#TeamList').val()}, function(data) {
      bindOptionResults(data);
  });
}
redsquare
A: 

Could you not construct the URL in TeamChange2 as you did in TeamChange1 ?

function TeamChange2() {
  var id = $('#TeamList').val();
  $.getJSON('/Upload/GetChildFolders/' + id, null, function(data) {
      bindOptionResults(data);
  });
}

I believe that's how I usually do it.

TJB
+2  A: 

You don't actually need routing here. In fact the default route {controller}\{action}\{id} matches your controller, action, and parameter name (id) already so defining UploadRoute is redundant.

The reason TeamChange2() doesn't work is because id is a string, not an object. The proper code is:

function TeamChange2() {
  var id = $('#TeamList').val();
  $.getJSON('/Upload/GetChildFolders', {id: id}, function(data) {
      bindOptionResults(data);
  });
}

This will pass id in the params collection instead of the url. MVC doesn't care and will still bind since the parameter name matches the id route parameter. Watch the requests in FireBug to see the difference.

Also, you can change your id parameter in the controller action to the Guid data type so you don't have to do new Guid(id) in the code.

Ryan
How do I watch this kind of request in Firebug? That would be really useful. DOM tab?
stupidkid
It will be in the console tab. Be sure to open the tab when you first load the page. The first method should post to `/Upload/GetChildFolders/1234` and the second one will post to `/Upload/GetChildFolders`. If you expand the second one and look at the params tab, you will see `id: 1234` listed.
Ryan