How to get related data with many-to-many relationship table? - asp.net-core

I have three tables. The first one is Movie, the second one Category, and the third one MovieCategory. I listed movies, but I want to choose a category and then list the movies for each category.
How do I make the controller? I've included my business objects, view, and current controller below.
Movie Entity
public class Movie : IEntity
{
public int Id { get; set; }
public string Name { get; set; }
public string Summary { get; set; }
public string Director { get; set; }
public string Banner { get; set; }
public ICollection<MoviesCategory> MoviesCategory { get; set; }
}
Category Entity
public class Category : IEntity
{
public int Id { get; set; }
public string CategoryName { get; set; }
public ICollection<MoviesCategory> MoviesCategory { get; set; }
}
MovieCategory Entity
public class MoviesCategory : IEntity
{
public int Id { get; set; }
public int MovieId { get; set; }
public int CategoryId { get; set; }
public Category Category { get; set; }
public Movie Movie { get; set; }
}
Controller
public IActionResult List()
{
var movies = _movieService.GetAll();
MovieListViewModel movieListViewModel = new MovieListViewModel()
{
Movies = movies
};
return View(movieListViewModel);
}
View
#foreach (var item in Model.Movies)
{
<tr>
#Html.HiddenFor(modelItem => item.Id)
<td>
#Html.DisplayFor(modelItem => item.Id)
</td>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#if (!string.IsNullOrEmpty(item.Summary) && item.Summary.Length > 35)
{
<p>#(item.Summary.Substring(0,35))</p>
}
</td>
<td>
#Html.DisplayFor(modelItem => item.Director)
</td>
<td>
<img src="~/images/#item.Banner" width="105" height="140" class="img-thumbnail" />
</td>
<td>
<i title="Edit" class="fas fa-edit" style="color:coral"></i>
<i title="Detail" class="fas fa-info-circle" style="color:cornflowerblue"></i>
<td>
<tr>
}

In order to get a Category and its related Movies do the following:
Create a view model that holds the data for Category and Movies in order to have a strongly typed view:
public class MovieData
{
public Category Category { get; set; }
public IEnumerable<Movies> Movies { get; set; }
}
Then in your controller you query the database like this:
public async Task<IActionResult> MovieDataAction(int catId)
{
var data = await context
.Categories
.Where(c => c.Id == catId) //Category Id
.Include(c => c.MoviesCategory)
.ThenInclude(p => p.Movie)
.Select(cat => new { Category = cat, Movies = cat.MoviesCategory.Select(w => w.Movie) })
.FirstOrDefaultAsync();
var vData = new MovieData(){
Category = data.Category,
Movies = data.Movies
};
return View(vData);
}

I made a demo based on your description like below:
View:
#model MovieListViewModel
#{
ViewData["Title"] = "List";
}
<h1>List</h1>
#Html.DropDownListFor(modelItem => modelItem.CategoryId, Model.Categories, "Select Category",
new { #class = "form-control" })
<table>
#foreach (var item in Model.Movies)
{
<tr>
#Html.HiddenFor(modelItem => item.Id)
<td>
#Html.DisplayFor(modelItem => item.Id)
</td>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#if (!string.IsNullOrEmpty(item.Summary) && item.Summary.Length > 35)
{
<p>#(item.Summary.Substring(0,35))</p>
}
</td>
<td>
#Html.DisplayFor(modelItem => item.Director)
</td>
<td>
<i title="Edit" class="fas fa-edit" style="color:coral"></i>
<i title="Detail" class="fas fa-info-circle" style="color:cornflowerblue"></i>
<td>
</tr>
}
</table>
#section scripts{
<script>
$("#CategoryId").on("change", function () {
var id = $(this).val();
window.location.href = "/Movie/List?id=" + id;
})
</script>
}
Controller:
public IActionResult List(int? id)
{
var movies = _context.Movies.ToList();
var categories = _context.Categories.ToList();
if(id != null)
{
movies = _context.MoviesCategories.Where(c => c.CategoryId == id).Select(m => m.Movie).ToList();
}
MovieListViewModel movieListViewModel = new MovieListViewModel()
{
CategoryId = id ?? 0,
Categories = new List<SelectListItem>(),
Movies = movies
};
foreach(var category in categories)
{
movieListViewModel.Categories.Add(new SelectListItem { Text = category.CategoryName, Value = category.Id.ToString() });
}
return View(movieListViewModel);
}
Result:

