ASP.NET MVC passing query result from controller to view - asp.net

How to print the result of query in View page for ASP.NET MVC?
My code is:
public ActionResult Index()
{
var list = from m in db.MenuTables
select m.MenuName;
return View(list);
}
Now what should i write to print the result of this query in View Page?

Personally, I would get in the habit of having ViewModels and then strongly typing your View, to that model.
The model will expose ONLY THE DATA you want to display. Nothing more, nothing less. So let's assume you want to display the Name, Price and some other meta data.
Pseudo-code:
//View Model
public class MenuItem
{
public string Name { get; set; }
public decimal Price { get; set; }
public bool IsVegetarian { get; set; ]
}
public class IndexViewModel
{
public IList<MenuItem> MenuItems { get; set; }
public string MaybeSomeMessage { get; set; }
}
//in Controller
public ActionResult Index()
{
// This gets the menu items from your db, or cache or whatever.
var menuItemsFromDb = GetMenuItems();
// Let's start populating the view model.
IndexViewModel model = new IndexViewModel();
// Project the results to your model.
IList<MenuItems> menuItems = null;
if (menuItemsFromDb != null)
{
model.MenuItems = (from menuItem in menuItemsFromDb
select new MenuItem() {
Name = menuItem.Name,
Price = menuItem.Price,
IsVegetarian = menuItem.IsVegetarian
}).ToList();
}
// Anything else...
model.MaybeSomeMessage = "Hi There!";
return View(model);
}
//in View
#model IndexViewModel
<h3>#Model.MaybeSomeMessage</h3>
<ul>
#foreach(var item in Model.MenuItems)
{
<li>#item.Name - $ #item.Price</li>
}
</ul>
etc..
Note I've skipped some error checking, etc.
The point: only pass what you need.
At first, you may think this is much more code than is necessary. The best answer I can suggest to that thought, is that in the long run, you'll thank yourself for getting in the habit of this because the view should only ever know about the exact data it requires.
Nothing more, nothing less. Sending the least amount of data means you have a very light and simple view which will make your support/debugging much better. Next, you'll be able to unit test your controllers with a lot more intelligence and smarts, when you get to that.

Assuming that list is an IEnumerable of strings (i.e. that MenuName is a string).
In your view, accept the model IEnumerable<string>
#model IEnumerable<string>
and then enumerate it
#foreach( string s in Model )
{
<div>
#s
</div>
}

The first thing you want to do is call ToList() or else you could possibly be executing the same SQL query multiple times.
public ActionResult Index()
{
var list = (from m in db.MenuTables
select m.MenuName).ToList();
return View(list);
}
Secondly, I wouldn't just pass up a full list like that. You should create a ViewModel. That will allow you to pass up more data later on with a smaller effort.
public ActionResult Index()
{
var model = new IndexModel();
model.Tables = db.MenuTables.ToList();
model.AnotherValue = "MENUS";
return View(model);
}
Now we are on the view, you will need to set the model and iterate the table.
#model IndexModel
<h3>#Model.AnotherValue</h3>
<ul>
#foreach( var table in Model.Tables) {
<li>#table.Name<li>
}
</ul>

public ActionResult Index()
{
var list = from m in db.MenuTables
select m.MenuName;
return View(list);
}
//In View
#model IEnumerable<ProjectName.models.MenuTables>
#foreach(var item in Model)
{
#item.Field_Name
}

Related

Count how many elements of an item and return to a view

I have a Database where I have a table cars that has some cars, and each devices has a type. I want to make a view to see how many cars of each type I have in the table. What I have till now is, in controller.
Controller:
public ActionResult CountCars()
{
var count = db.Cars.Where(s => s.Cars.Name.Contains("Ford")).Count();
var view = new CountCarsViewModel()
{
Count = count
};
return PartialView("_MainSideBarPartialLayout", view);
}
ViewModel class:
public class CountCarsViewModel
{
public int Count { get; set; }
}
View:
#model Project.ViewModels.Home.CountCarsViewModel
<span class="badge">#Model.Count</span>
But it wont count any cars.. Just getting 0.
Anyone can help, with a solution?
Your current query is returning 0 probably because there is no matching Car with Name Ford you will have to debug that and see what's happening. To answer how many cars of each type I have in the table you need GroupBy:-
var view= db.Cars.GroupBy(s => s.Cars.Name)
.Select(x => new CountCarsViewModel
{
CarName = x.Key,
Count = x.Count()
});
return PartialView("_MainSideBarPartialLayout", view);
Change you ViewModel to include a property to hold CarName like this:-
public class CountCarsViewModel
{
public string CarName {get; set; }
public int Count { get; set; }
}
I think the problem is using "PartialView" in "return PartialView("_MainSideBarPartialLayout", view);". Try it on normal view to see the result and then make it partial. If you insist to use partial view , probably you need a trigger for partial view to show correct count.

