I cannot for the life of me figure out how to do a viewmodel correctly. We have two models, tblInventory and tblGlobalhardware, both of which need to be shown on the Details page of an inventory item, based on the InventoryID (Primary key in tblInventory and is a column in tblGlobalhardware).
I've followed numerous tutorials but get errors such about the model etc when changed on the view.
Can anyone possibly point me in the direction of a basic, easy to follow tutorial?
Thanks
In MVC you usually pass a single model instance to the view. You want to show details of the product and the inventory. So you create a view model type:
public class ProductViewModel
{
public Inventory Inventory { get; set; }
public Product Product { get; set; }
}
Now you can bind your view to this type and display the data from both objects. Just create an instance with the desired values in your controller and send it to the view:
var viewModel = new ProductViewModel { Inventory = inventory, Product = product};
return View(viewModel);
Related
In my controller I have 2 simple methods for viewing and ordering products
[HttpGet]
public ActionResult Product(int id)
{
Product product = Repository.GetProduct(id);
return View(product);
}
[HttpPost]
public ActionResult Order(Order order)
{
var orderResult = OrderProcessor.Process(order);
return orderResult.Success ? View("OrderSuccess") : View("OrderFail");
}
The Order class contains fields from the view that customers must fill:
public class Order
{
public int ProductId { get; set; }
[Range(1, 10, ErrorMessage = "Quantity must be a number from 1 to 10")]
public int Quantity { get; set; }
[Required(ErrorMessage = "Address not specified")]
public string ShippingAddress { get; set; }
// other order info
}
In my view I want to use HTML helpers for form fields like #Html.TextBoxFor(x => x.ShippingAddress) to enable Javascript client validation. But the problem is that MVC only allows these helpers to be used for properties of the view model (in my case the Product class) and my view model doesn't contain ShippingAddress.
To get these helpers working I need to have the same class for the model of the Product view and the parameter of the Order method. But this doesn't make any sense in my case. The view model shold contain product properties (name, price, description, etc.) while the POST method parameter should contain user input (quantity, address, etc).
I would like to be able to use HTML helpers with the properties of the Order class like this:
#Html.TextBoxFor<Order>(x => x.ShippingAddress)
Is there a way to achieve this (maybe via an extension to MVC)? Or is there some other workaround for this problem?
There's a difference between your models and your view models. Models should reflect the database and your view models should be custom made to fit the view.
What you could do is creating a view model that contains all the properties you are interested in having contained in your view, and populate those fields with data from your database.
Perhaps it's not the neatest of solutions, but your view model could be as simple as:
public Order Order {get; set;}
public Product Product {get; set;}
And in the GET-method you get the order and product you want to display and and assign it to the view model.
No need To look for any magic. You can directly add "shipping address" in your Product Model as well.
What is the problem in adding that??
I'm struggling to conceptualise this because every resource I have found on Google has presented a different way to do it.
I have, at the moment generated razor views pertaining to a scaffolded controller using entity Framework. My controller looks like this:
// GET: tbl_computerinfo
public ActionResult Index()
{
var tbl_computerinfo = db.tbl_computerinfo.Include(t => t.tbl_equipment);
tbl_computerinfo = tbl_computerinfo.Where(c => c.Company == "Company Name");
return View(tbl_computerinfo.ToList());
}
My Model is quite large but is just a generated entity framework model built on two tables linked with a foreign key tbl_computerinfo and tbl_equipment.
There is a string field called company in tbl_computerinfo. I need to select all the unique company values in the database and then use that to populate a dropdown which would exist on the index view. The selection of a company on that dropdown list should then filter the results in index view to only pull back entries with that company name. Any pointing in the right direction would be gratefully appreciated.
You need to create a ViewModel:
public class ComputerInfoViewModel
{
public List<string> CompanyList {get; set;}
public ComputerInfo ComputerInfo {get; set;}
}
In your Index method you populate this and pass it to the View:
public ActionResult Index()
{
var model = new ComputerInfoViewModel
{
CompanyList = /* populate this with your list of companies */
ComputerInfo = /* populate this with what? */
};
return View(model);
}
In your View, you declare the model:
#model ComputerInfoViewModel
And you can access the model properties for display using #Model.CompanyList and #Model.ComputerInfo
I was originally developing a project for WPF, using MVVM, which had the benefit of allowing me to populate a list of views that I wanted available. Each view had a "Next" button that would progress to the next view in the list.
However, now I am trying to do the same in ASP.NET MVC. This is my first time using MVC, but I have an XML file, from which I need to generate this UI. These views, which are chosen from the script, also have components in them that are dynamic -- sometimes ViewA might need 3 "input views" nested in it, sometimes it might need 1.
I was achieving that before with ListBox, ItemsSource, and DataTemplate. So my question is this: how can I dynamically populate which views to display, and (more importantly) how can I dynamically fill those views with x number of control A, and y number of control B?
First off, a high-level overview of the project structure...
YourProjectName
Controllers
ProductController.cs
Models
ProductViewModel.cs
Views
_ProductPartial.cshtml
ListProducts.cshtml
ProductViewModel.cs
public class ProductViewModel
{
public string Name { get; set; }
public string Description { get; set; }
}
ProductController.cs
public class ProductController : Controller
{
public ActionResult Index()
{
// Create your model (this could be anything...)
var model = new List<ProductViewModel>
{
new ProductViewModel { Name = "Apple", Description = "A red apple" },
new ProductViewModel { Name = "Orange", Description = "An orange orange" }
};
// Return the main view and your model
return View("ListProducts", model);
}
}
_ProductPartial.cshtml
#model YourProjectName.Models.ProductViewModel
<h1>#Model.Name</h1>
<p>#Model.Description</p>
ListProducts.cshtml
#model System.Collections.Generic.List<YourProjectname.Models.ProductViewModel>
#foreach (var product in Model)
{
Html.Partial("_ProductPartial", product)
}
Summary
Now if you request that controller action (localhost/Product/Index or whatever it ends up being for you), the controller will create the model, render the parent view, and the parent view will render as many of the product partial views as necessary depending on the product model collection we defined in the controller. Views and partial views don't require models, but I imagine you will be using a model class of some sort to help you determine what/where/how many partial views to render in your parent views. This is about as basic as it gets but it should get you started in using partial views.
I have a project I am working on for a Meal Planner. I have a simple product model and a Meal model which should be a collection of products.
I am trying to create a "Create" view in which I can enter the name of the meal and I thought that I would return a partial view that would have a list of available products to choose from.
I know you can send a model to the partial view using
#Html.Partial("_ProductList", new MealPlanner.Models.Product())
My PartialView takes a
#model IEnumerable<MealPlanner.Models.Product>
This obviously throws an error so how would I pass a List of Products to my partial?
Ok so #scartag put me on the right track but I started looking at ViewModels and came up with the following...
public class ViewModelProducts
{
public Meal Meal { get; set; }
public virtual IEnumerable<Product> Products { get; set; }
}
This allows me to pass in a everything I need for the create view and then I can send the list of products to the partial as follows...
#Html.Partial("_ProductList", Model.Products)
Then all I had to do was to customize my partial view.
Thanks for the quick relies!
I'm creating a C# application using MVC 4, LINQ to SQL, and Razor Syntax.
I have created a class that gets the contents of a given row in the db based on a requested id.
I have made a controller that has a get and post handler. I created a strongly-typed view based on one of the model classes, and everything works great. Data is retrieved and displayed in the form. Data can be updated and submitted.
The problem is the dropdowns. I don't want it to show a textfield for the id. I want the dropdowns. I have about five dropdowns, all to be generated from the database. I've created models to create them.
I can use ViewData or ViewBag to pass in the dropdowns with no problem. But then, how do I select the selected option when the user loads the page?
The "model" in MVC is supposed to model the page, not your data. If you have dropdowns on your page, then you should have a collection of some kind (likely a List<T>) on your model that represents the choices, along with another property that represents the selected value. This property will be used to populate the initial value of the dropdown as well as send the selected value back up to the controller.
I would recommend avoiding ViewData or ViewBag in favor of a ViewModel.
A ViewModel is essentially a hybrid Model that aggregates all of the data that your View needs into a single entity. Rather than typing the View to a Model and passing the additional information needed by your View that is not in the Model in ViewData or the ViewBag you have everything you need in the Model that your View is typed to.
In your case the ViewModel might look something like this:
public class MyViewModel
{
public DropDown1 DropDownA { get; set; }
public DropDown2 DropDownB { get; set; }
public Model ModelData { get; set; }
}
public class DropDown1
{
public int SelectedValue { get; set; }
public List<T> DropDownValues { get; set; }
}
public class DropDown2
{
public int SelectedValue { get; set; }
public List<T> DropDownValues { get; set; }
}
Your View would by typed to MyViewModel. At this point, setting the data source of the drop downs to the drop downs in your ViewModel and setting the SelectedValue would be trivial.