Related

Get data from Ajax in ASP.NET Core not working?

I'm new at ASP.NET Core, and this is how I get data from Ajax.
I have a View Model like this
public class RequestSearchDefaultModel
{
public string FromToDate { get; set; }
public int Status { get; set; }
public List<SelectListItem> StatusType { get; set; }
public DateTime FromDate { get; set; }
public DateTime ToDate { get; set; }
public IEnumerable<RequestViewModel> requestViewModel { get; set; }
}
When I search the form, I use Ajax to get the data
function OpenSearch() {
var stt = $('#StatusDropDown').val();
var daterange = $('#daterange').val();
var url = "#Url.Action("Search","RequestApproval")";
var model = { FromToDate: daterange, Status: stt };
$.ajax({
type: "POST",
data: JSON.stringify(model),
url: url,
contentType: "application/json",
}).done(function (res) {
console.log("here");
$('#myTable').html(res);
})
}
This is controller
[HttpPost]
public async Task<IActionResult> Search([FromBody] RequestSearchDefaultModel m)
{
m.FromDate = DateTime.Parse(m.FromToDate.Substring(0, 10)).Add(new TimeSpan(00, 0, 0));
m.ToDate = DateTime.Parse(m.FromToDate.Substring(14)).Add(new TimeSpan(23, 59, 59));
var request = _headerService.Search();
m.requestViewModel = _mapper.Map<IEnumerable<RequestViewModel>>(request);
return PartialView("_RequestBody", m);
}
This is the view
<div class="card-body">
<div class="table-responsive" id="myTable">
#Html.Partial("_RequestBody")
</div>
</div>
And this is the partial view
#model RequestSearchDefaultModel
<table class="table table-striped">
<thead>
<tr>
<th>Seq.</th>
<th>Title</th>
<th>Status</th>
<th>Draft Date</th>
<th>Final Approval Date</th>
</tr>
</thead>
<tbody id="RequestBody">
#if (Model.requestViewModel == null)
{
}
else
{
foreach (var item in Model.requestViewModel)
{
<tr>
<td>#item.ID</td>
<td>#item.DocumentNo</td>
<td>
<a asp-action="Edit" asp-route-id="#item.ID">#item.Title</a>
</td>
<td>#item.DraftDate</td>
</tr>
}
}
</tbody>
</table>
But I can't get the data, I don't know where I wrong, so please help. Thanks in advance.

Link in partial Razor Page fires wrong OnGet

