Referencing Table data in View that references a different table [MVC] - c#

I have 2 Tables with separate Controllers & Views in the Same Database one called
Part
Another Called
Assembly
In my Edit View i get the data from the Parts Table.
I need to ALSO get specific data from the Assembly Table in the Edit view for Parts. The data i need to get has the same Column name.
I need to use #foreach to get / display this data in the Part Edit View
Below is what i'm using
#model WebSpares3.Data.Part
#foreach (var item in Model.Assembly) {
How can i specifically reference the Name from The Assembly table into the parts data if they have the same column name in each of the tables?

You can create a Model or ViewModel for this:
public class ViewModel
{
public Part MyPart { get; set;}
public Assembly MyAssembly { get; set;}
}
Then this is what you will pass to your view:
public ActionResult Create()
{
ViewModel model = new ViewModel();
model.MyPart = new MyPart ()
{
ColumnName1 = "Details here",
ColumnName2 = 1
}
model.MyAssembly = //populate your Assembly details class
return View(model); //return your view with two classes on one class
}
Now you can do this on your razor view:
#Html.DisplayFor(x => x.MyPart.ColumnName1)
#Html.DisplayFor(x => x.MyPart.ColumnName2)
and this one:
#Html.DisplayFor(x => x.MyAssembly.ColumnName1)
#Html.DisplayFor(x => x.MyAssembly.ColumnName2)

Related

MVC ViewModels - Can't access objects/variable passed from controller to View

I am trying to pass ModelView variables from controller to views but unfortunately views not allowing me to access variables. I mention code below.
Here is the ViewModel:
public class AuctionViewModels
{
public List<Auction> AllAuction { get; set; }
public List<Auction> PromotedAuction { get; set; }
}
Here is the Controller action that passes the data to the View:
public ActionResult Index()
{
AuctionViewModels vmodel = new AuctionViewModels();
vmodel.AllAuction = service.GetAllAuction(); //If we need to send more then 1 model to views
vmodel.PromotedAuction = service.GetPromotedAuction();
return View(vmodel);
}
Here is view:
#model List<DealDouble.Web.ViewModels.AuctionViewModels>
#foreach (var auction in Model.AllAuction )
{
<img class="card-img-top" src="http://placehold.it/700x400" alt="">
}
Here is Error:
CS1061: 'List<AuctionViewModels>' does not contain a definition for
'AllAuction' and no extension method 'AllAuction' accepting a first
argument of type 'List<AuctionViewModels>' could be found (are you missing
a using directive or an assembly reference?)
Can anyone tell me what actually i am doing wrong?
Change
#model List<DealDouble.Web.ViewModels.AuctionViewModels>
To
#model DealDouble.Web.ViewModels.AuctionViewModels
Then you'll be able to do foreach(var auction in Model.AllAuction)
you have error in line:
#model List<DealDouble.Web.ViewModels.AuctionViewModels>
you pass (as a model) Class, not list. List does not contain such property as AllAuction. try to replace this line with this one:
#model DealDouble.Web.ViewModels.AuctionViewModels
It should just be
#model DealDouble.Web.ViewModels.AuctionViewModels
You're only passing in one instance of this object, and then iterating over the AllAuction property.
You're instantiating a single object containing two fields both of which are lists:
AuctionViewModels vmodel = new AuctionViewModels();
vmodel.AllAuction = service.GetAllAuction(); /
vmodel.PromotedAuction = service.GetPromotedAuction();
But treating it as if it were a list in the view
#model List<DealDouble.Web.ViewModels.AuctionViewModels>
You need to change the above to:
#model DealDouble.Web.ViewModels.AuctionViewModels
You can then iterate over the two fields
#foreach (var auction in Model.AllAuction ){}
#foreach (var auction in Model.PromotedAuction ){}

Add model into model using Html helper HiddenFor C# MVC

