MVC Object(x) does not contain a definition for blah - asp.net-mvc

Getting an error on the view, at the displaynamefor softwareid line, saying the model SoftwareDTO does not contain a definition for softwareid. I can see it right there in the model.
Model:
public class SoftwareDTO
{
public int SoftwareId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
Controller:
public ActionResult Index()
{
List<SoftwareDTO> softwareList = new List<SoftwareDTO>();
var data = _db.Software.ToList();
foreach (var sw in data)
{
SoftwareDTO software = new SoftwareDTO()
{
SoftwareId = sw.SoftwareId,
Name = sw.Name,
Description = sw.Description
};
softwareList.Add(software);
};
return View(softwareList);
}
View:
#model List<Request.Models.SoftwareDTO>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.SoftwareId)
</th>
<th>
#Html.DisplayNameFor(model => model.Name)
</th>
<th>
#Html.DisplayNameFor(model => model.Description)
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.SoftwareId)
</td>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.Description)
</td>

its because model its a list not an object SoftwareDTO in your razor view
I think you are missing the foreach

SoftwareId is a property of SoftwareDTO class. Your view is strongly typed to a collection of SoftwareDTO objects. So you need to loop through the model(The collection of SoftwareDTO) and access the SoftwareId of each item.
#model List<Request.Models.SoftwareDTO>
<table class="table">
#foreach(var item in Model)
{
<tr>
<td>
#Html.DisplayNameFor(x=> item.SoftwareId)
</td>
</tr>
}
</table>
EDIT : As per the edit in the question, and the comments provided.
Looks like you want to print the display name of the propertes in your table headers. If you do not wish to change the data you are passing from your action method, you can try this
#if (Model.Any())
{
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(x => Model[0].SoftwareId)
</th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(x => item.SoftwareId)
</td>
</tr>
}
</table>
}
This is using the first item in the collection and it's properties to use with DisplayNameFor method. Since i have a if condition to check for at least one item before rendering the table, It will not even render the table if your Model has 0 items.
If you want to show the empty table with headers, you have 2 options.
Write HTML markup for the table header
<table class="table">
<tr>
<th>
<label>Software Id</label>
</th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(x => item.SoftwareId)
</td>
</tr>
}
</table>
Or if you still want to use the DisplayNameFor helper method to render the table header labels,
Create a new viewmodel
public class TableListVm
{
public List<SoftwareDTO> Items {set;get;}
public SoftwareDto ItemMeta {set;get;}
public TableListVm()
{
ItemMeta= new SoftwareDto();
}
}
And in your GET action, Send this object to your view
public ActionResult Index()
{
var data = _db.Software.ToList().Select(sw=> new SoftwareDTO {
SoftwareId = sw.SoftwareId,
Name = sw.Name,
Description = sw.Description
}).ToList();
var vm= new TableListVm { Items = data };
return View(vm);
}
And in your view which is strongly typed to this new view model.
#model TableListVm
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(x => Model.ItemMeta.SoftwareId)
</th>
</tr>
#foreach (var item in Model.Items)
{
<tr>
<td>
#Html.DisplayFor(x => item.SoftwareId)
</td>
</tr>
}
</table>

Related

How to call multiple partials in parent view in MVC4?