I am using a razor page to display an ItemT model and at the bottom I inserted a partial view to show all properties (which are not assigned to this model in a n:m relation).
The PageModel 'FreePropertiesToItemT' has two public properties:
public ItemT ItemT { get; set; } // the one Item to show
public IList<PropertyIndexViewModel> FreeProperties { get; set; } // all free properties
An OnGetAsync(int? id) Method is called which works fine. The Page shows all data correctly.
The view displays a link for every Property:
<a asp-page-handler="addProperty" asp-route-id="#item.PropertyID">add</a>
This creates the link:
add
This is the correct link (I think). The route, id value and the handler are correct because there is a second OnGet Method in the PageModel:
public async Task<IActionResult> OnGetaddPropertyAsync(int? id)
However, the link only calls OnGetAsync (and not OnGetaddProppertyAsync) every time and, of course, for every Property!
What am I missing?
Model of ItemT:
public class ItemT
{
[Key]
public int ItemTID { get; set; }
[Required]
[StringLength(100, MinimumLength = 1)]
[Display(Name = "ItemT")]
public string Title { get; set; }
public bool isActive { get; set; } = true;
public virtual ICollection<ItemTProperty> ItemTProperties { get; set; }
}
ViewModel of free properties:
public class PropertyIndexViewModel
{
[Key]
public int PropertyID { get; set; }
[Required]
[StringLength(100, MinimumLength = 1)]
public string Title { get; set; }
public bool DefaultsOnly { get; set; }
[Display(Name = "Unit")]
public string Unit { get; set; }
[Display(Name = "Valuetype")]
public string Valuetype { get; set; }
}
The Page to list one ItemT:
#page
#model Inventory.Areas.Inventory.Pages.ItemTs.FreePropertiesToItemTModel
#{
ViewData["Title"] = "FreePropertiesToItemT";
}
<h1>Free Properties</h1>
<div>
<h4>ItemT</h4>
<hr />
<dl class="row">
<dt class="col-sm-2">
#Html.DisplayNameFor(model => model.ItemT.Title)
</dt>
<dd class="col-sm-10">
#Html.DisplayFor(model => model.ItemT.Title)
</dd>
<dt class="col-sm-2">
#Html.DisplayNameFor(model => model.ItemT.isActive)
</dt>
<dd class="col-sm-10">
#Html.DisplayFor(model => model.ItemT.isActive)
</dd>
</dl>
</div>
<div>
<a asp-page="./Edit" asp-route-id="#Model.ItemT.ItemTID">Edit</a> |
<a asp-page="./Index">Back to List</a>
</div>
<p></p>
<div>
#{
ViewData["FreeProperties"] = true;
}
<partial name="../Properties/_Properties.cshtml" model="Model.FreeProperties" />
</div>
The Partial which is loaded:
#using Inventory.DAL.ViewModels
#model IList<PropertyIndexViewModel>
<table class="table">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model[0].Title)
</th>
<th>
#Html.DisplayNameFor(model => model[0].DefaultsOnly)
</th>
<th>
#Html.DisplayNameFor(model => model[0].Unit)
</th>
<th>
#Html.DisplayNameFor(model => model[0].Valuetype)
</th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Title)
</td>
<td>
#Html.DisplayFor(modelItem => item.DefaultsOnly)
</td>
<td>
#Html.DisplayFor(modelItem => item.Unit)
</td>
<td>
#Html.DisplayFor(modelItem => item.Valuetype)
</td>
<td>
#if (ViewBag.FreeProperties != null)
{
<a asp-page-handler="addProperty" asp-route-id="#item.PropertyID">add</a>
}
</td>
</tr>
}
</tbody>
</table>
And the c# code behind the page:
namespace Inventory.Areas.Inventory.Pages.ItemTs
{
public class FreePropertiesToItemTModel : PageModel
{
private readonly IUnitOfWork _uow;
public FreePropertiesToItemTModel(IUnitOfWork uow)
{
_uow = uow;
}
public ItemT ItemT { get; set; }
public IList<PropertyIndexViewModel> FreeProperties { get; set; }
public async Task<IActionResult> OnGetAsync(int? id)
{
if (id == null)
{
return NotFound();
}
ItemT = await _uow.ItemTRepo.getById((int)id);
if (ItemT == null)
{
return NotFound();
}
FreeProperties = await _uow.PropertyRepo.getFreePropertiesForItemT((int)id);
return Page();
}
public async Task<IActionResult> OnGetaddPropertyAsync(int? id)
{
if( id == null)
{
return NotFound();
}
if(ItemT == null) { return NotFound(); }
await _uow.ItemTRepo.addProperty(ItemT.ItemTID, (int)id);
await _uow.Commit();
return Page();
}
}
}
The issue is that your handler name error ,change it like below:
public async Task<IActionResult> OnGetAddPropertyAsync(int? id)
The first letter of handler name must be capitalized , otherwise handler=addProperty in the url is treated as a query-string parameter not a handler name.

For each student make comma-separated list of all courses for which he enlisted

