3

I know this question has been asked several times and answered, but none of the solutions are working for me.

This is my ViewModel:

public class FlightSearchResults
{
    public FlightSearch SearchModel { get; set; }
    public List<vwLowFareSearchResults> SearchResults { get; set; }
    public string TestString { get; set; }
    public DateTime TestDate { get; set; }
}

I am using a RedirectToAction like this:

FlightSearchResults flightSearchResults = new FlightSearchResults();
flightSearchResults.SearchModel = model;
flightSearchResults.SearchResults = flights;
flightSearchResults.TestDate = DateTime.Now.AddDays(-2);
flightSearchResults.TestString = "Just Testing . . .";
return RedirectToAction("index", "flights", flightSearchResults);

I am only getting this List<vwLowFareSearchResults> SearchResults property in my flights index, none of the others are having values assigned. I have tried several variations from some threads on StackOverFlow like:

return RedirectToAction("index", "flights", new { SearchResults = flights, SearchModel = model });
return RedirectToAction("Result", "Dialog", new RouteValueDictionary(flightSearchResults));

I can return the view like this:

return View("~/Views/Flights/Index.cshtml", flightSearchResults);

but this is not a good solution as the url is not updated. I am modifying some older projects and it's mess of using Session and Viewbag.

I need to simplify and the pattern of view and controller communication of data in the previous code is a mess. Is it possible to do this without using the ViewData or Viewbag in a simple RedirectToAction.

Any kind of help in achieving this will be great as I am new to MVC.

RickL
  • 3,318
  • 10
  • 38
  • 39
Ali Umair
  • 1,386
  • 1
  • 21
  • 42
  • 2
    Never pass complex objects to a GET method. Apart from the ugly query string it generates, If the model contains properties which are complex objects or collections (as yours does) binding fails. And there is a possibility that your will exceed the query string limit and throw and exception. Save your model, pass its ID to the GET method and in the GET method, retrieve the model again. –  May 17 '15 at 07:49
  • I am not saving anything in database, list is coming from an API, i need to display it on a page after some computations, so i need to have the model if user decides to update search query. How can one controller call another and pass the data ? – Ali Umair May 17 '15 at 07:52
  • You need to save it somewhere. Session is one option if you don't want to save it to a database –  May 17 '15 at 07:56
  • you are saying that it is impossible to do, i must save it somewhere first ? – Ali Umair May 17 '15 at 07:59
  • Yes, it needs to be saved somewhere. –  May 17 '15 at 08:01
  • Check this post: http://stackoverflow.com/questions/4197811/asp-net-mvc-trouble-passing-model-in-html-actionlink-routevalues/14597115#14597115 – Ehsan Sajjad May 17 '15 at 08:17
  • @EhsanSajjad this idea is good but what if the string exceeds the querystring limit ? and if not is it a good practice to use such long querytsrings – Ali Umair May 17 '15 at 08:30
  • 2
    @EhsanSajjad, Not a good idea when the model contains collections - could very easily exceed the query string limit and throw an exception –  May 17 '15 at 08:31
  • Now i understand this situation. The main reason behind using using `RedirectToAction` is to update the URL also , is there any method by which i can return a View and also update the URL ? – Ali Umair May 19 '15 at 04:31

1 Answers1

1

Here is an approach I used recently. Try:-

        ... Previous code omitted.
        //In your controller action, save the data to TempData...
        TempData["FlightSearchResults"] = FlightSearchResults;

        return RedirectToAction("flights");
    }

    public ActionResult flights()
    {
        FlightSearchResults flightResults = TempData["FlightSearchResults"];

        return View(flightResults);
    }

I actually used NewtonSoft to serialise the objects to a string, and then back again in the target action. So you might want to try something like ...

using Newtonsoft.Json;
...
...

        ... Previous code omitted.
        //In your controller action, save the data to TempData...
        TempData["FlightSearchResults"] = JsonConvert.SerializeObject(FlightSearchResults);

        return RedirectToAction("flights");
    }

    public ActionResult flights()
    {
        string storedResults = TempData["FlightSearchResults"].ToString();

        FlightSearchResults flightResults = JsonConvert.DeserializeObject<FlightSearchResults>(storedResults);

        return View(flightResults);
    }
cometbill
  • 1,619
  • 7
  • 19
  • 41