I am trying to call multiple partials in parent view. I have tried multiple way but could not succeed. I think there is something missing in View. Please guide me where i am going wrong.
Note: I have partials in the question. Please suggest me.
The following error:
System.InvalidOperationException: 'The model item passed into the
dictionary is of type 'Aplication.Models.ABC.ClsA', but this
dictionary requires a model item of type
'System.Collections.Generic.IEnumerable`1[Aplication.Models.ABC.first]'.'
Model
public class ClsA
{
public List<first> firsts{ get; set; }
public List<second> seconds{ get; set; }
}
public class first
{
public string Name { get; set; }
public string Address { get; set; }
}
public class second
{
public string Details{ get; set; }
public string Age{ get; set; }
}
Controller
public ActionResult ABC()
{
SDetails sDetails=new SDetails();
var model = new ClsA();
model.firsts = sDetails.Rst();
model.seconds = sDetails.Rs();
return View(model);
}
View
#model Aplication.Models.ABC.ClsA
#Html.Partial("_PartialA");
#Html.Partial("_PartialB.cshtml")
_PartialA
#model IEnumerable<Aplication.Models.ABC.first>
<table>
<tr>
<th>#Html.DisplayNameFor(m => m.Name)</th>
<th>#Html.DisplayNameFor(m => m.Address)</th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.Address)
</td>
</tr>
}
</table>
_PartialB
#model IEnumerable<Aplication.Models.ABC.second>
<table>
<tr>
<th>#Html.DisplayNameFor(m => m.Details)</th>
<th>#Html.DisplayNameFor(m => m.Age)</th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Details)
</td>
<td>
#Html.DisplayFor(modelItem => item.Age)
</td>
</tr>
}
</table>
#Html.Partial() Takes a second parameter model. If you do not pass the parameter to #Html.Partial() it will automatically pass the model of the current view.
Parameters
htmlHelper
Type: System.Web.Mvc.HtmlHelper
The HTML helper instance that this method extends.
partialViewName
Type: System.String
The name of the partial view to render.
model
Type: System.Object
The model for the partial view.
You need to update your code from
#Html.Partial("_PartialA");
#Html.Partial("_PartialB");
To
#Html.Partial("_PartialA", Model.firsts);
#Html.Partial("_PartialB", Model.seconds)
You do not need to pass the file extension to the #Html.Partial method
This is an example of loading partial view. The controller has an action to load the data in a partial view.
public ActionResult List()
{
var movies = db.Movies;
return PartialView("_list", movies.ToList());
}
In the partial _list view, you can have something like -
#model IEnumerable<WebApplication1.Models.Movie>
<div class="row">
<table class="table table-bordered table-hover" id="moviesTable">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.ID)
</th>
<th>
#Html.DisplayNameFor(model => model.Title)
</th>
<th>
#Html.DisplayNameFor(model => model.ReleaseDate)
</th>
<th>
#Html.DisplayNameFor(model => model.Genre)
</th>
<th>
#Html.DisplayNameFor(model => model.Price)
</th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.ID)
</td>
<td>
#Html.DisplayFor(modelItem => item.Title)
</td>
<td>
#Html.DisplayFor(modelItem => item.ReleaseDate)
</td>
<td>
#Html.DisplayFor(modelItem => item.Genre)
</td>
<td>
#Html.DisplayFor(modelItem => item.Price)
</td>
<td>
<div class="btn-group btn-group-xs">
<i class="fa fa-trash-o"></i>
<i class="glyphicon glyphicon-pencil"></i> Edit
<i class="glyphicon glyphicon-eye-open"></i> View
<i class="glyphicon glyphicon-trash"></i> Delete
</div>
</td>
</tr>
}
</tbody>
</table>
</div>
Now you can render the partial view in the main view like below -
<div class="row">
<div class="col-md-12" id="replacetarget">
#{ Html.RenderAction("List", "Movies"); }
</div>
</div>

MVC ActionResult isn't grabbing Where expression correctly

I'm working on an animal shelter application. I have an AnimalInitializer.cs in my DAL and I have it broken down into dogs and cats by species. In my controller, I want to see the list of dogs for one ActionResult and a list of cats for another ActionResult. They are all returning as dogs when I run the ShowDogs view and nothing is returned on the ShowCats view.
Pet model:
public enum SpeciesType { Dog, Cat }
public class Pet
{
public SpeciesType SpeciesType { get; set; }
}
AnimalInitializer seed:
var dogs = new List<Dog>
{
new Dog { SpeciesType = SpeciesType.Dog, Breed = "German Shepherd" }
}
var Cats = new List<Cat>
{
new Cat { SpeciesType = SpeciesType.Cat, Breed = "Domestic Long Haired" },
}
PetController:
public ActionResult ShowDogs()
{
var dogs = db.Pets.Where(d => d.SpeciesType == SpeciesType.Dog);
return View(dogs.ToList());
}
public ActionResult ShowCats()
{
var cats = db.Pets.Where(c => c.SpeciesType == SpeciesType.Cat);
return View(cats.ToList());
}
ShowDogs View:
#model IEnumerable<AnimalShelter1.Models.Pet>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.Breed)
</th>
<th>
#Html.DisplayNameFor(model => model.SpeciesType)
</th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.Breed)
</td>
<td>
#Html.DisplayFor(modelItem => item.SpeciesType)
</td>
</tr>
}
</table>
ShowCats View:
#model IEnumerable<AnimalShelter1.Models.Pet>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.SpeciesType)
</th>
<th>
#Html.DisplayNameFor(model => model.Breed)
</th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.SpeciesType)
</td>
<td>
#Html.DisplayFor(modelItem => item.Breed)
</td>
</tr>
}
</table>
I am not sure whether the below solution works. But please try this:
public ActionResult ShowDogs()
{
var dogs = db.Pets.Where(d => d.SpeciesType == SpeciesType.Dog).ToList();
return View(dogs);
}
public ActionResult ShowCats()
{
var cats = db.Pets.Where(c => c.SpeciesType == SpeciesType.Cat).ToList();
return View(cats);
}
I just ended up editing the ones that were supposed to be cats and saving them and that seemed to have worked. Every time I launch the application, the animals are in their correct places, and the breakpoints for ShowDogs and ShowCats are both getting hit and populated with the correct animals. Weird, I don't know what went wrong with it...