Could somebody help me for each student make comma-separated list of all courses for which he enlisted?
I need to modify a Contoso University application with a comma-separated list.
Student Controller:
public ActionResult Index(string studentEnrollment, string sortOrder, string currentFilter, string searchString, int? page)
{
ViewBag.CurrentSort = sortOrder;
ViewBag.NameSortParm = String.IsNullOrEmpty(sortOrder) ? "name_desc" : "";
ViewBag.DateSortParm = sortOrder == "Date" ? "date_desc" : "Date";
if (searchString != null)
{
page = 1;
}
else
{
searchString = currentFilter;
}
ViewBag.CurrentFilter = searchString;
var students = studentService.GetAll();
var studentViewModel = Mapper.Map<IEnumerable<Student>, IEnumerable<StudentViewModel>>(students);
if (!String.IsNullOrEmpty(searchString))
{
students = students.Where(s => s.LastName.ToUpper().Contains(searchString.ToUpper())
|| s.FirstMidName.ToUpper().Contains(searchString.ToUpper()));
}
switch (sortOrder)
{
case "name_desc":
students = students.OrderByDescending(s => s.LastName);
break;
case "Date":
students = students.OrderBy(s => s.EnrollmentDate);
break;
case "date_desc":
students = students.OrderByDescending(s => s.EnrollmentDate);
break;
default:
students = students.OrderBy(s => s.LastName);
break;
}
int pageSize = 3;
int pageNumber = (page ?? 1);
return View(students.ToPagedList(pageNumber, pageSize));
}
Course Controller:
public ActionResult Index(int? page)
{
int pageNumber = page ?? 1;
var courses = courseService.GetAll();
var coursesViewList = Mapper.Map<IEnumerable<Course>, IEnumerable<CourseViewModel>>(courses);
var model = coursesViewList.ToPagedList(pageNumber, PageSize);
return View(model);
}
Student Model:
public int ID { get; set; }
[Display(Name = "Last Name")]
public string LastName { get; set; }
[Display(Name = "First Name")]
public string FirstMidName { get; set; }
[Display(Name = "Enrollment Date")]
[DisplayFormat(DataFormatString = "{0:g}", ApplyFormatInEditMode = true)]
public DateTime EnrollmentDate { get; set; }
[Display(Name = "Date Of Birth")]
[DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}", ApplyFormatInEditMode = true)]
public DateTime DateOfBirth { get; set; }
public virtual ICollection<Enrollment> Enrollments { get; set; }
public List<Comment> Comments { get; set; }
Course Model:
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int CourseID { get; set; }
[Required]
public string Title { get; set; }
public int Credits { get; set; }
public int StudentId { get; set; }
public virtual Student Student { get; set; }
public virtual ICollection<Enrollment> Enrollments { get; set; }
View:
#model PagedList.IPagedList<ContosoUniversity.Models.Student>
#using PagedList.Mvc;
<link href="~/Content/PagedList.css" rel="stylesheet" type="text/css" />
#{
ViewBag.Title = "Students";
}
<h2>Students</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
#using (Html.BeginForm("Index", "Student", FormMethod.Get))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<p>
Find by name: #Html.TextBox("SearchString", ViewBag.CurrentFilter as string)
<input type="submit" value="Filter" />
</p>
}
<table class="table">
<tr>
<th>
#Html.ActionLink("Last Name", "Index", new { sortOrder = ViewBag.NameSortParm })
</th>
<th>
First Name
</th>
<th>
#Html.ActionLink("Enrollment Date", "Index", new { sortOrder = ViewBag.DateSortParm })
</th>
<th>
Date Of Birth
</th>
<th>
Courses
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.LastName)
</td>
<td>
#Html.DisplayFor(modelItem => item.FirstMidName)
</td>
<td>
#Html.DisplayFor(modelItem => item.EnrollmentDate)
</td>
<td>
#Html.DisplayFor(modelItem => item.DateOfBirth)
</td>
<td>
</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>
}
</table>
<br />
Page #(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber) of #Model.PageCount
#Html.PagedListPager(Model, page => Url.Action("Index",
new { page, sortOrder = ViewBag.CurrentSort, currentFilter = ViewBag.CurrentFilter }))
Please tell me somebody the easiest way to do it!
Without knowing the model for the Enrollment class, assuming it has a Course property which returns a Course object, you can just do this in your view (where item is the Student object in your foreach loop):
#string.Join(",", item.Enrollments.Select(e => e.Course.Title))

CS0234: type or namespace name 'StudentViewModel.' does not exist in the namespace 'ContosoUniversity.ViewModels'

