0

I have a view model which contains a List and when I pass the view model to the and attempt to use foreach loop to display the list contents nothing is displayed on screen. I have debugged and when the list is definitely being filled with data before being passed to the view so I am at a loss to see why it won't display. If any one has any suggestions on what I've done wrong I 'd really appreciate it. Thanks!

My Controller method

    [HttpPost]
    public ActionResult Create(OrderVM model)
    {

        //get the currentUser ID to search database for user
        string currentUserId = User.Identity.GetUserId();

        //instantiate new ApplicationUser and assign the current user to this var
        ApplicationUser currentUser = db.Users.FirstOrDefault(x => x.Id == currentUserId);

        //instantiate new Event and assign the event being booked to this var
        Event currentEvent = db.Events.Find(model.EventID);

        // Initialize an Order data model, save it and gets its ID
        Order order = new Order
       {
           OrderDate = DateTime.Now,
           EventID = model.EventID,
           Event = currentEvent,
           user = currentUser

       };
        db.Orders.Add(order);
        db.SaveChanges(); 
        float total = 0;

        // Initialise a TicketsOrdered data model for each valid ticket
        foreach (TicketVm ticket in model.Tickets.Where(t => t.Quantity > 0))
        {
            total += (ticket.Price*ticket.Quantity);
            TicketsOrdered ticketOrder = new TicketsOrdered
          {
              OrderID = order.OrderID,
              TicketID = ticket.TicketID,
              Quantity = ticket.Quantity
          };
            db.ticketsOrdered.Add(ticketOrder);
        }

        order.OrderTotal = total;
        currentEvent.Order.Add(order);
        currentUser.Order.Add(order);    
        db.SaveChanges(); 

        //instantiate new SummaryVm to display order to user and complete transaction
        SummaryVm summaryVm = new SummaryVm
        { 
            email = order.user.UserName, 
            orderID = order.OrderID,
            tickets = model.Tickets, 
            totalPrice = total, 
            eventID = model.EventID,
        };

        return RedirectToAction("OrderSummary", "Order", summaryVm);
    }

My ViewModels

public class SummaryVm
{

    public IList<TicketVm> tickets { get; set; }
    public string email { get; set; }
    public float totalPrice { get; set; }
    public int orderID { get; set; }
    public int eventID { get; set; }

}

public class TicketVm
{
    public int TicketID { get; set; }
    public string Description { get; set; }
    public float Price { get; set; }
    public int Quantity { get; set; }
}

My OrderSummary view

@model Site.ViewModels.SummaryVm
<head>
 <title>Summary</title> 
</head>
<body>
 <table class="table">
                    <thead>
                        <tr>
                            <th>Ticket Type</th>
                            <th><span contenteditable>Price</span></th>
                            <th><span contenteditable>Quantity</span></th>

                        </tr>
                    </thead>
                    <tbody>
                        @foreach (Site.ViewModels.TicketVm ticket in Model.tickets)
                        {
                            <tr>
                                               row
                                <td><span contenteditable>@ticket.Description</span></td>
                                <td><span contenteditable>@ticket.Price</span></td>
                                <td><span contenteditable>@ticket.Quantity</span></td>
                            </tr>
                        }
                    </tbody>
                </table>
</body>

3 Answers 3

3

As Saleem says, you don't want to use RedirectToAction. That will make another HTTP call, and make it harder for you to send that data over.

You have two options: 1) If you want to pass that data into that method (within the same controller) and do further work, you can have a parameter (possibly defaulted if it is being called elsewhere) and just use return OrderSummary(summaryVm);

2) This is how you most likely will want to do it. If both are using the same View, you can explicitly say what view to return with return View("OrderSummary", "Order", summaryVm);. That allows you change from looking for a view with the same name (or potentially controller) as the name of the method.

Sign up to request clarification or add additional context in comments.

Comments

1

Why are you calling RedirectToAction? It will never carry any data. Last parameter to RedirectToAction just carry route dictionary value. Please see https://msdn.microsoft.com/en-us/library/system.web.mvc.controller.redirecttoaction(v=vs.118).aspx#M:System.Web.Mvc.Controller.RedirectToAction%28System.String,System.String,System.Object%29

4 Comments

should I be calling return View(summaryVm) instead?
Yes and no. It depends what are you trying to do. if you decide to call View, you have to pass view name too as by convention it will call view named to action. So View(<view_name>,<model>)
e.g. in your case return View("OrderSummary", summaryVm)
Thank @Saleem I used return View and it worked perfectly.
0

I think you want to follow the PRG pattern here when posting data to the server. You just can't send data across in the call to RedirectToAction. You have to redirect to an OrderSummary controller action and fetch the data back from the database or push the data you want into the session or TempData so that it's available the next view.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.