show details view in mvc 3

HI i am new to mvc so if anyone can help me will be great
basically i just want to display a partiular item details, my code
private sneakerEntities
_sneaker_categoryDataModel = new sneaker_info.Models.sneakerEntities();
public ActionResult Index()
{
IList<sneaker> Releases = _sneaker_categoryDataModel.sneakers.ToList<sneaker_info.Models.sneaker>();
return View("Releases", Releases);
}
//
// GET: /Home/Details/5
public ActionResult Details (int id)
{
return View();
}
You need to find it from Repository and display in your strongly typed view
public ActionResult Details (int id)
{
Sneaker snkr=_sneaker_categoryDataModel.sneakers.Find(id);
return View(snkr);
}
In Details.cshtml
#model Sneaker
//all view related code
private sneakerEntities
_sneaker_categoryDataModel = new sneaker_info.Models.sneakerEntities();
public ActionResult Index()
{
IList<sneaker> Releases = _sneaker_categoryDataModel.sneakers.ToList<sneaker_info.Models.sneaker>();
// populate your IList with values here
return View("Releases", Releases);
}
After this Add a View By right clicking on this Action.
You will have a view Created which will have the First line as
#model IList<sneaker>
if not change it to this. Now write this syntax to retrieve values from each item of the list
#foreach(var data in Model)
{
//#data.Whatever
#data.Name
}

asp.net mvc - couple lists on page

Can I have 3 divs with lists from database on my page? I'm beginner in asp.net mvc and I don't know how to exactly do it... When I want make 1 list I do:
public ActionResult Favs()
{
var db = new MyDbContext();
List<books> lb = db.DbBooks.ToList();
return View(lb);
}
Then I right click -> make view and check option 'list'.
But what, if I want to see 3 diffrent lists?
public ActionResult Favs()
{
var db = new MyDbContext();
List<book> lb = db.DbBooks.ToList();
List<magazine> lm = db.DbMagazines.ToList();
List<author> la = db.DbAuthors.ToList();
return View(lb);
////////how return rest of them???
}
I will be thankful for any help!
You should use a Model class for your return View. (note this is all very rough code knocked up quickly)
Something like
public class MyListsModel
{
public List<book> Books { get; set; }
public List<magazine> Magazines { get; set; }
public List<author> Authorss { get; set; }
}
Then your ActionResult would be something like
var myModel = new MyListsModel();
myModel.Books = db.DbBooks.ToList();
myModel.Magazines = db.DbMagazines.ToList();
myModel.Author = db.DbAuthors.ToList();
return View(myModel);
You can then use those lists in your View page which might look similar to this:
#model MyListsModel
#{
ViewBag.Title = "My Page;
}
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
#foreach(book bookItem in Model.Books)
{
// Do something and repeat this type of action for each list
}
}

MVC Model State Validation fails on Listbox