how to get selected checkbox in asp.net using entity framework

i'm new to asp.net mvc.I have a list of checkboxes and i want when the checkboxes are selected a new list of selected checkboxs are shown.
my code Product.cs code:
public class Product
{
public int ProductID { get; set; }
public string ProductName { get; set; }
public int Price { get; set; }
public bool Checked { get; set; }
public virtual ICollection<Purchase> Purchases { get; set; }
}
My view:
<h2>Product Lists</h2>
#using (Html.BeginForm())
{
<table class="table">
<tr>
<th>
Product ID
</th>
<th>
Product Name
</th>
<th>
Price
</th>
<th></th>
</tr>
#for (var i = 0; i < Model.Count(); i++)
{
<tr>
<td>
#Html.DisplayFor(x => x[i].ProductID)
</td>
<td>
#Html.DisplayFor(x => x[i].ProductName)
</td>
<td>
#Html.DisplayFor(x => x[i].Price)
</td>
<td>
#Html.CheckBoxFor(x => x[i].Checked, new { Style = "vertical-align:3px}" })
</td>
</tr>
}
</table>
<input type="submit" value="Purchase" class="btn btn-default" />
}
This is my Controller code.I want when the check boxes are selected in a new page the selected check boxes are shown.
my ActionResult:
public ActionResult Index()
{
return View(db.Products.ToList());
}
[HttpPost]
public ActionResult Index(List<Product> list)
{
return View(list);
}
#using (Html.BeginForm())
{
<table class="table">
<tr>
<th>
Product ID
</th>
<th>
Product Name
</th>
<th>
Price
</th>
<th></th>
</tr>
#for (var i = 0; i < Model.Count(); i++)
{
<tr>
<td>
#Html.DisplayFor(x => x[i].ProductID)
</td>
<td>
#Html.DisplayFor(x => x[i].ProductName)
</td>
<td>
#Html.DisplayFor(x => x[i].Price)
</td>
<td>
#Html.CheckBoxFor(x => x[i].Checked, new { Style = "vertical-align:3px}" })
</td>
</tr>
}
</table>
If you already have a List with all checked/unchecked properties and just want to show the checked records in a new view, you can store your list in a TempData and redirect to an action which will use your list:
public ActionResult Index()
{
return View(db.Products.ToList());
}
[HttpPost]
public ActionResult Index(List<Product> list)
{
TempData["CheckedRecords"] = list.Where(x=>x.Checked).ToList(); //Don't forget to add 'using System.Linq;'!
return RedirectToAction("MyOtherView");
}
public ActionResult MyOtherView()
{
var checkedRecords = (List<Product>)TempData["CheckedRecords"];
return View(checkedRecords);
}

How to display a collection in View of ASP.NET MVC Razor project?

How to display a collection in View of ASP.NET MVC Razor project?
My Model and View is below. For one person i've to display Many tests on the screen. Thanks in Advance
namespace UI.Models
{
public class SuperStudent
{
public string FullName { get; set; }
public ICollection<TestDetail> CandidateTestDetails { get; set; }
}
public class TestDetail
{
public DateTime TestDate { get; set; }
public string RegNum { get; set; }
}
}
View
#model IEnumerable<UI.Models.SuperStudent>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.FullName)
</th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
Print all test details
</td>
</tr>
}
</table>
For one person your view must be like :
#model UI.Models.SuperStudent
<h2>#Model.FullName</h2>
<table class="table">
<tr>
<th>
TestDate
</th>
<th>
RegNum
</th>
</tr>
#foreach (var item in Model.CandidateTestDetails ) {
<tr>
<td>
#item.TestDate
</td>
<td>
#item.RegNum
</td>
</tr>
}
</table>
The code works the same inside a loop as it does outside the loop. Just reference the loop item. For example:
#foreach (var student in Model) {
#foreach (var test in student.CandidateTestDetails) {
<tr>
<td>#test.RegNum</td>
</tr>
}
}
That would output just the RegNum value. You can also make use of things like DisplayNameFor by referencing an element in the collection:
#foreach (var student in Model) {
#foreach (var test in student.CandidateTestDetails) {
<tr>
<td>
#Html.DisplayNameFor(model => student.CandidateTestDetails.First().RegNum)<br />
#test.RegNum
</td>
</tr>
}
}
While intuitively it may seem that this could fail if Model is empty (since First() would throw an exception), it doesn't actually execute First() on the collection. The engine simply uses that to reflect into the model returned by First() to determine the display name.
Given this, you can construct the markup however you wish for those items. If it's complex enough, you might even create a partial view for just an item in that collection and render that partial view in the loop by passing the item value to the partial view.

