Jacob
Jacob

Reputation: 227

Sessions in MVC 5 asp.net

I am doing a project about an Chinese food ordering system, and I am wanting show selected items in a view on another page. I am trying to use sessions, but I keep getting different errors, like "The model item passed into the dictionary is of type" and "object reference is not set to an instance of an object". How can I select the data, and show them in a different view? The project is linked up to a database, the DishID and other instances should be connected through the database.

Controller:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using KinaRest.Models;
using KinaRest.View_Models;
using KinaRest.Infrastructure;

namespace KinaRest.Controllers
{
    public class TakeawayController : Controller
    {
        private Basket basket = new Basket();

        [ChildActionOnly]
        public ActionResult BasketItemsList()
        {
            Basket basket = new Basket();
            return View("_Basket", basket.Items);
        }


        // GET: /Takeaway/

        private ChinaContext db = new ChinaContext();
         [HttpGet]
        public ActionResult Index()
        {
            return View(db.Dish.ToList());
        }


        [HttpPost]
         public ActionResult Index(BasketItem basketItem)
        {
            //Repository repository = new Repository();
            if (Session["Basket"] == null)
            {
                Session["Basket"] = new Basket();
            }
            else
            {
                basket = (Basket)Session["Basket"];
            }
            basket.AddItem(basketItem);

            return View("Test");
        }

    }
}

Model 1: Basket

namespace KinaRest.Infrastructure
{
    public class Basket
    {
        private List<BasketItem> items = new List<BasketItem>();


        public List<BasketItem> Items { get { return items; } }

        public void AddItem(BasketItem bi) {
            items.Add(bi);
        }
    }
}

Model 2: BasketItem

namespace KinaRest.Infrastructure
{
    public class BasketItem
    {
        public int DishId {get; set; }
        public int Number { get; set; }
        public decimal Price { get; set; }
        }
}

In this view, we are trying to collect the data, such as the ID, the quantity(number) and price with a form:

@model IEnumerable<KinaRest.Models.Dish>

@{
    ViewBag.Title = "Index";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>Index</h2>

   <div class="form-group">
       @using (Html.BeginForm())
       {         

            foreach (var item in Model)
            {
                <div class="col-md-10">
                    @Html.DisplayFor(modelItem => item.DishId)
                </div>
                <div class="col-md-10">
                    @Html.DisplayFor(modelItem => item.Title) 
                </div>
                <div class="col-md-10">
                    @Html.DisplayFor(modelItem => item.Price)
                </div>
                <div class="col-md-10">
                    @Html.DisplayFor(modelItem => item.Description)
                </div>
                <div class="col-md-10">
                    @Html.DisplayFor(modelItem => item.Type.Type1)
                </div>
                <img src="@Url.Content("~/content/images/" + item.Image)" />





                @Html.EditorFor(model => item.Number, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => item.Number, "", new { @class = "text-danger" })
            <input type="submit" value="Tilføj" class="btn btn-default" />
                }
            }
        </div>

In this view, we are trying to access the sessions data:

@model List<KinaRest.Infrastructure.BasketItem>
@{
    ViewBag.Title = "Test";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>Test</h2>

<ul>
    @foreach (var item in Model)
    {
        <li>
            @Html.DisplayFor(modelItem => item.Number)
        </li>
    }
</ul>

and yes, I am new to MVC and I am still learning. Hope you guys can help.

Upvotes: 1

Views: 501

Answers (1)

Florian Schmidinger
Florian Schmidinger

Reputation: 4692

[HttpGet]
     public ActionResult Order(int id)
    {

        Dish dish = db.Dish.Single(d=> d.DishId == id); //database call here
        BasketItem basketItem = new BasketItem(){DishId = dish.?, Number = dish.?, Price = dish.Price }; // create a new BasketItem

        Basket basket; //create reference outside if block
        //Repository repository = new Repository();
        if (Session["Basket"] == null)
        {
            basket = new Basket();
            Session["Basket"] = basket;
        }
        else
        {
            basket = (Basket)Session["Basket"];
        }
        basket.AddItem(basketItem);

        return View("Test", basket.Items); //or return View(((Basket)Session["Basket"]).Items); // give the view the data
    }

take out the class field basket. As far as i know the controller is instanciated every time when a request is to be processed

View for ordering

@model IEnumerable<KinaRest.Models.Dish>

@{
    ViewBag.Title = "Index";
    Layout = "~/Views/Shared/_Layout.cshtml";
  }

<h2>Index</h2>
<table>
    <tr><th></th><th>Dish</th><th></th></tr>
    @foreach(var item in Model)
    {
        <tr><td><img src="@Url.Content("~/content/images/" + item.Image)" /></td><td>@html.displayfor(item => item.Name)</td><td>@Html.ActionLink("Add", "Order", "TakeAway", new {id = item.DishId})</td></tr>
    }
</table>

Upvotes: 1

Related Questions