I have a simple model which uses a multi select listbox for a many-many EF relationship.
On my Create action, I'm getting the error
The parameter conversion from type 'System.String' to type 'MyProject.Models.Location' failed because no type converter can convert between these types.
I have 2 models, an Article and a Location:
Article.cs
namespace MyProject.Models
{
public class Article
{
public Article()
{
Locations = new List<Location>();
}
[Key]
public int ArticleID { get; set; }
[Required(ErrorMessage = "Article Title is required.")]
[MaxLength(200, ErrorMessage = "Article Title cannot be longer than 200 characters.")]
public string Title { get; set; }
public virtual ICollection<Location> Locations { get; set; }
}
Location.cs:
namespace MyProject.Models
{
public class Location
{
[Key]
public int LocationID { get; set; }
[Required(ErrorMessage = "Location Name is required.")]
[MaxLength(100, ErrorMessage = "Location Name cannot be longer than 100 characters.")]
public string Name { get; set; }
public virtual ICollection<Article> Articles { get; set; }
}
}
I have a ViewModel:
namespace MyProject.ViewModels
{
public class ArticleFormViewModel
{
public Article article { get; set; }
public virtual List<Location> Locations { get; set; }
public ArticleFormViewModel(Article _article, List<Location> _locations)
{
article = _article;
Locations = _locations;
}
}
}
create.cshtml:
#model MyProject.ViewModels.ArticleFormViewModel
<h2>Create</h2>
#using (Html.BeginForm()) {
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<fieldset>
<legend>Article</legend>
<div class="editor-label">
#Html.LabelFor(model => model.article.Title)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.article.Title)
#Html.ValidationMessageFor(model => model.article.Title)
</div>
<h3>Locations</h3>
#Html.ListBoxFor(m=>m.article.Locations,new MultiSelectList(Model.Locations,"LocationID","Name"))
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
Finally my controller actions:
// GET: /Article/Create
public ActionResult Create()
{
var article = new Article();
var AllLocations = from l in db.Locations
select l;
ArticleFormViewModel viewModel = new ArticleFormViewModel(article, AllLocations.ToList());
return View(viewModel);
}
//
// POST: /Article/Create
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(Article article)
{
var errors = ModelState.Values.SelectMany(v => v.Errors);
if (ModelState.IsValid)
{
var locations = Request.Form["article.Locations"];
if (locations != null)
{
var locationIDs = locations.Split(',');
foreach (var locationID in locationIDs)
{
int id = int.Parse(locationID);
Location location = db.Locations.Where(l => l.LocationID == id).First();
article.Locations.Add(location);
}
}
db.Articles.Add(article);
db.SaveChanges();
return RedirectToAction("Index");
}
var AllLocations = from l in db.Locations
select l;
ArticleFormViewModel viewModel = new ArticleFormViewModel(article, AllLocations.ToList());
return View(viewModel);
}
This all works relatively well, my Locations listbox is populated properly:
If I do not select a Location then my model is saved properly. If I select one or more locations then my Model.IsValid check fails with the exception
The parameter conversion from type 'System.String' to type 'MyProject.Models.Location' failed because no type converter can convert between these types.
However if I remove the ModelState.IsValid check then despite the error my values are all correctly saved into the database - just that I lose validation for things such as the model title.
Hope someone can help!
Unless you create a type converter, you cannot directly bind the results of your list box directly to a complex object like that. The reason lies in the fact that MVC can only deal with posted HTTP values, which in this case are an array of strings that contain the selected ID's. Those strings do not directly map to your Locations object (ie the number 1 cannot be directly converted to a Locations object with an ID of 1).
Your best bet is to have a list of location ID's in your View Model of type string or int to accept the posted values, then in your post method create the Location objects and fill them with the correct ID's.
FYI, the reason your code works is because you are bypassing the model binding and going directly to the Request.Form collection. You will notice that the bound Article object will not have any Location objects.
EDIT:
I don't even see how your code would work even without this problem. Your ArticleFormViewModel does not have a parameterless constructor, so that will fail in model binding (unless you have a custom model binder).
In any event, what you want to do is this (note, you will have to populate SelectedLocationIDs if you want them to be selected when the view is rendered):
public class ArticleFormViewModel
{
...
List<int> SelectedLocationIDs { get; set; }
...
}
Then, in your view you have:
#Html.ListBoxFor(m=>m.SelectedLocationIDs,
new MultiSelectList(Model.Locations,"LocationID","Name"))
In your Post method, instead of the code that calls Request.Form, you have something like this:
foreach(var locationID in article.SelectedLocationIDs) {
... // look up your locations and add them to the model
}

How to edit using ViewData model

I have created a View Model based on combination of three Tables.
I click on Edit action it displays the Data from Three tables correctly.
But when i click on Save button i am not able to get data either from FormCollection or from Request["Id"]
Please suggest it the possible way.
public class ConferenceResourceEditModel
{
public ConferenceRoom ConferenceRoom { get; set; }
public Resources Resources { get; set; }
public ResourceAllocation ResourceAllocation { get; set; }
}
public ActionResult Edit(int id)
{
//ConferenceRoom conferenceroom = db.ConferenceRooms.Find(id);
var query =
from c in db.ConferenceRooms
from r in db.Resourcess
from ra in db.ResourceAllocation
where c.ConferenceID == id
where c.ConferenceID == ra.ConferenceID
where r.ResourceID ==ra.ResourceID
select new ConferenceResourceEditModel { ConferenceRoom = c, Resources = r,ResourceAllocation=ra };
return View(query);
}
//
// POST: /ConferenceRoom/Edit/5
[HttpPost]
public ActionResult Edit(FormCollection form, int id, ConferenceResourceEditModel conferenceroom,ConferenceRoom crf)
{
if (ModelState.IsValid)
{
db.Entry(conferenceroom).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(conferenceroom);
}
Look up model binding on the http://www.asp.net/mvc site where there are magnificent tutorials about this kind of thing.
in a nutshell your controller action will take a parameter of type YOURVIEWMODEL and bind to it automatically
Use some ORM ( like EntityFramework,personally i recommend DatabaseFirst approach). Using something like that:
var query =
from c in db.ConferenceRooms
from r in db.Resourcess
from ra in db.ResourceAllocation
where c.ConferenceID == id
where c.ConferenceID == ra.ConferenceID
where r.ResourceID ==ra.ResourceID
is much more complicated and difficult. Hope it will help.

Resources