Passing entire Model from a View back to the Controller

I got a list of:
public class Items
{
public String Nro_Item { get; set; }
public Sucursal Sucursal { get; set; }
public Areas Area { get; set; }
public Sectores Sector { get; set; }
public bool ID_Estado { get; set; }
}
I'm passing it to this view:
#using ClientDependency.Core.Mvc
#model IEnumerable<TrackingOperaciones.Controllers.Items>
#{
ViewBag.Title = "Ver Items";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<br/>
#using (Html.BeginForm("CargarRecibidos", "Recepcion", FormMethod.Post))
{
<table class="table table-striped table-bordered table-condensed">
<tr>
<th>
Numero
</th>
<th>
Sucursal
</th>
<th>
Area
</th>
<th>
Sector
</th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Nro_Item)
</td>
<td>
#Html.DisplayFor(modelItem => item.Sucursal.descripcion)
</td>
<td>
#Html.DisplayFor(modelItem => item.Area.descripcion)
</td>
<td>
#Html.DisplayFor(modelItem => item.Sector.Descripcion)
</td>
<td>
#Html.CheckBoxFor(modelItem => item.ID_Estado)
</td>
</tr>
}
</table>
<p>
<input class="btn" name="Guardar" type="submit" value="Guardar"/> |
#Html.ActionLink("Volver al listado de RecepciĆ³n", "Index")
</p>
}
Until there everything is fine: Now the problem is getting back the entire model with the checked values in a controller for processing it like this one:
[HttpPost]
public ActionResult CargarRecibidos(IEnumerable<Items> items)
{
if (ModelState.IsValid)
{
//do something here
}
return RedirectToAction("Index");
}
}
But i'm falling miserably because "items" came back empty in the postback
i'm guess something is wrong with the form
#using (Html.BeginForm("CargarRecibidos", "Recepcion"))
{
<input class="btn" name="Guardar" type="submit" value="Guardar"/>
}
please help me!
Use IEnumerable
Then the controller input parameter will be List
Perhaps also consider using AJAX POST with JSON objects in place of a form submit (more modern/elegant) but submits are fine too.
Part of the problem is it won't post the entire model since only the checkbox is a form value. I think you need to add an additional hidden value in your form to track the item number and then handle the checkbox values specially in the controller. The item number is appended to "checkbox" in the posted values to keep them distinct.
<tr>
<td>
#Html.DisplayFor(modelItem => item.Nro_Item)
#Html.Hidden("Nro_Item", item.Nro_Item)
</td>
<td>
#Html.DisplayFor(modelItem => item.Sucursal.descripcion)
</td>
<td>
#Html.DisplayFor(modelItem => item.Area.descripcion)
</td>
<td>
#Html.DisplayFor(modelItem => item.Sector.Descripcion)
</td>
<td>
#Html.CheckBox("checkbox" + item.Nro_Item, item.ID_Estado)
</td>
</tr>
In the controller only bind to the number item so it can be used to process the checkboxes:
[HttpPost]
public ActionResult CargarRecibidos(List<string> nro_item)
{
foreach (string item in nro_item)
{
var checkbox=Request.Form["checkbox" + item];
if (checkbox != "false") // if not false then true,false is returned
{
// Do the action for true...
}
else
{
// Do the action for false
}
}
return View();
}

Resources