MVC ActionResult isn't grabbing Where expression correctly - asp.net-mvc

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...

Related

How to implement image dynamically in multiple views?

I am looking for a way to display the Image dynamically based on Placement_Position and Region into different View.
Placement view, where I display all the content from table.
There is no link between these Views.
I am confused, how to implement this scenario. Anyone please help me here.
In Employee view, I want to display the image Atop_1if the region is 1 and Atop_2 if the region is 2
public class ClsPlacement
{
public int Id { get; set; }
public string Placement_Position { get; set; }
public string Path { get; set; }
public int Region { get; set; }
}
Controller
public ActionResult Placement()
{
var model = context.Placement.ToList();
return View(model);
}
Placement View
<table>
<tr>
<th>
#Html.DisplayNameFor(m => m.Id)
</th>
<th>
#Html.DisplayNameFor(m => m.Placement_Position)
</th>
<th>
#Html.DisplayNameFor(m => m.Region)
</th>
<th>
#Html.DisplayNameFor(m => m.Path)
</th>
</tr>
#foreach (var item in Model)
{
<tr>
#Html.DisplayFor(modelItem => item.Id)
<td>
#Html.DisplayFor(modelItem => item.Placement_Position)
</td>
<td>
#Html.DisplayFor(modelItem => item.Region)
</td>
<td>
#Html.Image(item.Path, "Image")
</td>
</tr>
}
</table>
you can use LINQ to write query for each controller and return IList :
so in Employee view :
public ActionResult Employee()
{
IList<ClsPlacement> plcList = new List<ClsPlacement>();
var query= from m in context.Placement
select m;
var plc= query.ToList();
foreach(var plcData in plc)
{
if(plcData.Placement_Position=="A_Top")
{
plcList.Add(new ClsPlacement()
{
Id= plcData.Id,
Placement_Position= plcData.Placement_Position,
Path = plcData.Path ,
Region= plcData.Region
});
}
}
return View(plcList);
}
then in your view you can write this:
#foreach (var item in Model)
{
<div class="col-md-5">
<img src="#Url.Content(String.Format("~/Content/Place/{0}{1}{2}", "Atop_",item.Region,".jpg"))" />
</div>
}
and same this for Customer view.

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);
}

MVC Object(x) does not contain a definition for blah

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>

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();
}

Use properties of different models in view (.net MVC)

I am learning MVC and display a list of products in a view.
#model IEnumerable<Domain.Model.Product>
<table>
<tr>
<th style="width:50px; text-align:left">Id</th>
<th style="text-align:left">Name</th>
<th style="text-align:left">Category</th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.Id)
</td>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.Category.Name)
</td>
</tr>
}
</table>
The products belong to categories, which are displayed in the right column. I now want to filter the products by categories, for which I would like to use a dropdownlist control. I found #Html.DropDownListFor(), but as far as I understand, this will only give me properties of the currently underlying model (Product).
My controller:
public class ProductController : Controller
{
ProductRepository pr = new ProductRepository();
public ActionResult Default()
{
List<Product> products = pr.GetAll();
return View("List", products);
}
}
You could do something like this. Just create a class with the info that you need.
public class ProductsModel
{
public ProductsModel() {
products = new List<Product>();
categories = new List<SelectListItem>();
}
public List<Product> products { get;set; }
public List<SelectListItem> categories { get;set; }
public int CategoryID { get;set; }
}
Then your controller:
public class ProductController : Controller
{
ProductRepository pr = new ProductRepository();
public ActionResult Default()
{
ProductsModel model = new ProductsModel();
model.products = pr.getAll();
List<Category> categories = pr.getCategories();
model.categories = (from c in categories select new SelectListItem {
Text = c.Name,
Value = c.CategoryID
}).ToList();
return View("List", model);
}
}
Finally, your view
#model IEnumerable<Domain.Model.ProductsModel>
#Html.DropDownListFor(m => model.CategoryID, model.categories)
<table>
<tr>
<th style="width:50px; text-align:left">Id</th>
<th style="text-align:left">Name</th>
<th style="text-align:left">Category</th>
</tr>
#foreach (var item in Model.products) {
<tr>
<td>
#item.Id
</td>
<td>
#item.Name
</td>
<td>
#item.Category.Name
</td>
</tr>
}
</table>

Resources