I have a model like
public class Model
{
public int Value { get; set; }
public List<OtherModel> List { get; set; }
}
public class OtherModel
{
public int Value1 { get; set; }
public int Value2 { get; set; }
public bool IsPropTrue { get; set; }
}
I am using Model in a View where I'm looping through the List to show data in a table.
Depending on whether one of the properties (IsPropTrue) in OtherModel is true or false, I want to use the HiddenFor Html helper and send the data to the HttpPost controller.
#model Model
#foreach (var item in Model.List)
{
if (item.IsPropTrue)
{
#Html.HiddenFor(model=> item.Value1)
#Html.HiddenFor(model=> item.Value2)
}
}
I think it doesn't work because I should in some way add these properties to the OtherModel, which is inside the Model; But the way I have it now, I am adding properties to Model.
you can do it like this :
#model Model
#foreach (var item in Model.List)
{
if (item.IsPropTrue)
{
#Html.HiddenFor(model => model.List[Model.List.IndexOf(item)].Value1)
#Html.HiddenFor(model => model.List[Model.List.IndexOf(item)].Value2)
}
}
this way the binding system will bind the hidden fields with your List OtherModel in the Model
if you want send an array to server based on the Model you have to use indexer in #Html.HiddenFor .
#model WebApplication1.Models.MyModel
<form>
#if (Model != null && Model.List != null)
{
for (int i = 0; i < Model.List.Count; i++)
{
if (Model.List[i].IsPropTrue)
{
#Html.HiddenFor(model => Model.List[i].Value1)
#Html.HiddenFor(model => Model.List[i].Value2)
}
}
}
<button type="submit">submit</button>
</form>
if you want know reason of using indexer on model i recommend How does MVC 4 List Model Binding work?
Consider if it the responsibility of the view or the controller action to make the decisions - you can send everything back to the action to do the decision making.
In your Views/Shared folder, create a controller called EditorTemplates
In this folder, add a partial view called OtherModel
In this view, set the model to OtherModel and set the Layout=null
Add the three OtherModel fields in EditorFor (and HiddenFor if not displaying isPropTrue). This partial view displays just one instance of your list.
In your main view, use the above editor model like so. MVC will take care of all rendering and postback of the Model State for your complete list of items. We like one-liners...
#Html.EditorFor(model => model.OtherModel)
When the data is subsequently posted back to an action, Model State has wrapped up all of your displayed items into a list again, so you can check the isPropTrue value for each item on the server.
The only issue with MVC is that is you pass an empty list out to a view, you get a null value back, so just replace this with an empty list when null is returned

How to create foreach loop of a Model in a PartialView? (MVC.NET)

Beginner's Question: 2 tables on my db: Products, Categories. I created a View of Products. And I have a Sidebar Menu as a Partial View.
PartialView Name: _SidebarMenu
Layout Name: _AdminLayout
I want to list my categories in _SidebarMenu dynamically. So I tried this in _SidebarMenu:
#model IEnumerable<ProjectName.MVCWebUI.Models.Categories>
#foreach (var item in Model)
{
<li>#item.CategoryName</li>
}
But I got a Server Error:
The model item passed into the dictionary is of type 'System.Collections.Generic.List`1 [ProjectName.MVCWebUI.Models.Products]', but this dictionary requires a model item of type 'ProjectName.MVCWebUI.Areas.Admin.Models.AdminMenuContent'.
How can I list a different Model rather than a Model in a rendering View?
I would recommend using a child action, since it's virtually impossible to ensure that the right model will be passed to the partial in every single view otherwise. Basically, in the controller of your choice, add an action like:
[ChildActionOnly]
public ActionResult SidebarMenu()
{
// get categories from DB or whatever
return PartialView("_SidebarMenu", categories);
}
Then, in your layout, add the following where you want this menu to appear:
#Html.Action("SidebarMenu", "Foo")
Where "Foo" is the name of the controller you put this action in.
Assuming you have a ViewModel like:
public class IndexViewModel()
{
public List<Product> Products { get; set; }
public List<Category> Categories { get; set; }
}
Main view would have the:
#model IndexViewModel
Partial would have:
#model List<Category>
So from your main view you could render the partial and passing the correct list like:
#Html.Partial("~/Areas/....your_partial_name.cshtml", Model.Categories)

Trying to use two models in a view. Composite model does not contain extension method

