Creating a product gallery with EF 6 and MVC 5 - asp.net-mvc-5

I'm working on a website for someone and am having a small issue. I'll admit I'm a little new to MVC and EF so I've got this issue. My Index view shows my products, but it shows them in a straight up and down list, like the table I created it supposed to do.
What I'm trying to do is create a gallery, where they're side by side for say 4 in a row, then move on to the next row and so forth (God I know this is making sense). Here's my view
#model IEnumerable<AccessorizeForLess.ViewModels.DisplayProductsViewModel>
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Index</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table class="table">
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Name)<br />
<img src="#item.Image.ImagePath"/>
</td>
<td>
#Html.DisplayFor(modelItem => item.Price)
</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>
And of course it's doing what it's supposed to do. Can someone help me out with this?

In case anyone has anything close to this issue this is what I came up with and it works just the way I was looking for:
#model IEnumerable<AccessorizeForLess.ViewModels.DisplayProductsViewModel>
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Products</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
#foreach (var item in Model)
{
<div style="float:left; width:25%">
#Html.DisplayFor(modelItem => item.Name)<br />
<input id="Hidden1" type="hidden" value="#item.Id" />
<div>$#Html.DisplayFor(modelItem => item.Price)</div>
<div><img src="#item.Image.ImagePath" /></div>
<div> </div>
<div>Quantity: <input type="text" id="quantity" style="width:50px;" /></div>
<div>#Html.ActionLink("Details", "Details", new { id = item.Id })</div>
</div>
}
I do, however have one question, in my controller how can I format the price as currency, I tried this:
IEnumerable<DisplayProductsViewModel> model = products.Select(p => new DisplayProductsViewModel()
{
Id = p.ProductId,
Name = p.ProductName,
Image = p.ProductImage,
Price = string.Format("{0:C}",p.ProductPrice)
}).ToList();
And get the error:
LINQ to Entities does not recognize the method 'System.String
Format(System.String, System.Object)' method, and this method cannot
be translated into a store expression

Related

Loading a Partial view which has a complex model of many sub models into a jquery ui tab

