I am new to MVC.
I have two tables: first one stores the vendor’s information, the other one stores the order details. I want to use the vendor table’s values for the dropdown list.
#model Ore.Domain.Entities.OrderDetail
#{
ViewBag.Title = "";
}
<h2> </h2>
#using (Html.BeginForm())
{
<div>vendor: #Html.DropDownListFor(x=>x.Vendor,’**how to use the value from another entities or models?** ’)</div>
<div>Contract Number: #Html.EditorFor(x=>x.ContractNo)</div>
Thanks
This is a good example of when you need to break away from your DO and make a hybrid view that either contains composite DO's like a Parent item and a List of Child items or some combination thereof. The more it resembles your DO the more likely that you can leverage mapping techniques such as auto mapper.
Just introduce a model specificly for your view. Let's call it OrderDetailViewModel:
public class OrderDetailViewModel
{
public Ore.Domain.Entities.OrderDetail Order {get;set;}
public IEnumerable<SelectListItem> Vendors {get; set;}
}
Then on your view:
#model OrderDetailViewModel
<h2> </h2>
#using (Html.BeginForm())
{
<div>vendor: #Html.DropDownList("Vendor", Model.Vendors)</div>
<div>Contract Number: #Html.EditorFor("ContractNo", Model.ContractNo)</div>
Or just pass Vendors throught ViewBag like this:
in controller:
ViewBag.Vendors = // populate items as new List<SelectListItem>()
on view:
<div>vendor: #Html.DropDownListFor(n=>n.Vendor, (List<SelectListItem>)ViewBag.Vendors)</div>
Related
Translate code in Laravel to asp.net mvc. I am passing a subset of the model and summarizing the fields by year. My EF model has 50+ fields.
This is my Laravel route:
Route::get('/metrics', 'MetricsController#index');
My Laravel Controller
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use App\Http\Controllers\Controller;
class MetricsController extends Controller
{
public function index()
{
$metrics = DB::select('select year(date_id) as Year, Sum(Revenue) from metrics Group By year(date_id)');
return ($metrics);
}
}
I would like to display the model data in a #foreach loop in the view? The dump in the Laravel view displays the data in the following way.
[{"Year":2009,"Sum(Revenue)":"61302670.65"},
{"Year":2011,"Sum(Revenue)":"68397989.00"},
{"Year":2012,"Sum(Revenue)":"69245803.00"},
{"Year":2013,"Sum(Revenue)":"67184051.00"},
{"Year":2014,"Sum(Revenue)":"33445434.00"}]
I will keep it simple, sticking to the fact that you need to show the data in the View. For that, I will assume that you already have your DbContext, Models and data loading parts ready.
Model
I will create a sample model just for the sake of example. But it could, obviously, be more advanced.
public class Result
{
public string Year { get; set; }
public decimal SumRevenue { get; set; }
}
Action Method (in the Controller)
The most important here is the fact that you are loading a "List of" model as result of your query. As you are using EF, you could load it directly from your DbContext or probably use a repository pattern. Since we don't know, I am just making a simple method call so just imagine the DB logic is in there :)
public ActionResult Index()
{
// Here is where you load your data. I am using this line just as example.
List<Result> resultList = RandomLibrary.LoadData();
return View(resultList)
}
View
Remember to prepare your View to receive the List you got in the Action Method.
#model List<Result>
#foreach(var item in Model)
{
<p>
<strong>Year: </strong>#item.Year
<br />
<strong>Sum of revenue: </strong>#item.SumRevenue
</p>
}
This is an oversimplification of the process. You can see it in more details in the official documentation. Or just let us know if you will need a more detailed explanation as your case might be a bit different.
I am a front end developer and not very strong with MVC 4, so I apologise if this is a very stupid question.
I am attempting to modify a view I have inherited - I have copied a dynamic model into a page that has a model already - I know that you cannot have 2 models declared, so how should I modify the below?
#model MvcSiteMapProvider.Web.Html.Models.SiteMapNodeModel
#using System.Web.Mvc.Html
#using MvcSiteMapProvider.Web.Html.Models
#using Project.RealTime.LookupService;
#using Project.RealTime.Models;
#model dynamic
#{
SessionVars session = new SessionVars();
Account account = null;
if ((Model != null) && (Model is Account))
{
account = (Account)Model;
}
What is the best way to combine the model and the dynamic model so I can use both in this view?
Try to leave just #model dynamic and delete #model MvcSiteMapProvider.Web.Html.Models.SiteMapNodeModel.
But it will be better to have two separate views with strongly-typed models. Because it helps you to identify some errors at compile time and have intellisense on view.
If you need Account in our view - maybe you should review your ViewModel and add Account to it.
Include the dynamic data you want into the model. A model should usually not be a certain data class but rather a class that is a collection of the data to be used in your view.
For example
public class ControllerActionViewModel
{
public FooClass Foo;
public dynamic Foo2;
}
and then
#model Project.Models.ControllerActionViewModel
#Model.Foo2.whatever
Since you can only have one Model in the View, the best option is to modify the Model so that it includes the information in your new dynamic model.
You have two good options:
-Edit the existing Model class and add the properties
-Or inherit the existing Model:
public class MyNamespace.MyNewModel : MvcSiteMapProvider.Web.Html.Models.SiteMapNodeModel
{
public string Property1 { get; set; }
/* .... */
}
And in your View only reference the new View Model:
#model MyNamespace.MyNewModel
The easiest way to do that is using the ViewBag for the dyanmic part. ViewBag is a dynamic object which is available in both the controller and the template. If you add a property in the controller, it will be available in the template.
In the controller:
ViewBag.Title="Our house in the middle of a street";
In the template:
<h1>#Viewbag.Title</h1>
If you the model is already available, just pass it as a property of ViewBag:
ViewBag.SecondModel=myExistingModel;
I would like to know how I can render a custom header (based on customerid) and a side menu (again, based on the customerid) + the main content.
On a search page, I have a list of customers. When I select a customer, it will take me to another page passing the id of that customer (/controller/action/id). However, on this new page, I would like to list customer details on the header (name, email, phone, etc), on the side menu, I would like to list the pets that this customer owns (dog1, cat2, etc) and on the main content I want to show details of the first pet on the list (side menu). The list of pets on the side menu should be links. For instance, the dog1 should be a link to its own details shown on the main content. Cat2 should be a link to show details on the main content, etc
I just don't know how I am going to pass the id to the header, side menu and content page, all at once!
I have seen the mvcMusicStore where we have a list of the genres on the left menu, but that does not change! In my case, the side menu should change according to the customer selected on the previous page! Make sense?
You have multiple choices. At first, you can use partial views:
in layout.cshtml [or in your usecase, search page]:
#Html.Partial(your-partial-view-name)
view: headerPartial.cshtml as an example:
#if(User.Identity.IsAuthenticated) {
<span>Welcome</span> #User.Identity.Name
} else {
<span>Login or Register</span>
}
This is the base logic. For your situation, you need something like this. But, if you have to load some data from for example database, I would suggest you using partial actions:
// in layout or search or any page you want to render partial views:
// For example you have a controller named MyPartials:
// Put this line where you want to render header:
#Html.Action("HeaderInfo", "MyPartials")
and action:
public class MyPartialsController : Controller {
public ActionResult HeaderInfo() {
var model = retrive header needed info from db
return Partial(model);
}
}
Let me know more about your problem in details, to suggest you a good solution
UPDATE:
Suppose:
Controller: CustomerController
Action: SeletedCustomer
Solution:
1. Models:
public class HeaderInfoModel { } // contains header data: name, email, phone, etc
public class SideInfoModel { } // dog1, cat2, etc
public class MainContentModel { } // holding main content data
// bringing all together
public class CustomerModel {
public HeaderInfoModel HeaderInfo { get; set; }
public SideInfoModel SideInfo { get; set; }
public MainContentModel MainContent { get; set; }
}
2. Controller
public class CustomerController : Controller {
public ActionResult SeletedCustomer(int id) {
// use id and retrieve data you want, from db or anywhere else you want
var model = new CustomerModel {
HeaderInfo = SomeMethodToFetchHeaderData(id),
SideInfo = SomeMethodToFetchSideData(id),
MainContent = SomeMethodToFetchMainContent(id)
};
return View(model);
}
}
3. Main View: Customer/SeletedCustomer.cshtml
#model CustomerModel
<div id="header">
<!-- put this where you want to render header -->
#Html.DisplayFor(model => model.HeaderInfo)
</div>
<div id="side">
<!-- put this where you want to render side -->
#Html.DisplayFor(model => model.SideInfo)
</div>
<div id="main">
<!-- put this where you want to render main content -->
#Html.DisplayFor(model => model.MainContent)
</div>
4. In your situation, using Display Templates is the easiest way. Create a folder named DisplayTemplates in one of these places: ~/Views/Customer/ or ~/Views/Shared. It depends on where and how you want to use provided models. Again, in your case, I suggest create this: ~/Views/Customer/DisplayTemplates/. And then add some views in that folder, which are described below:
4.1. Create HeaderInfoModel.cshtml in ~/Views/Customer/DisplayTemplates/:
#model HeaderInfoModel
<div>
implement your model presentation, I mean, show the data how you want
</div>
4.2. Create SideInfoModel.cshtml in ~/Views/Customer/DisplayTemplates/:
#model SideInfoModel
<div>
implement your model presentation, I mean, show the data how you want
</div>
4.3. Create MainContentModel.cshtml in ~/Views/Customer/DisplayTemplates/:
#model MainContentModel
<div>
implement your model presentation, I mean, show the data how you want
</div>
That is it. Done! With your situation, the best way I can suggest is that. However, you have multiple choices; It's completely depended on your project.
You probably need to use some kind of partial view with condition like it shown below inside razor
if(this is correct page && CustomerID is available) { show the view }
You can pass parameters in ViewBag and use them inside your view.
If you are new to ASP.NET MVC, here are some cool tutorials http://www.asp.net/mvc.
And here is tutorial of building partial views http://mvc4beginner.com/Tutorial/MVC-Partial-Views.html for beginners.
Hope this helps
Maybe this is very simple to do but I can't find the good words when I search on stackoverflow or on google.
I have a model and this model contains a "Country" property that is a integer. When I am in the Edit view, this property is used this way and it work well.
#Html.DropDownListFor(model => model.Country, new SelectList(ViewBag.Countries, "IDCountry", "Name"))
In the Details view, I only want to show the name of the country, but I don't know how! Right now, I'm doing this but it only show the ID and I can't find a way to give him the List so it use it as a datasource or something like that to show "Canada" instead of 42.
#Html.DisplayFor(model => model.Country)
How can this be achieved?
How can this be achieved?
By using a view model of course:
public class CountryViewModel
{
public int CountryId { get; set; }
public string CountryName { get; set; }
}
and then you would populate this view model in the controller action that is supposed to render your Display view:
public ActionResult Display(int id)
{
Country country = ... go and fetch from your db the corresponding country from the id
// Now build a view model:
var model = new CountryViewModel();
model.CountryId = country.Id;
model.CountryName = country.Name;
// and pass the view model to the view for displaying purposes
return View(model);
}
Now your view will be strongly typed to the view model of course:
#model CountryViewModel
#Html.DisplayFor(x => x.CountryName)
So as you can see in ASP.NET MVC you should always be working with view models. Think in terms of what information you need to work with in a given view and the first thing you should do is define a view model. Then it's the responsibility of the controller action that is serving the view to populate the view model. Where the values of this view model are coming from doesn't really matter. Think of the view model as a single point of aggregation of many data sources.
As far as the views are concerned, they should be as dumb as possible. Simply work with what's available in the view model.
So, should Model be considered as reflection of a view in terms of data. For example the model of a contact form would be : Name, Email Address, WebsiteName and Description ? Is this correct conceptually ?
Thanks
V.
What you have explained is a ViewModel essentially: a Model that is tailored to one View. But the definition of a Model would be the objects that send information to the database, perform business functions, and are just the representation of the domain of the application.
Yes that is one case of model. Model can also be business domain rules.
From Wikipedia:
The model manages the behaviour and data of the application domain,
responds to requests for information about its state (usually from the
view), and responds to instructions to change state (usually from the
controller). In event-driven systems, the model notifies observers
(usually views) when the information changes so that they can react.
In general, yes. Sometimes it's tedious, but a 1:1 ratio of "view" model to view works very well, and keeps concerns separated.
public class ContactFormViewModel
{
public string Name { get; set; }
public string Email { get; set; }
public string WebsiteName { get; set; }
}
If you were to use Visual Studio's (assuming version 3 of MVC and Razor syntax) built-in scaffolding to generate a view inheriting this view model, it would look something like this:
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>ContactFormViewModel</legend>
<div class="editor-label">
#Html.LabelFor(model => model.Name)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Name)
#Html.ValidationMessageFor(model => model.Name)
</div>
...
This gives you a couple things:
A little CSS styling (again, just the default templating)
Validation
1 Model to modify when the contact form logic changes
Yes.
There are two ways to look at a model in an MVC application. The two have a lot of overlaps, but are not necessarily the same.
View Model -- contains a model of data to be created, deleted, edited or shown in a view.
Entity Model -- contains a model of a data set from a datasource to be created, deleted, edited or shown in a view.
As you can see, in most cases this will be the same thing. There are situations where thinking of a view model will make more sense.