Question

I'm searching for the best possible way to solve the following problem: I have a search page, with different criterias that can be selected, which are availible in the SearchViewModel. Now the search returns a list of SearchResults, which are products. Those can be added directly to the basket. Now the problem is, the action for adding the item to the basket is on the BasketController and not the SearchController. When the user clicks it, he is returned to the SearchPage but loses all the selections he has made.

if (Request.UrlReferrer != null)
        return Redirect(Request.UrlReferrer.ToString());

I have tried working around the problem using TempData, but I get a "The result of a query cannot be enumerated more than once."-Exception.

private SearchViewModel EnsureViewModel(SearchViewModel viewModel)
    {
        if (TempData["SearchModel"] != null && viewModel.SearchResult == null)
            viewModel = TempData["SearchModel"] as SearchViewModel;

        TempData["SearchModel"] = viewModel;
        return viewModel;
    }

Here where I display the list of my results in the model, the exception is thrown:

@Html.DisplayFor(p => Model.SearchResult)

I've also considered that there might be a way to do this using a partial view? Of course, my last ressource is just duplicating the code, but I'm not thrilled by that idea...

Any ideas are appreciated, thanks =)


Edit The call for the controller is made using the form as following:

@using (Html.BeginForm("Add", "Basket", new { id = Model.Name } ))
    {
        @Html.TextBox("amount", "1", new { name="amount", maxlength=7, @class = "txtfield number" })
        <button><img src="@Url.Content("~/Content/images/icon_basket.gif")" border="0" width="14" height="10" class="basket" /></button>
    }       
Was it helpful?

Solution

I think the Redirect is what's blowing up the TempData, try replacing "Redirect" in your controller code with "View" and pass it the view name (not the whole url).

(Note: if your controller action was doing anything to populate a view model you'll need to copy that code and insert it just before your call to the View (I pull it out into a private method and call it from both places))

OTHER TIPS

Why not call the "Add to Basket" method using AJAX? Then users don't need to leave your search page to add items to the basket, which will preserve their search.

Also, when I implement search parameters I often pass those parameters on the query string. They still populate a SearchViewModel, but having them on the query string allows them to be passed around between web requests pretty easily if necessary.

If you can't use AJAX, there is another option:

  1. Store all basket items into the session (obviously).
  2. When rendering the search result page, for each item verify if it is already into the basket. If it is, show it checked.
  3. When the user clicks on "Add to basket", clear you basket and repopulate it using this last post.

Of course, I'm not sure if you're using pagination. If you are, this solution probably will not work...

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top