I get an error when loading a particular view via an Html.action call to an action and Controller, into a jquery Tab.
The other View is loaded successfully via an HTML.Partial call.
How do I get this other particular partial loaded please.
The tab where the error happens is tab4.
The commented out HTML.Partial call works to a point but when it loads that Partial (User), which has multiple models in it's containing model,..those other models are null and it's iteration over them crashes.
(That partial is beneath the first block of code.)
If I try load it from an action Call, then
the JQuery function ("$#tabs").tabs crashes with ".tabs" is undefined
TIA
Code:
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>jQuery UI Tabs - Content via Ajax</title>
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<link rel="stylesheet" href="/resources/demos/style.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<script>
$(function ()
{
$("#tabs").tabs({
beforeLoad: function (event, ui)
{
ui.jqXHR.fail(function ()
{
ui.panel.html(
"Couldn't load this tab. We'll try to fix this as soon as possible. " +
"If this wouldn't be a demo.");
});
}
});
});
</script>
<div id="tabs">
<ul>
<li>Person Detail</li>
<li>Addresses</li>
<li>Role Detail</li>
<li>User Detail</li>
</ul>
<div id="tabs-1">
#*#Html.Partial("~/Views/Person/Index.cshtml")*#
</div>
<div id="tabs-2">
#*#Html.Partial("~/Views/Address/Index.cshtml")*#
</div>
<div id="tabs-3">
#Html.Partial("~/Views/IdentityRole/List.cshtml", new List<Catalyst.Shared.IdentityRole>())
</div>
<div id="tabs-4">
#Html.Action("List", "User");
#*#Html.Partial("~/Views/User/List.cshtml", new Catalyst.Mvc.IdentityUserPersonViewModel())*#
</div>
</div>
The Partial which I want to load, but needs data, which I think would work if I called the Action as opposed to calling the Partial.
#model Catalyst.Mvc.IdentityUserPersonViewModel
#{
ViewBag.User = "List";
}
<div class="panel panel-default" style="width:1400px !important;text-align:center ">
<div class="panel-heading">
<h3>Users</h3>
</div>
<div class="panel-body">
<div style="text-align:right;">#Html.ActionLink("Add", "Create", null, new { #class = "btn btn-default" })</div>
<table class="table table-bordered table-hover">
<thead>
<tr>
<th>
UserName
</th>
<th>
Password
</th>
<th>
Title
#*#Html.DisplayNameFor(model => model.)*#
</th>
<th>
FirstName
#*#Html.DisplayNameFor(model => model.)*#
</th>
<th>
LastName
</th>
<th>
PhoneNumber
</th>
<th>
Email
</th>
<th>
Company and Branch
</th>
<th></th>
<th></th>
</tr>
</thead>
#for (var i = 0; i < Model.identityUsers.Count(); i++)
{
<tr>
<td>
<a href="#Url.Action("Edit", "User" , new {id=Model.UserPersons[i].UserPersonId})">
#Html.DisplayFor(x => Model.identityUsers[i].UserName)
</a>
</td>
<td>
<a href="#Url.Action("Edit", "User" , new {id=Model.UserPersons[i].UserPersonId})">
#Html.EditorFor(x => Model.identityUsers[i].PasswordHash, new { htmlAttributes = new { #class = "form-control", placeholder = "Password", Type = "password" } })
</a>
</td>
<td>
<a href="#Url.Action("Edit", "User" , new {id=Model.UserPersons[i].UserPersonId})">
#Html.DisplayFor(x => Model.UserPersons[i].Title)
</a>
</td>
<td>
<a href="#Url.Action("Edit", "User" , new {id=Model.UserPersons[i].UserPersonId})">
#Html.DisplayFor(x => Model.UserPersons[i].Name)
</a>
</td>
<td>
<a href="#Url.Action("Edit", "User" , new {id=Model.UserPersons[i].UserPersonId})">
#Html.DisplayFor(x => Model.UserPersons[i].Surname)
</a>
<td>
#*<a href="#Url.Action("Edit", "User" , new {id=Model.identityUsers[i].Id})">
#Html.DisplayFor(x => Model.identityUsers[i].Email)
</a>*#
</td>
<td>
#*<a href="#Url.Action("Edit", "User" , new {id=Model.identityUsers[i].Id})">
#Html.DisplayFor(x => Model.identityUsers[i].PhoneNumber)
</a>*#
</td>
<td>
#*<a href="#Url.Action("Edit", "User" , new {id=item.ID})">
#Html.DisplayFor(x => item.PhoneNumber)
</a>*#
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id =
Model.identityUsers[i].Id })
</td>
<td>
#Html.ActionLink("Delete", "Delete", new { id =
Model.identityUsers[i].Id })
</td>
</tr>
}
</table>
</div>
The Controller of the view I can't get laoded
public class UserController : Controller
{
private IdentityUserBo identityUserBo;
private PersonBo personBo;
private IdentityUserPersonBo identityuser_personBo;
IdentityUserPersonViewModel model = new IdentityUserPersonViewModel();
public UserController(IdentityUserBo boIdentityUser, PersonBo boPerson, IdentityUserPersonBo boIdentityUserPerson )
{
this.identityUserBo = boIdentityUser ?? throw new ArgumentNullException("boIdentityUser");
this.personBo = boPerson ?? throw new ArgumentNullException("boPerson");
this.identityuser_personBo = boIdentityUserPerson ?? throw new ArgumentNullException("boIdentityUserPerson");
}
public ActionResult Index()
{
return RedirectToAction("List");
}
public ActionResult List()
{
ExBool result = null;
IdentityUserPersonViewModel userPersonViewModel = new IdentityUserPersonViewModel();
result = this.identityUserBo.List(out List<IdentityUser> identityUsers);
if (!result.Success) throw new Exception(result.Messages);
if (identityUsers == null) throw new Exception("Could not load IdentityUsers");
// Ideally see detail eg branch and tel and email from their respective tables
userPersonViewModel.identityUsers = identityUsers;
//Get the Persons, match these via Person.Id -> IdentityUserPerson.FKPersonId + IdentityUserPerson.FKUserId -> IdentityUser.ID
List<Person> persons = null;
result = this.personBo.List(out persons);
//IdentityUserPersonViewModel viewModel = new IdentityUserPersonViewModel();
userPersonViewModel.persons = persons;
// Get the IdentityUserPersons
List<IdentityUserPerson> identityUserPersons = null;
result = this.identityuser_personBo.List(out identityUserPersons);
IdentityUserPerson UPRec = new IdentityUserPerson();
Person PRec = new Person();
userPersonViewModel.UserPersons = new List<UserPerson>();
foreach (IdentityUser rec in userPersonViewModel.identityUsers)
{
UPRec = identityUserPersons.Find(x => x.FKUserID == rec.Id);
if (UPRec != null)
{
//UserId, UserPersonId, + Person.Id + Person.Name + Person.Surname
PRec = persons.Find(y => y.ID == UPRec.FKPersonID);
UserPerson UsrPers = new UserPerson();
UsrPers.UserId = rec.Id;
UsrPers.UserPerson_FKPersonId = UPRec.FKPersonID;
UsrPers.UserPerson_FKUserId = UPRec.FKUserID;
UsrPers.Name = PRec.FirstName;
UsrPers.Surname = PRec.LastName;
UsrPers.Title = PRec.TitleCode;
userPersonViewModel.UserPersons.Add(UsrPers);
}
else
{
UserPerson UsrPers = new UserPerson();
userPersonViewModel.UserPersons.Add(UsrPers);
}
}
return View(userPersonViewModel);
}
Check your console what error you got.
and also change this in tab4
#{
#Html.Partial("List", new Catalyst.Mvc.IdentityUserPersonViewModel())
}

