0

I have the following action methods:

    [HttpGet]
    public ActionResult DBLookupIndex(DBLookupDTO dto)
    {
        dto.Areas = _ph.GetProfiles();
        return View(dto);
    }

    [HttpGet]
    public ActionResult Search(DBLookupDTO dto)
    {
        dto.Orders = _oh.GetOrders(dto.OrderNumber, dto.ProductNumber, dto.DateRange, dto.SelectDeleted, dto.AreaId);
        return RedirectToAction("DBLookupIndex", dto);
    }

The user simple enters valid information into one or more of the textboxes on the webpage, and submits it to the controller by pressing submit. This then calls the Search-action. By debugging, I have determined, that the function works. It does find what it should, but it is not passed on, when it redirects back to the DBLookupIndex-action.

My question is; What am I doing wrong? I have seen code examples similar to the one above provided as solutions for similar issues, but for some reason it does not work for me.

EDIT:

I realised after the first answer came, that I was missing some information. Whenever the page is loaded, it has to update a dropdown that is rendered in the view, in case new profiles/areas have been added. I do that with razor:

     <select name="AreaId" asp-for="AreaId" class="form-control">
         <option disabled selected value=""> -- Vælg et område -- </option>
         @foreach (var a in Model.Areas)
         {
             <option value="@a.ProfileId">@a.Name</option>
         }

That is why I have to used RedirectToAction, instead of having a new action render the same view. Unless there is a better way to do it? :)

Thank in advance for any help!

2 Answers2

0

The object parameter in RedirectToAction is meant to set querystring values for the URL that is generated and then sent to the browser as a "Redirect to other page" result. It is supposed to be an object similar to new { id = 7, otherParam = 5 }, or a Dictionary, but certainly not a recordset or any other kind of business data.

It seems like you want to show the View that belongs to the DBLookupIndex action. That can be done in a very simple way, like this:

[HttpGet]
public ActionResult Search(DBLookupDTO dto)
{
    dto.Orders = _oh.GetOrders(dto.OrderNumber, dto.ProductNumber, dto.DateRange, dto.SelectDeleted, dto.AreaId);
    return View("DBLookupIndex", dto); // Render the "DBLookupIndex" view and pass it the dto object
}

Update: if you need dto.Areas to be always set, you can create a method that just does that.

Like this (1):

[HttpGet]
public ActionResult DBLookupIndex(DBLookupDTO dto)
{
    SetAreas(dto);
    return View(dto);
}

[HttpGet]
public ActionResult Search(DBLookupDTO dto)
{
    dto.Orders = _oh.GetOrders(dto.OrderNumber, dto.ProductNumber, dto.DateRange, dto.SelectDeleted, dto.AreaId);
    SetAreas(dto);
    return View("DBLookupIndex", dto);
}

private void SetAreas(DBLookupDTO dto)
{
    dto.Areas = _ph.GetProfiles();
}

Or like this (2):

[HttpGet]
public ActionResult DBLookupIndex(DBLookupDTO dto)
{
    return SetAreasAndView(dto);
}

[HttpGet]
public ActionResult Search(DBLookupDTO dto)
{
    dto.Orders = _oh.GetOrders(dto.OrderNumber, dto.ProductNumber, dto.DateRange, dto.SelectDeleted, dto.AreaId);
    return SetAreasAndView(dto);
}

private ActionResult SetAreasAndView(DBLookupDTO dto)
{
    dto.Areas = _ph.GetProfiles();
    return View("DBLookupIndex", dto);
}
Peter B
  • 22,460
  • 5
  • 32
  • 69
0

In addition to Peter B's answer, another option is to store it in the TempData object that exists on your base controller.

[HttpGet]
public ActionResult Search(DBLookupDTO dto)
{
    var orders = new List<Order>();

    TempData["orders"] = orders;
    return RedirectToAction("DBLookupIndex", dto);
}

You can then retrieve the data on the following request like so:

[HttpGet]
public ActionResult DBLookupIndex(DBLookupDTO dto)
{
    var yourData = (List<Order>)TempData["orders"];
    ...
    return View(dto);
}

The TempData object exists for a single request and is then cleared up. You can read more about it here.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Joseph Woodward
  • 9,191
  • 5
  • 44
  • 63
  • In theory, that seems like the way to go, but the problem is, that my GetOrder()-method returns a List (list of orders). I've quickly been trying to google, but haven't been able to find a solution to that problem (at least none that I could understand with my current programming skill level). Maybe you have a suggestion? Thanks for helping btw! – Thomas Kjærhus Jørgensen Jan 10 '17 at 13:19
  • You should just be able to store the object direct, then cast it on it's way out (see my updated answer). Alternatively you could serialise/deserialise it to/from JSON as proposed [here](http://stackoverflow.com/questions/34638823/store-complex-object-in-tempdata-in-mvc-6) – Joseph Woodward Jan 10 '17 at 13:35
  • 1
    Thanks alot for the help! ... and thanks for the links. I have never used TempData before, because I didn't know how to use it properly, but I now have a greater understanding of how it works. Both you and Peter came with solid (and working) solutions to my problem, so I will try to figure out which one I will use. Thank for taking time to help me out :) – Thomas Kjærhus Jørgensen Jan 10 '17 at 13:53
  • No problem. Happy to help! – Joseph Woodward Jan 10 '17 at 14:13