0

I have a post method that has my view model and all of its data

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult SpecialOrderSelection(JobOrder job, ItemViewModel model)
{               
   return RedirectToAction("SpecialOrderSummary", "JODetails", model);        
}

The 'special order selection' page is where a user is shown a list of parts and must choose if the part should be transferred, harvested, or disposed of. It returns the correct data to the controller. But after the submit happens I want to give the user a summary page of everything that they have done. To do this I tried passing the view model to a 'Order summary' page. With the get method looking like this

public ActionResult SpecialOrderSummary(ItemViewModel model)
{       
   return View(model);
}

Here is my Model

 public class ItemViewModel
    {
        [Required]
        public int ID { get; set; }
        public string ItemId { get; set; }
        public string ItemName { get; set; }
        public string MFGNumber { get; set; }
        public IList<ItemPartViewModel> Parts { get; set; }
        public IList<ItemComponentViewModel> Components{ get; set; }
        public IList<ComponentPartViewModel> ComponentParts { get; set; }
        public IList<ComponentSubCompViewModel> ComponentSubComps { get; set; }
        public IList<SubCompPartViewModel> SubCompParts { get; set; }

        public IList<SubCompSubCompViewModel> SubCompSubComps { get; set; }
        public IList<SubCompSubCompPartViewModel> SubCompSubCompParts { get; set; }

    }

And then I want the view to do something like this

@model PIC_Program_1._0.Models.ItemViewModel
@using PIC_Program_1._0.Models
@{
    ViewBag.Title = "SpecialOrderSummary";
}

@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()
    @*@Html.HiddenFor(model => model.ID)*@
    @Html.HiddenFor(x => x.ID)
    <h2>Special Order Summary</h2>
    <p style="color:red" class="noprint">Please review and verify </p>

    <h2>
        Transfers
    </h2>
    <h3> 
    Parts 
    </h3>
    foreach (var part in Model.Parts) // part is null here
    {
    <p>@part.PartName</p>
    }

}

But Model.Parts always has a count of 0. So I'm wondering how I can pass the data of a view model around. Any help is appreciated.

As David suggested, I tried doing it through AJAX but it won't go to the view page that I want it to go to, just reloads the same page. Here is my AJAX method

 $(document).ready(function () {
        $("button").click(function () {
            $.ajax({
                url: '@IGT.baseUrl/JODetails/SpecialOrderSummary',
                data: $('#form').serialize(),
                type: 'GET'
            });
        });
    });

  • What part is null? Can you show us your model? – derloopkat Jul 09 '20 at 21:37
  • @derloopkat Okay I added in my model. And I guess null might've been the wrong way to describe it, Model.parts just has no data in in it. –  Jul 09 '20 at 21:42
  • According to [this answer](https://stackoverflow.com/a/37198363/2516718), if you pass the model in a `RedirectToAction`, that would work for simple values but fails for complex objects like e.g. a collection. – derloopkat Jul 09 '20 at 22:04
  • When you're posting `ItemViewModel` back, if you don't put the list of items in a hidden input, they will be NULL! The form won't post back anything that is not with an input. My solution is, instead of using regular form post, to use Ajax. That way you don't have to re-fetch everything within the view model. – David Liang Jul 09 '20 at 22:08
  • @DavidLiang I can pass the entire ViewModel through Ajax? It's sending the data to the POST method, but I want to be able to move that model around as I want to give the user a summary of what they did to confirm their actions –  Jul 10 '20 at 14:23
  • @DavidLiang and if I do an AJAX call won't I stay on the same page? I'm trying to move to a different View page that still displays data from the ViewModel. I tried doing what you suggested and added it into my question –  Jul 10 '20 at 17:37
  • @JoshFontaine: Yea in general with AJAX you will stay on the same page, even though there are ways to call window.redirect to other pages. In your case, I would suggest, instead of passing the view model after you're done on the form post, passing the identifier of the object as the query string to the other page you want to display the data on. Then you can delegate the corresponding method under the other controller to fetch the data again by the identifier you passed. In your case the identifier is the job ID, item ID? I am not sure. – David Liang Jul 10 '20 at 17:42
  • We don't know the domain you're working on, and don't know the relationships between your JobOrder and Item so it's hard to craft out what you really need. There are many ways to do things. If I am guessing right - 1 Job Order has many items, and the form was there to let user update 1 particular item within 1 job order, then I would have 2 controllers - JobOrderController and ItemController. The form would be posting back to Edit() method under ItemController, and then upon it's done, it uses RedirectToAction() to redirect to Summary() method in the JobOrderController. – David Liang Jul 10 '20 at 17:56
  • @JoshFontaine, you wouldn't need Ajax if you were using MVVM design pattern properly. What you called view-model is actually a model. The view-model is supposed to contain only the fields you would be using on the view; not all fields in the model. That's why the design pattern discriminates between "model" and "view-model". Once you post only the fields you need and this matches the view-model, the controller would perform update operation in the database only for these fields. – derloopkat Jul 12 '20 at 13:28
  • @DavidLiang the process I am doing is transferring one item to another item which is a type of 'JobOrder'. The user first selected what they wanted to do with the parts/components. Now I'm trying to figure out how to pass that data around. (Summary page of what they selected/passing selected data to other controllers so that the parts and components will do the necessary actions when an order is 'released' meaning once it's released, do the disposal,harvesting, and transferring) . –  Jul 13 '20 at 14:36

