Perhaps I am misunderstanding how a ViewModel works. A ViewModel is used to display custom data to the user without having to use the full Model. So you would use only the database fields that you want displayed. I have a ViewModel that looks like this
using PagedList;
using Resolutions.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Web;
namespace Resolutions.ViewModels
{
public class SearchPagingViewModels
{
public int ObjectID { get; set; } //Database Primary Key
[DisplayName("Resolution Year")]
public string ResolutionYear { get; set; } //Year of the Resolution
[DisplayName("Resolution Number")]
public string ResolutionNumber { get; set; } //Number of the Resolution
[DisplayName("Resolution Text")]
public string ResolutionText { get; set; } //OCR'd text for the Resolution
[DisplayName("Resolution Date")]
public Nullable<System.DateTime> ResolutionDate { get; set; } //Date of the Resolution
public int? PageNumber { get; set; }
public bool? IsResYearChecked { get; set; }
public bool? IsResNumChecked { get; set; }
public bool? IsKeywordChecked { get; set; }
public string SearchKeyword { get; set; }
}
}
I want to store the value of a checkbox from the client side into my object and use the boolean to be able to filter and page through the results. However, if I use my current ViewModel I get 25 checkboxes when I try to access the object's boolean; As I can only seem to access the value of the checkbox within a foreach loop that I am using to display each item. I am currently pulling information from a database and then storing the database results into a list of the ViewModel.
This is my controller:
using PagedList;
using Resolutions.Models;
using Resolutions.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace Resolutions.Controllers
{
public class SearchPagingController : Controller
{
private DocumentManagementEntities db = new DocumentManagementEntities();
// GET: SearchPaging
public ViewResult Index(int? page, bool? resnum)
{
var temp = resnum;
int pageSize = 25;
int pageNumber = (page ?? 1);
List<SearchPagingViewModels> searchList = new List<SearchPagingViewModels>();
var allResolutions = from c in db.AllResolutions select c;
allResolutions = allResolutions.OrderBy(c => c.ResolutionYear).ThenBy(c => c.ResolutionNumber);
foreach (var item in allResolutions)
{
SearchPagingViewModels searchItem = new SearchPagingViewModels();
searchItem.ObjectID = item.ObjectID;
searchItem.ResolutionYear = item.ResolutionYear;
searchItem.ResolutionNumber = item.ResolutionNumber;
searchItem.ResolutionText = item.ResolutionText;
searchItem.ResolutionDate = item.ResDate;
searchItem.IsResNumChecked = resnum;
searchList.Add(searchItem);
}
return View(searchList.ToPagedList(pageNumber, pageSize));
}
}
}
As you can see I create a List<SearchPagingViewModels> and then add each SearchPagingViewModels into the List<SearchPagingViewModels>. In my Index.cshtml, I use a foreach loop to traverse the list and display each item and create a PagedList. Should I be changing my ViewModel to store a List<AllResolutions> like so:
using PagedList;
using Resolutions.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Web;
namespace Resolutions.ViewModels
{
public class SearchPagingViewModels
{
public List<AllResolution> AllResolutions { get; set; }
public int? PageNumber { get; set; }
public bool? IsResYearChecked { get; set; }
public bool? IsResNumChecked { get; set; }
public bool? IsKeywordChecked { get; set; }
public string SearchKeyword { get; set; }
}
}
or do I want to use the current values within the ViewModel? If instead I used a List<AllResolutions>, how do you access the values within the list in the cshtml file?
Related
Here is my model and View info to capture a single value in a Razor page into a variable.
I get this error when trying to use this IEnumerable, but before with without IEnumerable this works without any errors.
Here is my program that works fine without IEnumerable, but how do you access all the tables that have relations together this way?:
GlobalCommandCenter
View showing Model connection using IEnumerable:
#model IEnumerable<OperationsCommandCenter.Models.CommandCenterModel>
Error in View that I am getting with IEnumberable in Razor Page:
Model:
using ClassLibraryDAL.DAL;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace OperationsCommandCenter.Models
{
public class CommandCenterModel
{
public List<DimLocation> LocationDatas { get; set; }
public List<DimLocation> DimLocations { get; set; }
public List<DimProductInventory> DimProducts { get; set; }
public List<SelectListItem> Country { get; set; }
public List<SelectListItem> Continent { get; set; }
public List<SelectListItem> Product { get; set; }
public List<SelectListItem> FactInventory { get; set; }
public List<SelectListItem> query { get; set; }
public string SectionCity { get; set; }
}
}
I start studying asp.net MVC and I am confused about sending data to VIEW. I have one class Dispatch:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace Logistic.Models
{
public class Dispatch
{
public int DispatchId { get; set; }
public int TrackingId { get; set; }
public int CustomerId { get; set; }
public int RecipientId { get; set; }
public int CityId { get; set; }
public DateTime Delivered { get; set; }
public string Notes { get; set; }
}
}
Another class City:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace Logistic.Models
{
public class City
{
public int CityId { get; set; }
public string Name { get; set; }
}
}
A class Client:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace Logistic.Models
{
public class Client
{
public int ClientId { get; set; }
public string Name { get; set; }
}
}
From my class Dispatch, CustomerId and RecipientId will be related to the class Client; CityId related to City.
I create my context class:
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration.Conventions;
using System.Linq;
using System.Web;
namespace Logistic.Models
{
public class LogisticContext : DbContext
{
public DbSet<Dispatch> Dispatches { get; set; }
public DbSet<Client> Clients { get; set; }
public DbSet<Driver> Drivers { get; set; }
public DbSet<City> Cities { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
}
}
And here is my Controller:
using Logistic.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace Logistic.Controllers
{
public class HomeController : Controller
{
private LogisticContext db = new LogisticContext();
public ActionResult Dispatch()
{
var dispatches = db.Dispatches.ToList();
return View(dispatches);
}
}
}
The problem is that in my View class I do not know how to display the Customer Name, Recipient Name, and City Name. I only can display the CustomerId, RecipientId, and CityId.
View:
#model IEnumerable<Logistic.Models.Dispatch>
#{
ViewBag.Title = "Dispatch";
}
<h2>Dispatch</h2>
#foreach(var item in Model)
{
<h2></h2>
}
Thanks
If you have relationships in place...
If you already have defined relationships between these properties, you can generally use the Include() method to pull related entities in as seen below :
// Pull all of the dispatches and their related cities
var dispatchesWithCities = db.Dispatches.Include("Cities")
.ToList();
If you do this and have the proper relationships, you would then be able to iterate through and access the item.City.Name, however it doesn't look like that is the case in your current scenario.
Without relationships...
If you don't have these "hard" relationships in place, you can still perform a few database queries to pull the properties you need and construct a ViewModel, but it wouldn't be pretty with so many results :
public class DispatchViewModel
{
public Dispatch Dispatch { get; set; }
public City City { get; set; }
public Client Client { get; set; }
public Driver Driver { get; set; }
}
And then use each of your individual Dispatch objects and map them to their related properties :
// Build your Dispatches with related information
var dispatchModels = db.Dispatches.AsEnumerable()
.Select(d => new DispatchViewModel()
{
Dispatch = d,
City = db.Cities.FirstOrDefault(c => c.CityId == d.CityId),
Client = db.Clients.FirstOrDefault(c => c.ClientId == d.CustomerId),
...
});
At this point you can simply iterate through the collection and output them by referencing the iterator in the loop :
#foreach(var item in Model)
{
<h2>#item.Dispatch.DispatchId</h2>
<ul>
<li>
<b>City</b>: #item.City.Name
<!-- Other stuff here -->
</li>
</ul>
}
You can use view model approach to send data from mutliple views to controller. Here is an example:
http://rachelappel.com/use-viewmodels-to-manage-data-amp-organize-code-in-asp-net-mvc-applications/
I want to show a calculated field in a view, so I tried to create a viewmodel like this:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
namespace Facturacion.Models
{
public class Test
{
public int testId { get; set; }
[Required]
public decimal price { get; set; }
}
public class TestViewModel
{
[Key]
public int testId { get; set; }
public Test test { get; set; }
public decimal price { get; set; }
public decimal calculated { get; set; }
public TestViewModel(Test test)
{
Test = test;
calculated = Test.price * 2;
}
}
}
It gave me an error so I changed the constructor:
public TestViewModel(Test test)
{
var foo = test;
calculated = foo.price * 2;
}
But now when I build the project, it creates a table called "TestViewModels", so I can not reach the data in the Tests table.
I think a viewmodel shouldn't have an id, but if it does not the scaffolder won't generate the controllers.
What is the correct way to use a viewmodel to show a calculated field in a view?
I could solve it without using the viewmodel
namespace Facturacion.Models
{
public class Test
{
public int testId { get; set; }
[Required]
public decimal price { get; set; }
public decimal calculated
{
get
{
return (decimal)(price*2);
}
}
}
}
Notice the calculated field does not have a set method.
Following is a code written by me for searching a specific item by name in the Advertisement table.
public ActionResult SearchResult(string name)
{
var advertisement = db.Advertisements.ToArray(); // retrieve data from database
foreach (var ad in advertisement)
{
if (ad.Title.Equals(name))
{
return View(ad);
}
}
return View(advertisement);
}
Even though I search an item which is already in the database, in all cases the if condition is not being true.Each time I get the whole list of items as the result in the view page. what is the issue here?
My model for Advertisement looks like this.
using System;
using System.Drawing; // Image type is in this namespace
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
namespace Bartering.Models
{
public class Advertisement
{
[Key]
public int ID { get; set; }
[Required]
[StringLength(100)]
public string Title { get; set; }
public Guid OwnerID { get; set; }
[Required]
public string Category { get; set; }
public byte[] Image { get; set; }
[Required]
[StringLength(200)]
public string Description { get; set; }
}
}
I think you should be doing something like this
public ActionResult SearchResult(string name)
{
var ad=db.Advertisements.Where(s=>s.Title.ToUpper()==name.ToUpper())
.FirstOrDefault();
if(ad!=null)
return View(ad);
//Nothing found for search for the name, Let's return the "NotFound" view
return View("NotFound");
}
This code will get the first item(if exists) which matches with our check (Title==name) and return it. if there is nothing found which matches the condition, It will return a View called "Notfound"
In my controller i am creating a subcategory object and giving that object a reference to the category it belongs to. Everything works fine when i debug the site but when i load the list of objects from my entityframework db all the category object references are removed. the rest persists. anybody got an idea why this happens ?
Controller:
[Authorize(Roles = "administrator")]
[HttpPost]
public ActionResult Create(CategoryViewModel viewmodel, HttpPostedFileBase Icon)
{
SubCategory subcategory = new SubCategory();
Category category = categorycontroller.getCategoryByName(viewmodel.SelectedValue);
viewmodel.subcategory.Category = category;
subcategory = viewmodel.subcategory;
category.Subcategories.Add(subcategory);
if (Icon != null && Icon.ContentLength > 0)
{
var fileName = Path.GetFileName(Icon.FileName);
var path = Path.Combine(Server.MapPath("../../Content/icons/"), fileName);
Icon.SaveAs(path);
subcategory.Icon = fileName;
}
if (ModelState.IsValid)
{
subcategorydb.categories.Attach(category);
subcategorydb.subcategories.Add(subcategory);
subcategorydb.SaveChanges();
return RedirectToAction("Index");
}
return View(subcategory);
}
and this is my viewmodel:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity;
using System.Web.Mvc;
using SkyLearn.Areas.Categories.Controllers;
namespace SkyLearn.Areas.Categories.Models
{
public class CategoryViewModel
{
public List<SelectListItem> PossibleValues { get; set; }
public string SelectedValue { get; set; }
public SubCategory subcategory { get; set; }
public CategoryController categorycontroller;
public CategoryViewModel()
{
PossibleValues = new List<SelectListItem>();
}
}
}
And here is my Category and SubCategory class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity;
namespace SkyLearn.Areas.Categories.Models
{
public class Category
{
public int ID { get; set; }
public string Title { get; set; }
public string Icon { get; set; }
public string Description { get; set; }
public List<SubCategory> Subcategories;
public Category()
{
Subcategories = new List<SubCategory>();
}
}
public class CategoryDBContext : DbContext
{
public DbSet<Category> categories { get; set; }
public DbSet<SubCategory> subcategories { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity;
using SkyLearn.Areas.Categories.Controllers;
namespace SkyLearn.Areas.Categories.Models
{
public class SubCategory
{
public int ID { get; set; }
public string Title { get; set; }
public string Icon { get; set; }
public string Description { get; set; }
public int CategoryID { get; set; }
public Category Category { get; set; }
}
public class SubCategoryDBContext : DbContext
{
public DbSet<SubCategory> subcategories { get; set; }
public DbSet<Category> categories { get; set; }
}
}
i have searched many sites for info on this problem but couldnt find much of help. Anybody here able to identify my problem?
as seen on this screenshot the object is correctly referenced by all means. but when i load the data next time the object reference has disapeared. all other attributes are still there and saved as they should:
thanks AronChan
//// Update ////
I am now getting the following error:
A foreign key value cannot be inserted because a corresponding primary
key value does not exist. [ Foreign key constraint name =
SubCategory_Category ]
Your category object won't get saved because it is not attached to the DbContext that you add the subcategory to. The subcategory might know about the reference but the category won't. If there is a lookup table (which there must be if its many to many) I don't see how that record would be saved. Try attaching the category, adding the subcategory and then saving. Personally I have always set up the many-to-many look up tables as their own entity. It is a little easier to visualize what is actually happening as opposed to giving all control to EF.
Also, if you are using code first, make sure your EntityConfigurations are correct. Try running the EdmxWriter over your context to make sure the data model looks exactly how you want it to.