I know there are a lot of topics about this issue, but none answers this specific problem of mine. I have a MVC project in which I want to implement two models on one View (separate tables).
I used the validated suggestion from the link to execute just that:
How do I view the parent view model MVC3 C#?
Here's my code:
-First model
[Table("Issue_Tracker")]
public class Case
{...
}
-Second model:
[Table("Jobs_Ref_Tbl")]
public class Job
{...
}
-Composite model:
public class IndexPageModel
{
public IEnumerable<Case> Cases { get; set; }
public IEnumerable<Job> Jobs { get; set; }
}
-Creating my CaseDBContext:
public class CaseDBContext : DbContext
{
public DbSet<Case> Cases { get; set; }
public DbSet<Job> Jobs { get; set; }
public DbSet<Server> Servers { get; set; }
public DbSet<User> Users { get; set; }
public DbSet<Department> Departments { get; set; }
}
In the controller I have sorted and filtered version of Cases model, using LINQ queries. After all the sorting and filtering, I used to pass an IPagedList of cases model to the view.
Now I have:
var cases = db.Cases.AsQueryable();
[sorts and filters]
var model = new IndexPageModel
{
Jobs = db.Jobs.ToPagedList(page ?? 1, 5),
Cases = cases.ToPagedList(page ?? 1, 10)
};
return View(model);
And finally I use them in the View:
<!DOCTYPE html>
#using PagedList;
#using PagedList.Mvc;
#model IPagedList<ITS.Models.IndexPageModel>
...
<table id="tableBe">
<tr>
<th style="border-left:none !important">
Action Buttons
</th>
<th>
<div style="width: 250px">
#Html.DisplayNameFor(model => model.Cases.First().Issue)
And here I run into the problem
'IPagedList' does not contain a definition for 'Cases' and no extension method 'Cases' accepting a first argument of type 'IPagedList' could be found (are you missing a using directive or an assembly reference?)
It's as if I did not include them in the model at all. Any advice on how to solve this problem would be appreciated.
EDIT: ADDITIONAL INFO
The code is very long, there are many filters in order to support combined search function. The basics consist of the 5th code snippet in my post:
I declare my IQueryable then manipulate it and after that I insert it into the model as the cases variable. db.Jobs I leave intact and thats why I insert it directly into the model variable.
It used to be:
var cases = db.Cases.AsQueryable();
[sorts and filters]
return View(cases.ToPagedList(page ?? 1, 10));
I want it to be:
var cases = db.Cases.AsQueryable();
[sorts and filters]
var model = new IndexPageModel
{
Jobs = db.Jobs.ToList()
Cases = cases
};
return View(model.ToPagedList(page ?? 1, 10));
But it returns
'IndexPageModel' does not contain a definiton for 'ToPagedList'
Your controller is returning a IndexPageModel, but your view wants a IPagedList<ITS.Models.IndexPageModel>. Change your model to accept the correct model:
<!DOCTYPE html>
#using PagedList;
#using PagedList.Mvc;
#model ITS.Models.IndexPageModel // The correct model.
Based on model => model.Cases.First().Issue it seems that you actually want to use the model returned from the controller (IndexPageModel).
I assume ToPagedList() returns an IPagedList<T>. Which means that you actually just want to use IPagedList in the IndexPageModel, but not in the actual view. So based on that you should be able to simply change the model in the view and it will work.

Making multiple models cast an ID using Entity Framework

I am new to using the Entity Framework. I have added my Model, and I need to use two my models/tables in one View Page. So to do that I added this to my AccountViewModels.cs page:
public class category_menuitem
{
public Category Category { get; set; }
public MenuItem MenuItem { get; set; }
}
I am trying to use Values from those two Models/Tables.
My View Page:
using System.Data.SqlClient
#model IEnumerable<YourGoGetterV1.Models.category_menuitem>
#{
ViewBag.Title = "Show Menu" - ViewBag.restaurant_id;
}
<h2>ShowMenu</h2>
<div class="jumbotron">
#foreach (var item in Model)
{
<div><strong>#Html.DisplayFor(item1 => item.Category.Name)</strong>
<div>#Html.DisplayFor(item1 => item.Category.Description)</div>
#{
using (var context = new YourGoGetterContext())
{
SqlParameter sa = new SqlParameter("#p0", ViewBag.restaurant_id);
var menu_items = context.MenuItems.SqlQuery("Select * FROM MenuItems where restaurant_id = #p0", sa).ToList();
var test = "DID IT WORK??";
}
}
</div>
}
</div>
Controller:
public ActionResult ShowMenu(string id, int restaurant_id)
{
ViewBag.Id = id;
ViewBag.restaurant_id = restaurant_id;
return View(Models.category_menuitem.ToList((object(id)));
}
I want to cast the ID, so that it creates a different URL for something that passes in a different ID. But I'm having two problems.
1) I can't even put in the Models.Category_menuitem.ToList() because "No overload for method 'ToList' takes 1 arguments"
2)The Models.Category_menuitem does not contain a definition for ToList.
What do I do?
I think you should do it different. The model should contain the data you use in the view. So do your db requests in the model and give the model to the view to display the data in it. Don't do SQL requests in the view. You also should write classnames always in capital letters because of C# naming conventions.
If I understand it right you want to display a menubar or something like that with categories and each category has many menuitems?
Just create a model menuitems like this:
public class MenuItems {
public List<Category> Categories{get;set;}
}
and a model Category like this:
public class Category {
public string CategoryName {get;set;}
public List<MenuItem> MenuItems {get;set;}
}
Fill the models with data and give the MenuItems Model to the view. In the view you can do something like:
#foreach (var category in Model.Categories)
{
foreach (var menuItem in category.MenuItems)
{
}
}
I hope this helps ;)
To this part of your code:
var menu_items = context.MenuItems.SqlQuery("Select * FROM MenuItems where restaurant_id = #p0", sa).ToList();
I am not sure what you wanna do. You are querying the db for data which should be already in the model or am I wrong? But if you want to use EF you would write:
var items = context.Menuitems.Where(m => m.restaurant_id == id).ToList();

Categories

Resources