Reputation: 373
I am trying to create a combined view of an Index Page (which has product list using IEnumerable
) and with the Create Page (which has the add / save stuff)
and i am getting errors with the lambda expressions.
Here's my code:
@model IEnumerable<OIS.Models.Category>
<table class="table">
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.category_name)
</th>
<th>
@Html.DisplayNameFor(model => model.date_created)
</th>
<th>
@Html.DisplayNameFor(model => model.date_updated)
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.category_name)
</td>
<td>
@Html.DisplayFor(modelItem => item.date_created)
</td>
<td>
@Html.DisplayFor(modelItem => item.date_updated)
</td>
<td>
@Html.ActionLink("Edit", "Edit", new { id = item.ID }) |
@Html.ActionLink("Details", "Details", new { id = item.ID }) |
@Html.ActionLink("Delete", "Delete", new { id = item.ID })
</td>
</tr>
}
</tbody>
</table>
//For for Creating new Item
@using (Html.BeginForm()){
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Category</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
//Im Gettig Error with this line (model => model.category_name)
@Html.LabelFor(model => model.category_name, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
//Im Gettig Error with this line (model => model.category_name)
@Html.EditorFor(model => model.category_name, new { htmlAttributes = new { @class = "form-control" } })
//Im Gettig Error with this line (model => model.category_name)
@Html.ValidationMessageFor(model => model.category_name, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
What shall I do? Edited: Here's my controller
namespace OIS.Controllers{
public class CategoryController : Controller
{
private DbOnlineIS db = new DbOnlineIS();
// GET: Category
public ActionResult Index()
{
return View(db.Categories.ToList());
}
// Post: Category
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Index([Bind(Include = "ID,category_name,date_created,date_updated")] Category category)
{
if (ModelState.IsValid)
{
category.date_created = DateTime.Now;
category.date_updated = DateTime.Now;
db.Categories.Add(category);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(category);
}
// GET: Category/Create
public ActionResult Create()
{
return View();
}
// POST: Category/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "ID,category_name,date_created,date_updated")] Category category)
{
if (ModelState.IsValid)
{
category.date_created = DateTime.Now;
category.date_updated = DateTime.Now;
db.Categories.Add(category);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(category);
}
Upvotes: 0
Views: 2665
Reputation: 10209
To make a combined view you have to do something like below.
Create a ViewModel that have 2 properties
public class CategoryViewModel {
public IEnumerable<OIS.Models.Category> Categories { get; set; }
public Category Category { get; set; }
}
After that you move, Create and List, from the View in 2 partial views. Let's say _CategoryCreatePartial.cshtml
and _CategoryListPartial.cshtml
.
Than the combined view become something like this, Index.cshtml
@model OIS.Models.CategoryViewModel
@Html.Partial("_CategoryListPartial", Model.Categories)
@Html.Partial("_CategoryCreatePartial", Model.Category)
Partial Views:
_CategoryListPartial.cshtml
@model IEnumerable<OIS.Models.Category>
<table class="table">
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.category_name)
</th>
<th>
@Html.DisplayNameFor(model => model.date_created)
</th>
<th>
@Html.DisplayNameFor(model => model.date_updated)
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.category_name)
</td>
<td>
@Html.DisplayFor(modelItem => item.date_created)
</td>
<td>
@Html.DisplayFor(modelItem => item.date_updated)
</td>
<td>
@Html.ActionLink("Edit", "Edit", new { id = item.ID }) |
@Html.ActionLink("Details", "Details", new { id = item.ID }) |
@Html.ActionLink("Delete", "Delete", new { id = item.ID })
</td>
</tr>
}
</tbody>
</table>
_CategoryCreatePartial.cshtml
@model OIS.Models.Category
@using (Html.BeginForm("Create", "Category")){
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Category</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
//Im Gettig Error with this line (model => model.category_name)
@Html.LabelFor(model => model.category_name, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
//Im Gettig Error with this line (model => model.category_name)
@Html.EditorFor(model => model.category_name, new { htmlAttributes = new { @class = "form-control" } })
//Im Gettig Error with this line (model => model.category_name)
@Html.ValidationMessageFor(model => model.category_name, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
Controller and Index action
public class CategoryController : Controller
{
private DbOnlineIS db = new DbOnlineIS();
public ActionResult Index() {
var categoryViewModel = new CategoryViewModel();
categoryViewModel.Categories = db.Categories.ToList();
categoryViewModel.Category = new Category();
return View(categoryViewModel); // list + create category
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(Category category) // call this action to create category.
{
if (ModelState.IsValid)
{
category.date_created = DateTime.Now;
category.date_updated = DateTime.Now;
db.Categories.Add(category);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(category);
}
}
Upvotes: 6
Reputation: 5771
You will need to create another ViewModel to cater to this requirement of showing a List as well as the Create screen.
public class CategoryViewModel
{
public List<OIS.Models.Category> Categories {get;set;}
public OIS.Models.Category Category {get;set;}
}
In your razor view set the model to this new ViewModel
@model CategoryViewModel
In your enumeration you now access the list from within this new ViewModel
@foreach (var item in Model.Categories)
For your create section access the category from within the ViewModel
@Html.LabelFor(model => model.Category.category_name, htmlAttributes: new { @class = "control-label col-md-2" })
On the same lines you will need to refactor your View page.
In your controller you must currently passing a List. You will need to change that to pass your new CategoryViewModel
List<Category> categories = "your db call";
CategoryViewModel viewModel = new CategoryViewModel();
viewModel.Categories = categories;
viewModel.Category = new Category();
return View(viewModel);
Upvotes: 2
Reputation: 651
Your Problem is in the <thead>
. You try to access properties from the Category Model:
@Html.DisplayNameFor(model => model.category_name)
But your Model is an IEnumerable and has no property category_name
.
Upvotes: 0