Error : CS0234: The type or namespace name 'StudentViewModel' does not exist in the namespace 'ContosoUniversity.ViewModels' (are you missing an assembly reference?)
https://www.dropbox.com/s/vqusln7le5fklxg/%D0%91%D0%B5%D0%B7%D1%8B%D0%BC%D1%8F%D0%BD%D0%BD%D1%8B%D0%B9.jpg?dl=0
public ActionResult Index(string sortOrder, string currentFilter, string searchString, int? page)
{
ViewBag.CurrentSort = sortOrder;
ViewBag.NameSortParm = String.IsNullOrEmpty(sortOrder) ? "name_desc" : "";
ViewBag.DateSortParm = sortOrder == "Date" ? "date_desc" : "Date";
if (searchString != null)
{
page = 1;
}
else
{
searchString = currentFilter;
}
ViewBag.CurrentFilter = searchString;
var students = from s in studentService.GetAll()
select s;
if (!String.IsNullOrEmpty(searchString))
{
students = students.Where(s => s.LastName.ToUpper().Contains(searchString.ToUpper())
|| s.FirstMidName.ToUpper().Contains(searchString.ToUpper()));
}
switch (sortOrder)
{
case "name_desc":
students = students.OrderByDescending(s => s.LastName);
break;
case "Date":
students = students.OrderBy(s => s.EnrollmentDate);
break;
case "date_desc":
students = students.OrderByDescending(s => s.EnrollmentDate);
break;
default:
students = students.OrderBy(s => s.LastName);
break;
}
int pageSize = 3;
int pageNumber = (page ?? 1);
return View(students.ToPagedList(pageNumber, pageSize));
}
My Class
using ContosoUniversity.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
namespace ContosoUniversity.ViewModels
{
public class StudentViewModel
{
public int ID { get; set; }
[Display(Name = "Last Name")]
public string LastName { get; set; }
[Display(Name = "First Name")]
public string FirstMidName { get; set; }
[Display(Name = "Enrollment Date")]
[DisplayFormat(DataFormatString = "{0:g}", ApplyFormatInEditMode = true)]
public DateTime EnrollmentDate { get; set; }
[Display(Name = "Date Of Birth")]
[DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}", ApplyFormatInEditMode = true)]
public DateTime DateOfBirth { get; set; }
public string FullName
{
get
{
return FirstMidName + LastName;
}
}
public virtual ICollection<Enrollment> Enrollments { get; set; }
public List<Comment> Comments { get; set; }
}
}
View:
#model PagedList.IPagedList<ContosoUniversity.ViewModels.StudentViewModel>
#using PagedList.Mvc;
<link href="~/Content/PagedList.css" rel="stylesheet" type="text/css" />
#{
ViewBag.Title = "Students";
}
<h2>Students</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
#using (Html.BeginForm("Index", "Student", FormMethod.Get))
{
<p>
Find by name: #Html.TextBox("SearchString", ViewBag.CurrentFilter as string)
<input type="submit" value="Search" />
</p>
}
<table class="table">
<tr>
<th>
#Html.ActionLink("Last Name", "Index", new { sortOrder = ViewBag.NameSortParm })
</th>
<th>
First Name
</th>
<th>
#Html.ActionLink("Enrollment Date", "Index", new { sortOrder = ViewBag.DateSortParm })
</th>
<th>
Date Of Birth
</th>
<th>
Full Name
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.LastName)
</td>
<td>
#Html.DisplayFor(modelItem => item.FirstMidName)
</td>
<td>
#Html.DisplayFor(modelItem => item.EnrollmentDate)
</td>
<td>
#Html.DisplayFor(modelItem => item.DateOfBirth)
</td>
<td>
#Html.DisplayFor(modelItem => item.FullName)
</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>
}
</table>
<br />
Page #(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber) of #Model.PageCount
#Html.PagedListPager(Model, page => Url.Action("Index",
new { page, sortOrder = ViewBag.CurrentSort, currentFilter = ViewBag.CurrentFilter }))
I think something might be wrong with view model or automapper if need some more code please write to me!

Saving multiple records on submit click into differnt entities in MVC4. Not getting values from view in Controller