MVC Approve or Unapprove button Clarification

I'm new to mvc and am trying to figure out how to create an approve button on an index view. Some clarification is needed.
There is a question here already about creating an Approve/Unapprove button in an mvc view. But after reviewing it, it appears to be missing information. The controller is expecting the SubmitButton and the ID to be passed to it. This I understand. But the view's submit buttons only sends the SubmitButton with no ID. Can someone please clear the fog? Thank you.
Controller
[ActionName("Index")]
[HttpPost]
public ActionResult IndexPost(string SubmitButton, int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
string buttonClicked = SubmitButton;
if(buttonClicked == "Approve")
{
CurrentApplication currentApplication = db.CurrentApplications.Find(id);
currentApplication.AppStatus = "APPROVED";
db.SaveChanges();
}
else if(buttonClicked == "Unapprove")
{
CurrentApplication currentApplication = db.CurrentApplications.Find(id);
currentApplication.AppStatus = "UNAPPROVED";
db.SaveChanges();
}
//Save Record and Redirect
return RedirectToAction("Index");
}
View
<button type="submit" name="SubmitButton" value="Approve" class="btn btn-sm btn-success">Approve</button>
<button type="submit" name="SubmitButton" value="Unapprove" class="btn btn-sm btn-danger">Unapprove</button>
The controller will them update the database with the status change and return the Index to reflect the changes.
According to your newest example, here is the best answer I can think. At first, your code example has a few syntax errors and I needed to create own macaddress -class. I hope its similar than yours.
I used the same example than in my earlier answer. I only modified view and created maccaddress -class. The controller is same as earlier.
Modified View
This is the important part. I think you just have formatted Html form and tables in weird way. Here is a screenshot of how the view is rendered.
Now when user click Approve or Unapprove the form will send maccaddress id and button value to the controller IndexPost -action.
In a view example:
table is made just for example, modify it if needed.
I changed foreach location, now it is before Html.BeginForm. In your example, BeginForm was outside foreach and that caused a few problems when submitting your code. In a way how your form was rendered, it was impossible to know which Id is submitted.
Look #Html.Hidden("id", item.idMACAddress). It should be inside BeginForm.
I have only print id and status into a table for example purposes.
Action buttons are in the third column.
So why it works now is the way Form is rendered. In the example, there is now one html form for every maccaddress row. When a button is clicked, we know exactly what values we want to send into the controller.
#model IEnumerable<MySQL_MACAddress.Models.macaddress>
#{ ViewBag.Title = "Index"; }
<table class="table">
<tr>
<th> MAC Address </th>
<th> Status </th>
<th> Actions </th>
</tr>
#foreach (var item in Model)
{
using (Html.BeginForm())
{
#Html.AntiForgeryToken()
#Html.Hidden("id", item.idMACAddress)
<tr>
<td> #item.idMACAddress </td>
<td> #item.Status </td>
<td>
<button type="submit" name="SubmitButton" value="Approve" class="btn btn-sm btn-success">Approve</button>
<button type="submit" name="SubmitButton" value="Unapprove" class="btn btn-sm btn-danger">Unapprove</button>
</td>
</tr>
}
}
</table>
maccaddress.cs example
Check this example. Don't just copy it because probably it won't work with your code. The view is a more important part here so look it.
using System;
namespace MySQL_MACAddress.Models
{
public class macaddress
{
public macaddress()
{
}
public string Status { get; set; }
public int idMACAddress { get; set; }
}
}
Controller
Check earlier answer.
I suppose you have an HTML form in View made with Html-helpers. In your case, the following example code is probably the simplest one.
View - Home/Index.cshtml
<h2>Welcome to ASP.NET MVC!</h2>
<!--
If needed, check BeginForm parameters to send POST
into right controller and action.
-->
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<!-- second parameter is the value for id field. -->
#Html.Hidden("id", 2001)
<button type="submit" name="SubmitButton" value="Approve" class="btn btn-sm btn-success">Approve</button>
<button type="submit" name="SubmitButton" value="Unapprove" class="btn btn-sm btn-danger">Unapprove</button>
}
Controller - HomeController.cs
using System.Net;
using System.Web.Mvc;
namespace FormTest.Controllers
{
public class HomeController : Controller
{
// GET action for index
public ActionResult Index()
{
// Do something here ...
return View();
}
// POST action for index.
// Will use same path as GET
[HttpPost]
[ActionName("Index")]
public ActionResult IndexPost(string SubmitButton, int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
if (SubmitButton == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
//Redirect to GET Index
return RedirectToAction("Index");
}
}
}
The important part is the Hidden helper that will generate a hidden input field. If you need more modifications in your use case, read more here about parameters and examples.
#T.Nylund , Your thoughts? Thank you.
View
#model Enumerable<MySQL_MACAddress.Models.macaddress>
#{ ViewBag.Title = "Index"; }
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.Status)
</th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#HtmlHidden("id", item.idMACAddress)
</td>
<td>
#Html.DisplayFor(modelitem => item.Status)
</td>
<button type="submit" name="SubmitButton" value="Approve" class="btn btn-sm btn-success">Approve</button>
<button type="submit" name="SubmitButton" value="Unapprove" class="btn btn-sm btn-danger">Unapprove</button>
}
We use different controller methods for the different actions when approving (button to approve, button to reject)
Our view:
if (!Model.IsApproved)
{
<td>
#using (Html.BeginForm("Approve", "BudgetItem", new { id = Model.BudgetItemSid, role = Model.ActiveRole }, FormMethod.Post))
{<button type="submit" id="btnApprove" style="display: none;">Approve</button>}
</td>
}
if (!Model.IsRejected)
{
<td>
#using (Html.BeginForm("Reject", "BudgetItem", new { id = Model.BudgetItemSid, role = Model.ActiveRole }, FormMethod.Post))
{<button type="submit" id="btnReject" style="display: none;">Reject</button>}
</td>
}
Our Controller:
[HttpPost]
public ActionResult Approve(int id, EnumRole role)
{
}
[HttpPost]
public ActionResult Reject(int id, EnumRole role)
{
}

