asp.net mvc 5 one model with different format in view - pagedlist

I'm a newbie in MVC. Sorry all professionals for this question.
I have a model like:
public class Student
{
public int ID { get; set; }
public int Number{ get; set; }
public string Name{ get; set; }
public string Surname{ get; set; }
public bool IsStudentNow { get; set; }
}
In my "paged" index.cshtml page, i call this model like this;
#model PagedList.IPagedList<WebProj.Models.Student>
It's ok for the paging or foreach statement but I can't access the model property in HTML helper.
For example;
I can't access this property;
#Html.DisplayNameFor(model=> model.Number)
#Html.DisplayNameFor(model=> model.Name)
But I can access this;
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.Number)
</td>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
So, I want to access model properties in HTML helper. Don't prefer to use view model.

Related

How do I load data that has a Many to Many relationship in ASP.NET Core?

I'm working on a many to many relationship in my ASP.NET Core application. From reading sources online I understand that this isn't officially supported yet and so an intermediary class is needed to make it all work.
The problem that I have is that once I have created my 'many to many' relationship, I don't know how best to display the data in my view and I'm struggling to traverse everything with this particular setup.
In my example there are two tables Part and Supplier, one Part can have many Supplier just as one Supplier can have many Part.
The first thing I did was create my two entity classes Part and Supplier
Part.cs
public class Part
{
public int PartId { get; set; }
public string PartName { get; set; }
public string PartNumber { get; set; }
public string ShortDescription { get; set; }
public string LongDescription { get; set; }
public string Category { get; set; }
//Intermediate entity
public IList<PartSupplier> PartSupplier { get; set; }
}
Supplier.cs
public class Supplier
{
public int SupplierId { get; set; }
public string SupplierName { get; set; }
public string Website { get; set; }
public int? Telephone { get; set; }
public string Email { get; set; }
//Intermediate entity
public IList<PartSupplier> PartSupplier { get; set; }
}
You'll see from the above code that I've placed an intermediate table that creates this many to many relationship called PartSupplier
PartSupplier.cs
public class PartSupplier
{
public int PartId { get; set; }
public Part Part { get; set; }
public int SupplierId { get; set; }
public Supplier Supplier { get; set; }
}
At this point, I move to my data context and override the model building portion of the code to utilise the Fluent API.
Context.cs
protected override void OnModelCreating(ModelBuilder builder)
{
builder.Entity<PartSupplier>().HasKey(ps => new { ps.PartId, ps.SupplierId });
base.OnModelCreating(builder);
}
public DbSet<Part> Parts { get; set; }
public DbSet<Supplier> Suppliers { get; set; }
public DbSet<PartSupplier> PartSuppliers { get; set; }
Ok, so far so good. Now I need to display this information in a view, in this view specifically, I'd like to show all the parts and next to them all the available suppliers that part can be bought from.
I load the data in the following manner although, this is where I'm a little unsure how I should be structuring the query. Should I call the intermediary table or call Part and then include Supplier? I'm not sure
PartController.cs
public IActionResult Index()
{
var data = _context.Part.Include(p => p.Supplier);
return View(data);
}
Index.cshtml
#model IEnumerable<Part>
<div class="container">
<div class="row">
<div class="col">
<h2>Parts</h2>
<a asp-action="Create" asp-controller="Parts">Add Part</a>
<table class="table">
#foreach (var part in Model)
{
<tr>
<td>
<a asp-action="Edit" asp-route-id="#part.PartId" asp-controller="Part">#part.PartName</a>
</td>
<td>
#part.PartNumber
</td>
<td>
#part.ShortDescription
</td>
<td>
...I'd like to show the suppliers here...
</td>
</tr>
}
</table>
</div>
</div>
</div>
I think I've almost got it but really would like some assistance getting over this final hurdle. Many thanks
A cascade relationship is missing in Index.cshtml, you need to add ThenInclude.
public IActionResult Index()
{
var data = _context.Parts.Include(x => x.PartSupplier)
.ThenInclude(y=>y.Supplier);
return View(data);
}
Then in Index.cshtml.
<table class="table">
#foreach (var part in Model)
{
<tr>
<td>
<a asp-action="Edit" asp-route-id="#part.PartId" asp-controller="Part">#part.PartName</a>
</td>
<td>
#part.PartNumber
</td>
<td>
#part.ShortDescription
</td>
<td>
<ul>
#* Here has been changed. *#
#foreach(var supplier in part.PartSupplier)
{
<li>#supplier.Supplier.SupplierName #supplier.Supplier.Website</li>
}
</ul>
</td>
</tr>
}
</table>
In database, I insert some data, such as Part and PartSupplier.
Result.