I am trying to save the class attendance for multiple students on click of submit button. I am able to create the blank records in the concern tables and then populate the data in view.
I have the following view model:
public class TeacherAttendanceModel
{
#region Required Properties
public long ScholarAttendanceId { get; set; }
public string Student { get; set; }
public bool Absent { get; set; }
public string AbsentComment { get; set; }
public bool Uniform { get; set; }
public bool Homework { get; set; }
public string HomeworkComment { get; set; }
public String UniformCommentSelected { get; set; }
public IEnumerable<String> UniformComment { get; set; }
#endregion
}
My Controller is as below.
public class TeacherAttendanceController : Controller
{
//
// GET: /TeacherAttendance/
public ActionResult Index()
{
long classId = Success.Business.Roles.Teacher.GetHomeRoomClassID(Convert.ToInt64(Session[GlobalVar.LOGGED_IN_ID]));
var classAttendanceStatus = Success.Business.Entities.ClassAttendance.GetClassAttendanceStatus(classId);
ViewBag.status = classAttendanceStatus;
var attendanceData = TeacherAttendance.CreateClassAttendance(classId);
return View(attendanceData);
}
[HttpPost]
public ActionResult Index(IEnumerable<TeacherAttendanceModel> teacherAttendanceModel)
{
try
{
if (ModelState.IsValid)
{
TeacherAttendance.SaveAttendance(teacherAttendanceModel);
}
}
catch (Exception e)
{
}
return View(teacherAttendanceModel);
}
}
Get Index is working fine. But I am not getting the TeacheAttendanceModel object in Post index. I get null object. I would be thank full to get any help in this regards. How to update the multiple records of attendance on submit click?
I am using the following View:
#foreach (var item in Model) {
<tr >
<td style="border-style:solid; border-color:darkslategray; border-width:thin;">
#Html.DisplayFor(modelItem => item.Student)
</td>
<td style="border-style:solid; border-color:darkslategray; border-width:thin;">
#Html.CheckBoxFor(modelItem => item.Absent, ViewBag.status == 2 ? new {disabled = "disabled"} : null)
#Html.TextBoxFor(modelItem => item.AbsentComment, ViewBag.status == 2 ? new {disabled = "disabled"} : null)
</td>
<td style="border-style:solid; border-color:darkslategray; border-width:thin;">
#Html.CheckBoxFor(modelItem => item.Uniform, ViewBag.status == 2 ? new {disabled = "disabled"} : null)
#Html.DropDownListFor(modelItem => item.UniformCommentSelected, new SelectList(item.UniformComment),item.UniformCommentSelected ?? "---Select---", ViewBag.status == 2? new {disabled = "disabled"} : null)
</td>
<td style="border-style:solid; border-color:darkslategray; border-width:thin;">
#Html.CheckBoxFor(modelItem => item.Homework, ViewBag.status == 2 ? new {disabled = "disabled"} : null)
#Html.TextBoxFor(modelItem => item.HomeworkComment, ViewBag.status == 2? new {disabled = "disabled"} : null)
</td>
</tr>
}
Model:
public class Test
{
public List<string> UniformComment { get; set; }
}
Controller:
public ActionResult Index()
{
var model = new Test
{
UniformComment = new List<string>{ "one", "two", "three" }
};
return View(model);
}
[HttpPost]
public ActionResult Index(Test model)
{
return View(model);
}
View:
#using (Html.BeginForm())
{
for (var i = 0; i < Model.UniformComment.Count; i++)
{
#Html.TextBoxFor(x => Model.UniformComment[i])
}
<input type="submit" value="Save" />
}
Rendered html example:
<input id="UniformComment_0_" name="UniformComment[0]" type="text" value="one" />
<input id="UniformComment_1_" name="UniformComment[1]" type="text" value="two" />
<input id="UniformComment_2_" name="UniformComment[2]" type="text" value="three" />
The idea is iterate with for loop or create EditorTemplate and then you receive indexed items.
Added (Feel the difference):
View:
#using (Html.BeginForm())
{
foreach (var comment in Model.UniformComment)
{
#Html.TextBoxFor(x => comment)
}
<input type="submit" value="Save" />
}
Rendered html:
<input id="comment" name="comment" type="text" value="one" />
<input id="comment" name="comment" type="text" value="two" />
<input id="comment" name="comment" type="text" value="three" />
Use a IList instead of IEnumerable in the view and replace the foreach loop with a for loop.
Step 1:
Use
#model IList<TeacherAttendanceModel>
instead of
#model IEnumerable<TeacherAttendanceModel>
Step 2:
Use
#for (var i = 0; i < Model.Count; i++)
instead of
#foreach (var item in Model)
Refer How to pass IEnumerable list to controller in MVC including checkbox state? for more details.