mvc 5 Pass textbox value as a parameter

This is my view:
<table class="table">
<tr>
<td>
#Html.TextBox("SearchParameter", null, new { #style = "width:200px; height:30px" })
</td>
<td>
#using (Html.BeginForm("GetSearchParameter", "Parameter", new { sSearchParameterValue = ??? }, FormMethod.Post))
{
<input type="submit" value="GO!" />
}
</td>
</tr>
</table>
In my Controller "Parameter" I have a method "GetSearchParameter" that has one parameter which is "sSearchParameterValue". What I would like to do is pass the value of my textbox to that parameter.
I already tried two different ways:
1) I get sSearchParameterValue = null:
#using (Html.BeginForm("GetSearchParameter", "Parameter", new { sSearchParameterValue = Request.Form["SearchParameter"] }, FormMethod.Post))
2) I get A potentially dangerous Request.QueryString value was detected from the client:
#using (Html.BeginForm("GetSearchParameter", "Parameter", new { sSearchParameterValue = #Html.TextBox("SearchParameter") }, FormMethod.Post))
Can someone tell me how to do this?
Thank you,
Grega

Pass Id to ActionMethod

I have a Delete button inside my table and I m trying to delete the selected Row.
The problem is that I always get in the post method a null ID
<div>
<table class="table">
<thead>
<tr>
<th>Role Name</th>
<th>Action</th>
</tr>
</thead>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#using (Html.BeginForm("Delete","Role", new { id = item.Id },FormMethod.Post))
{
<div class="form-actions no-color">
<input type="submit" value="Delete" class="btn btn-default" /> |
</div>
}
</td>
</tr>
}
</table>
In My Controller
// POST: Jobs/Delete/5
[HttpPost, ActionName("Delete")]
public ActionResult Delete(int id)
{
IdentityRole role = _context.Roles.Find(id);
_context.Roles.Remove(role);
_context.SaveChanges();
return RedirectToAction("Index");
}
Any time I click on the button the id is null
From your comments, the html generated in <form> tags is
action="/Role/Delete/b1bc13ca-a855-48b0-90e2-9e5fc081ac86"
meaning that the Id property of your model is typeof Guid. Change the POST method signature to
public ActionResult Delete(Guid id)

