views:

27

answers:

4

I'm having difficulty getting the Model Binder to work. I thought it was the jQuery, so I asked this question, but after further investigation, I can see that the jQuery is indeed sending the parameter to the server. That's the reason I'm asking a new question - this is no longer a jQuery issue, as I originally thought.

Background:

What I'm doing is sending a GET request to my Action Method as follows:

$.get($(this).attr("href"), { "searchExpression": "schroders" }, function (result) {

    // do stuff

}, "html");

this creates the following URL:

http://localhost:65091/search/Tabs?searchExpression=schroders

I thought this would have worked, and populated the Action Method:

public PartialViewResult Tabs(string searchExpression)
{
    return PartialView(new SearchViewModel
    {
        PagedFunds = _fundService.GetFunds(searchExpression)
    });
}

but the route to this method is defined as:

routes.MapRoute(
    null,
    "search/{action}/{searchExpression}",
    new { controller = "search", action = "QuickSearch", searchExpression = "" }
    );

As we can see, searchExpression is expected as a URL parameter, not a query string parameter. I didn't think this would be an issue, but if I overload Tabs as follows:

public PartialViewResult Tabs(string searchExpression, string query)
{
    return PartialView(new SearchViewModel
    {
        PagedFunds = _fundService.GetFunds(searchExpression)
    });
}

and change

{ "searchExpression": "schroders" }

to

{ "query": "schroders" }

the query parameter in the Action Method is populated.

Question:

So my question is what needs to change to get the searchExpression populated? Do I need to modify the jQuery so it appends "schroders" to the URL, so it's like

/search/Tabs/schroders

Ideally I could have the best of both worlds, where the user could type the URL with the search term, and I could also use the $.get in a way that I could pass the search term as a parameter to the $.get function.

A: 

You could just create a different action method that you use when searching with jQuery:

public PartialViewResult JQuerySearchForTabs(string q)
{
    return Tabs(q);
}


public PartialViewResult Tabs(string searchExpression)
{
    // This goes unchanged
}

Then change your jQuery call to

$.get('YourControllerName/JQuerySearchForTabs', { q: "schroders" }, function (result) {

    // do stuff

}, "html");

If you don't want to hard-code the url but get it from the element, use a convention of for example tucking on WithAjax at the end of the url, so you can say $(this).attr('href') + 'WithAjax' for the url.

Tomas Lycken
+1  A: 

hello again dave,

looking at your route. you've got the controller hardcoded as 'search', as in:

routes.MapRoute(
    null,
    "search/{action}/{searchExpression}",
    new { controller = "search", action = "QuickSearch", searchExpression = "" }
);

what happens if you 'soften' this to:

routes.MapRoute(
    null,
    "{controller}/{action}/{searchExpression}",
    new { controller = "search", action = "QuickSearch", searchExpression = UrlParameter.Optional }
);

Also, might be 'interesting' to switch from $.get to $.ajax (post).

just another rambling thought..

jim

jim
Hi Jim, that's close but the actual answer is posted below. +1 for the hint though :-)
DaveDev
Dave - one down, nnn to go :) - glad that helped..
jim
A: 

It turns out I had to specify a route to use for the Tabs that didn't need searchExpression, so my routing configuration now looks like:

routes.MapRoute(
    null,
    "search/Tabs",
    new { controller = "search", action = "Tabs" }
    );

routes.MapRoute(
    null,
    "search/{action}/{searchExpression}",
    new { controller = "search", action = "QuickSearch", searchExpression = "" }
    );
DaveDev
+1  A: 

Perhaps I'm missing something but I would just build the normal get url:

$.get($(this).attr("href") + "/" + searchTerm, null, function (result) {
mattk
that would do the trick also, but it's something I'm trying to avoid
DaveDev
Any particular reason?
mattk
HI Mattk, the reason is because I want to be able to use the the same $.get request across the board. If I added this, I'd need another $.get for anything that didn't have a search term as part of the URL
DaveDev