0

Can someone tell what is wrong in my code? I've been searching several days a solution for this, but can't find any. Values from Form doesn't pass to view, only values that are "hardcoded" like OrderDate, CompanyID and so on, is added to database. I'm making my first MVC onlineshop and struggling with it quite a lot.

EDIT: Data to view is coming from db.Selection but I need to save data to model db.Cart with additional parameters. Maybe FormCollection is not right way to do this, but what is?

NVCONTROLLER:

public ActionResult Index()
        {
            return View(db.Selection);
        }

    public ActionResult AddtoCart()
    {
        return View("AddtoCart");
    }

    [HttpPost]
    [ValidateAntiForgeryToken()]
    public ActionResult AddtoCart(FormCollection form)
    {
        string Author = form["Author"];
        string ISBN = form["ISBN"];
        string BookName = form["BookName"];
        string Publisher = form["Publisher"];
        string Price = form["Price"];

        var cart = new Cart();
        cart.Orderdate = DateTime.Now;
        cart.CompanyID = 12345;
        cart.ISBN = Convert.ToInt32(ISBN);
        cart.BookName = BookName;
        cart.Price = Convert.ToInt32(Price);
        cart.IsInCart = true;
        cart.Author = Author;
        cart.Publisher = Publisher;
        cart.SentToJvs = false;
        cart.Reference = "NV kevät 1999";

        db.Cart.Add(cart);
        db.SaveChanges();

        return RedirectToAction("Index");
    }

VIEW

@model IEnumerable<STGchannelMVC.Models.Selection>
@using STGchannelMVC.Controllers
@{
    ViewBag.Title = "Index";
}
@using (Html.BeginForm("AddtoCart", "NV", FormMethod.Post))
{
    <p>
        Lisää tuotteet ostoskoriin
    </p>
    @Html.AntiForgeryToken()
    <div class="form-group">
        <table class="table">
            <tr>
                <th hidden>
                    @Html.DisplayNameFor(model => model.BookID)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.ISBN)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Author)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.BookName)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Publisher)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Price)
                </th>
                <th></th>
            </tr>
            @foreach (var item in Model)
            {
                <tr>
                    <td hidden>
                        @Html.DisplayFor(modelItem => item.BookID)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.ISBN)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.Author)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.BookName)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.Publisher)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.Price)
                    </td>
                    <td>
                        <button type="submit" class="btn btn-primary">Add to Cart</button>
                    </td>
                </tr>
            }
        </table>
    </div>
}
@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

MODEL

public class Cart
    {
        public int OrderID { get; set; }
        public Nullable<System.DateTime> Orderdate { get; set; }

        [Display(Name = "CompanyID")]
        public Nullable<long> CompanyID { get; set; }

        [Display(Name = "ISBN")]
        public Nullable<long> ISBN { get; set; }

        [Display(Name = "BookName")]
        public string BookName { get; set; }

        [Display(Name = "Price")]
        public Nullable<decimal> Price { get; set; }
        public Nullable<bool> IsInCart { get; set; }

        [Display(Name = "Author")]
        public string Author { get; set; }

        [Display(Name = "Publisher")]
        public string Publisher { get; set; }
        public Nullable<bool> SentToJvs { get; set; }
        public string Reference { get; set; }
    }
HeiJoe
  • 107
  • 8
  • Are you sure you are even passing the correct model to the controller? It looks like it is expecting a `FormCollection form` – JamesS Feb 28 '20 at 09:43
  • No i'm not sure =D I know something is wrong with my code, and maybe it is that.. I have to look that or if you have answer for that, please let me know. – HeiJoe Feb 28 '20 at 10:27
  • The model you pass to the controller when you are doing the form you are doing is the viewmodel which in this case seems to be `Selection`, but the controller method is expecting the model `FormCollection` – JamesS Feb 28 '20 at 10:51

1 Answers1

1

This question/answer might explain it better: MVC4 Razor - @Html.DisplayFor not binding to model

Basically you have two options:

In your view, you can keep using @Html.DisplayFor() but add @Html.HiddenFor() inside the foreach loop. Doesn't make much sense since there's no way for the values to be changed by the user.

@foreach (var item in Model)
    {
    @Html.HiddenFor(modelItem => item.BookID)
    @Html.HiddenFor(modelItem => item.ISBN)
    @Html.HiddenFor(modelItem => item.Author)
    @Html.HiddenFor(modelItem => item.BookName)
    @Html.HiddenFor(modelItem => item.Publisher)
    @Html.HiddenFor(modelItem => item.Price)
        <tr>
            <td hidden>
                @Html.DisplayFor(modelItem => item.BookID)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.ISBN)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Author)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.BookName)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Publisher)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Price)
            </td>
            <td>
                <button type="submit" class="btn btn-primary">Add to Cart</button>
            </td>
        </tr>
    }

Or instead of using @Html.DisplayFor(), use @Html.TextboxFor because DisplayFor does not render an input element that the user can interact with while TextboxFor does.

Andy Refuerzo
  • 3,312
  • 1
  • 31
  • 38