Eager Loading EF

I'm an absolute beginner on EF, and I am stuck at what probably is very simple.
I have 2 tables/classes:
Toys and Brands
public class Toys
{
public int Id { get; set; }
public string Name { get; set; }
public int BrandId { get; set; }
}
public class Brands
{
public int BrandId { get; set; }
public string BrandName { get; set; }
}
My DBContext file:
public class SOT : DbContext
{ public SOT(): base("name=SOT")
{
public virtual DbSet<Brands> brands; set; }
public virtual DbSet<Toys> toys { get; set; }
}
When I add a record, the BrandId goes to the BrandId field in the Toys table.
I want to display in the view the Name of the toy, and the Brand Name. Now I get toy name and Brand Id
In my controller, on the Index Action:
public ViewResult Index()
{
/// this is where I am sooo stuck.....
var toy = _context.Toys.Include(c => c.Brands).ToList();
return View(toy);
}
The view:
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.BrandName)
</td>
What am I doing wrong?
maybe this will helps you, If you make a relation between Toy and Brand Table
var q = _context.Toys
.Select(q_toys =>
new
{
q_toys.Name,
q_toys.Brand.BrandName
}).ToList();

Dealing With Multiple Instances Of Partial Views And Model Binding In ASP.NET MVC 4 Entity Framework

This is my controller code.
namespace MultipleInstance.Controllers
{
public class Default1Controller : Controller
{
private MVCDemoEntities db = new MVCDemoEntities();
public ActionResult Index()
{
Order ord = new Order();
//ord.BillingAddress = new Address1();
//ord.ShippingAddress = new Address();
return View(ord);
}
public ActionResult ProcessForm(Order ord)
{
return PartialView("Index");
}
}
}
This is my Index View.
#using(Html.BeginForm("ProcessForm","Default1",FormMethod.Post))
{
<h3>Basic Details</h3>
#Html.Partial("_BasicDetails")
<h3>Shipping Address</h3>
#Html.Partial("_Address",
new ViewDataDictionary()
{
TemplateInfo = new TemplateInfo()
{ HtmlFieldPrefix = "ShippingAddress" } })
<input type="submit" value="Submit" />
}
this is my two partial views _BasicDetails.cshtml and _Address.cshtml
#model MultipleInstance.Order
<table>
<tr>
<td>#Html.LabelFor(m => m.OrderID_)</td>
<td>#Html.TextBoxFor(m => m.OrderID_)</td>
</tr>
<tr>
<td>#Html.LabelFor(m => m.CustomerID_)</td>
<td>#Html.TextBoxFor(m => m.CustomerID_)</td>
</tr>
</table>
This is _Address.cshtml view.
#model MultipleInstance.Address
<table>
<tr>
<td>#Html.LabelFor(m => m.Street1)</td>
<td>#Html.TextBoxFor(m => m.Street1)</td>
</tr>
<tr>
<td>#Html.LabelFor(m => m.Street2)</td>
<td>#Html.TextBoxFor(m => m.Street2)</td>
</tr>
<tr>
<td>#Html.LabelFor(m => m.Country)</td>
<td>#Html.TextBoxFor(m => m.Country)</td>
</tr>
<tr>
<td>#Html.LabelFor(m => m.PostalCode)</td>
<td>#Html.TextBoxFor(m => m.PostalCode)</td>
</tr>
</table>
When i run the above code following error comes. The partial view '_BasicDetails' was not found or no view engine supports the searched locations. Can anyone help me where i am going wrong? Or do i need to change anything in my action method?
This is my model class
public partial class Order
{
public int Id { get; set; }
public string OrderID_ { get; set; }
public string CustomerID_ { get; set; }
public string SelectType { get; set; }
public Address ShippingAddress { get; set; }
}
public partial class Address
{
public int Id { get; set; }
public string Street1 { get; set; }
public string Street2 { get; set; }
public string Country { get; set; }
public string PostalCode { get; set; }
}
Thanks in advance.
this should work
#Html.Partial("~Views/shared/_BasicDetails.cshtml", Model)
and you need to pass it the model [and it should be initialized in your action] because as I see in you code you are consuming it in your partial view

InvalidCastException in Entity Framework 7