1 Answers1

1

I am assuming that the client passes job and model in the request body.

I'll show what happens with this sequence: https://swimlanes.io/#pZLBbhNBDIbv+xRWLgUpTQq9rUQPBKjgkopEQj06u25notlxGHuT5u3xzCQpSHDitDP2rP35969eA7WwGFOiqPCRHO49j6lpmkXwOXR9BytKe0otONVdO5/3PKCPs46H+ZZ7UvRB5rKjzmPg1FMSCtSp59g0kZXaRp0XSPRzJFE4+BDA2hD4CDmx4f4I6gi2vAGMfTkPVjnMYJ2PpI574Cf4o44dH5artZFWvkxamVv4Tr1PxgDKgAUFvi0/VdQFR00cAqXZqkIvM/RqHAZMR7ggE/Bmm2tMCssEjjwCJoIdivj4DI7s0jNJvFL7wsGhlkf0YnV11mR4qWyJZMdR8j0Wqly/qwo7FOisBdzevCvzo+lCaEwwCdxhxm//JXWl/q9tnUvUwX84ioBntjf3zM+BYOESDzSFLybrE79M4YFFB4xT+BqFh+gROBUFyJq/tXk78nuSMouBgCjqKGVEe3h7874oZ2k2JdJlqSdlTC4zYVe1pj47JYfPapzkyfZ4NcSVnJ1iMQwHPArcf17XNZzGsYw1vGzwN6M9Wr+zVf5mi1fXlh8+xDGEpvkF

enter image description here

You just don't have to redirect the client, simply return the oter action's result:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult SpecialOrderSelection(JobOrder job, ItemViewModel model)
{               
   return SpecialOrderSummary(model);        
}
ddfra
  • 2,413
  • 14
  • 24
  • Thanks for that explanation! Strangely though it seems to be kicking me back to the page I was just at. As I'm getting a null exception error on that page as it seems to be reloading the same page but just with a different model for the view class. odd. Maybe its just a bug with visual studio for now –  Jul 09 '20 at 22:00
  • Could you add the code of the action SpecialOrderSummary? – ddfra Jul 09 '20 at 22:03
  • what do you mean? Don't I have that added in my question already? Or is there something else you are talking about –  Jul 09 '20 at 22:07
  • My fault! I missed it. The problem is that the model is not what you expect at the start of SpecialOrderSelection method. If you can show the raw request payload (F12 then network tab on your browser) we can try to understand why it's not working. – ddfra Jul 09 '20 at 22:13
  • Unfortunately if I have my code the way you have it shown, it wont compile because it has null references –  Jul 09 '20 at 22:15
  • It's an error on the page that I just came from, it's like it's loading the same page but just with a different model and my view page was dependant on a different model so there are nulls. But my point is that it shouldn't even be going through that page anymore –  Jul 10 '20 at 14:15