ASP.Net MVC: How to generate html table using editorfor and editor template

still now i generate html table like below code example but interested to know how could i generate html table using editorfor using editor template
see my full razor and view model code and guide me how to achieve my goal.
#model MVCCRUDPageList.Models.StudentListViewModel
#{
ViewBag.Title = "Index";
}
<h2>CREATE TABULAR UI WITH HTML TABLE</h2>
#using (Html.BeginForm("Index", "HtmlTable", FormMethod.Post))
{
<div class="form-group">
<div class="col-md-12 table-responsive">
<table class="table table-bordered table-hover">
<tr>
<th>
Row No
</th>
<th>
ID
</th>
<th>
Name
</th>
<th>
Country
</th>
<th>
Hobbies
</th>
<th>
Sex
</th>
</tr>
}
#for (int x=0; x<=Model.Students.Count-1;x++)
{
<tr>
<td>
<label>#(x+1)</label>
</td>
<td>
#Html.TextBoxFor(m => m.Students[x].ID)
</td>
<td>
#Html.TextBoxFor(m => m.Students[x].Name)
</td>
<td>
#Html.DropDownListFor(m => m.Students[x].CountryID,
new SelectList(Model.Country, "ID", "Name", Model.Students[x].CountryID),
"-- Select Countries--", new { id = "cboCountry", #class = "edit-mode" })
</td>
<td>
#for (var i = 0; i < Model.Students.FirstOrDefault().Hobbies.Count; i++)
{
<div class="checkbox">
#Html.HiddenFor(m => m.Students[x].Hobbies[i].ID)
#Html.HiddenFor(m => m.Students[x].Hobbies[i].Name)
#Html.CheckBoxFor(m => m.Students[x].Hobbies[i].Checked)
#Html.LabelFor(m => m.Students[x].Hobbies[i].Name, Model.Students[x].Hobbies[i].Name)
</div>
}
</td>
<td>
#for (var i = 0; i < Model.Sex.Count; i++)
{
<div class="checkbox">
#Html.HiddenFor(m => Model.Sex[i].ID)
#Html.HiddenFor(m => Model.Sex[i].SexName)
#Html.RadioButtonFor(m => m.Students[x].SexID, Model.Sex[i].ID)
#Html.LabelFor(m => m.Students[x].SexID, Model.Sex[i].SexName)
</div>
}
</td>
</tr>
}
</table>
</div>
<input type="submit" value="Submit" />
</div>
}
View Model Code
public class StudentListViewModel
{
public IList<Student> Students { get; set; }
public List<Country> Country { get; set; }
public List<Sex> Sex { get; set; }
public StudentListViewModel()
{
Students = new List<Student>
{
new Student
{
ID=1,Name="Keith",CountryID=0,SexID="F",
Hobbies= new List<Hobby>
{
new Hobby{ID=1,Name="Football",Checked=false},
new Hobby{ID=2,Name="Hocky",Checked=false},
new Hobby{ID=3,Name="Cricket",Checked=false}
}
},
new Student
{
ID=2,Name="Paul",CountryID=2,
Hobbies= new List<Hobby>
{
new Hobby{ID=1,Name="Football",Checked=false},
new Hobby{ID=2,Name="Hocky",Checked=false},
new Hobby{ID=3,Name="Cricket",Checked=false}
}
},
new Student
{
ID=3,Name="Sam",CountryID=3,
Hobbies= new List<Hobby>
{
new Hobby{ID=1,Name="Football",Checked=false},
new Hobby{ID=2,Name="Hocky",Checked=false},
new Hobby{ID=3,Name="Cricket",Checked=false}
}
}
};
Country = new List<Country>
{
new Country{ID=1,Name="India"},
new Country{ID=2,Name="UK"},
new Country{ID=3,Name="USA"}
};
Sex = new List<Sex>
{
new Sex{ID="M",SexName="Male"},
new Sex{ID="F",SexName="Female"}
};
}
}
please guide me how to restructure my razor code to use editorfor and editor template for clean code. what will be name of editor template ?
thanks
To use an EditorTemplate using #Html.EditorFor(m => m.SomeProperty) (where SomeProperty is a complex object, or collection of complex objects), then the template must be located in the /Views/Shared/EditorTemplates or /Views/YourControllerName/EditorTempates folder, and be named the same as the class name for SomeProperty.
In your case, if you want an EditorTemplate for typeof Student, then the template (a partial view) will be named Student.cshtml.
#model yourAssembly.Student
<tr>
<td>#Html.TextBoxFor(m => m.ID)</td>
<td>#Html.TextBoxFor(m => m.Name)<td>
....
<tr>
and in the main view, your would use
<table>
<thead> .... </thead>
<tbody>
#Html.EditorFor(m => m.Students)
</tbody>
</table>
which will generate the correct html for each item in your collection.
However, since you also have a dropdownlist for CountryID, then you need to pass the SelectList to the template (the template has no knowledge of the parent model) using additionalViewData, so the code needs to be modified to
#Html.EditorFor(m => m.Students, new { Countries = Model.Countries})
where the Countries property in StudentListViewModel should be
public IEnumerable<SelectListItem> Countries { get; set; }
and delete you current List<Country> Country property. Then in the view generate the dropdownlist using
<td>#Html.DropDownListFor(m => m.CountryID, (IEnumerable<SelectListItem>)ViewData["Countries "], "-- Select Country--", new { ... })<td>
Note you should not be adding new { id = "cboCountry" } because its creating invalid html (duplicate id attribute).
Now you can extend this further by creating an EditorTemplate for Hobby (which will be named Hobby.cshtml
#model yourAssembly.Hobby
<div class="checkbox">
#Html.HiddenFor(m => m.ID)
#Html.HiddenFor(m => m.Name)
#Html.CheckBoxFor(m => m.Checked)
#Html.LabelFor(m => m.Checked, Model.Name)
</div>
Note the LabelFor() should be for the Checked property, not the Name property as you currently have it.
Then in your Student.cshtml template, use
<td>#Html.EditorFor(m => m.Hobbies)<td>
to generate the correct html for each Hobby.

Resources