I'm using Visual Studio 2015, .Net framework 4.6.00079 to build a simple ASP.NET MVC 6 app:
model:
namespace RimconPensionModel.DataAccessLayer
{
[Table("BaseMortality")]
public class BaseMortality
{
[Key]
public int Id { get; set; }
public string BaseMortalitySet { get; set; }
public int Age { get; set; }
public string Gender { get; set; }
public float MortalityFactor { get; set; }
public DateTime EffectiveDate { get; set; }
public DateTime UpdateDate { get; set; }
public string UpdateUser { get; set; }
}
}
controller:
namespace RimconPensionModel.Controllers
{
public class BaseMortalityController : Controller
{
[FromServices]
public RimconPensionModelContext RimconPensionModelContext { get; set; }
[FromServices]
public ILogger<BaseMortalityController> Logger { get; set; }
public IActionResult Index()
{
return View(RimconPensionModelContext.BaseMortality.ToList());
}
}
}
view:
#model IEnumerable<RimconPensionModel.DataAccessLayer.BaseMortality>
#{
ViewBag.Title = "Base Mortality Data";
}
<h2>Base Mortality Data</h2>
<!--
<p>
<a asp-controller="BaseMortalityData" asp-action="Create">Create New</a>
</p> -->
<table class="table">
<tr>
<th>Base Mortality Sets</th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.BaseMortalitySet)
</td>
</tr>
}
</table>
The app builds and starts, but when I invoke the controller, I get InvalidCastException on the "return View( . . . )" line of the controller. I've been googling for days (I'm a bit new to MVC and Entity Framework) with no luck. I think it probably has something to do with the datetime attributes. I bulk loaded the database table from a csv file with the datetime fields in YYYYMMDD format and the load went OK; the db table shows 1994-12-31 12:00:00 AM in the datetime fields. They are type datetime2(7), NOT NULL in the db.

pass two model with related date to view MVC4

How to pass two model with related date to view MVC4.
I have class of requirements and supplier have to check within he have the specific requirement or not .
So I need to show in my view the list of requirement in one column and supplier check/answer in other column. So I guess I need to pass the 2 models which they related to each other . How to do that? And then store the supplier answers to specific requirement in the DB.
Here my models
namespace OTMS.Models
{
public class Requiernments
{
[Key]
public int RequiernmentId { get; set; }
public int ID { get; set; }//link to project Name
public string RequiernmentName { get; set; }
public string RequiernmentType { get; set; }
}
namespace OTMS.Models
{
public class Supplier
{
[Key]
public int SupplierId { get; set; }
public int RequiernmentId { get; set; }
public string SupplierName { get; set;
public string Answer{ get; set; }
}
}
Update:
My viewmodel :
namespace OTMS.ViewModel
{
public class SupplierAnswerViewModel
{
public Supplier Sup{ get; set; }
public Requiernments Req { get; set; }
}
}
My controller :
public ProjectContext b = new ProjectContext();
public ActionResult ListRequiermentBySupplier(int ID) //Id of the project
{
var Project = b.RequiernmentEntries.Where(s => s.ID == ID).ToList();//geting all requierment under project
List<SupplierAnswerViewModel> listvm = new List<SupplierAnswerViewModel>();
SupplierAnswerViewModel vm = new SupplierAnswerViewModel();
vm.requirements = new Requiernments();
vm.requirements.RequiernmentId = ID;
vm.supplier = new Supplier();
vm.supplier.SupplierId = 2; //am testing supplier of this id=2 for now
listvm.Add(vm);
return View(listvm); ;
}
My view:
#model IEnumerable<OTMS.ViewModel.SupplierAnswerViewModel>
<table>
<tr>
<th>
RequiernmentName
</th>
<th>
RequiernmentType
</th>
<th>
UserId
</th>
<th>
SupplierName
</th>
<th>
Supplier Answer
</th>
<th></th>
</tr>
#if (Model != null)
{
foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.requirements.RequiernmentName)
</td>
<td>
#Html.DisplayFor(modelItem => item.requirements.RequiernmentType)
</td>
<td>
#Html.DisplayFor(modelItem => item.supplier.UserId)
</td>
<td>
#Html.DisplayFor(modelItem => item.supplier.SupplierName)
</td>
<td>
#Html.DisplayFor(modelItem => item.supplier.Answer)
</td>
<td>
<td>
#Html.ActionLink("Edit", "Edit", new { /* id=item.PrimaryKey */ }) |
</td>
</tr>
}
}
</table>
create a view model
public class ViewModel{
public Requirements requirements { get; set; }
public Supplier supplier { get; set; }
}
then on your controller
List<ViewModel> listvm = new List<ViewModel>();
ViewModel vm = new ViewModel();
vm.requirements.RequiernmentId
vm.supplier.SupplierID = ...
listvm.Add(vm);
Edit
to send one of the items as a list see my changes above. Then pass your view model to the view
return View(listvm);
and on your view
#model List<OTMS.ViewModel.SupplierAnswerViewModel>