ASP.NET MVC - Use two models in the same view - asp.net-mvc

The problem is that I need to "call" the PersonName field in the view of School, but the model in the view School is #model IList<Project.Presentation.Models.SchoolViewModel>, and the field PersonName is in the model #model IList<Project.Presentation.Models.PersonViewModel>. So, I guess I have to use two models in the same view, but I don't know how to do it. I don't know if I can only "call" the field I need using just one code line or if I have to do something behind.
Here is the code in the view School:
#model IList<Project.Presentation.Models.SchoolViewModel>
#{
ViewBag.Title = "Start view";
}#
{
<div class="row">
<div class="col-md-6 ">
<h2>
Details of the person #Html.DisplayFor(Project.Presentation.Models.PersonViewModel.PersonName)
</h2>
</div>
</div>
}
I'm trying with#Html.DisplayFor(Project.Presentation.Models.PersonViewModel.PersonName), but obviously it doesn't works.

your viewmodel will include all the property you will need in a view - so PersonViewModel should be a property in your viewmodel
you did not show the relationship between SchoolViewModel and PersonViewModel
but judge by the name, I am guessing it is a one to many relationship - i.e one SchoolViewModel will have many PersonViewModel representing the person in school
so base on that assumption, your SchoolViewModel may look like this:
public class SchoolViewModel
{
// other property ..
public IList<Project.Presentation.Models.PersonViewModel> PersonList {get; set;}
}
then in your view, it will look like:
#model IList<Project.Presentation.Models.SchoolViewModel>
#// first loop school
#for(int i =0; i < Model.Count; i++)
{
<div class="row">
#// then loop all person in the school
#for(int j = 0; j < Model[i].PersonList.Count; j++)
{
<div class="col-md-6 ">
<h2>
Details of the person #Html.DisplayFor(modelItem => Model[i].PersonList[j].PersonName )
</h2>
</div>
}
</div>
}
so the key is, put all your needed property to your viewmodel

Create a View Model and Include this Two Model in there
public class SchoolPersonViewModel
{
public IList<Project.Presentation.Models.PersonViewModel> PersonList {get; set;}
public IList<Project.Presentation.Models.SchoolViewModel> SchoolList {get; set;}
}
In View
<div class="row">
<div class="col-md-6 ">
<h2>
Details of the person
#Html.DisplayFor(model => model.PersonList)
</h2>
</div>
</div>
PersonList is List, So Use foreach
Same Like SchoolList

Related

How do I take a subset of a views Model and send the subset model to a partial view?

How do I take a subset of a views Model and send the subset model to a partial view?
I created a model, but the partial is looking for the parent model.
Am I creating this secondary subset model correctly?
How do I get the partial to see this secondary subset model?
Parent View code (not all):
#model GbngWebClient.Models.BlogPublishedByBlogIdVM
#* Create a subset model to send to the partial view. *#
#{
int parentBlogId = #Model.BlogPublishedByBlogId.BlogId;
int parentLikeCount = #Model.BlogPublishedByBlogId.LikeCount;
int parentDisLikeCount = #Model.BlogPublishedByBlogId.DisLikeCount;
bool parentDisabledBoolean = #Model.BlogPublishedByBlogId.DisabledBoolean;
}
<div class="row">
<div class="col-md-1">
#* A partial view. Sending the subset model to the partial view. *#
#Html.Partial("_BlogLikeAndDislike", #Model)
</div>
</div>
<br />
Partial view code (not all):
<div>
#* Get the parent view's values that were passed via a model. *#
<i class="BlogLike fa fa-my-size fa-thumbs-up"></i> | <i> #Model.LikeCount</i>
<i class="BlogDisLike fa fa-my-size fa-thumbs-down"></i> | <i> #Model.DisLikeCount</i>
</div>
You can define a new model e.g
public class ChildViewModel
{
public int ParentBlogId {get; set;}
public int ParentLikeCount = {get; set;}
public int ParentDisLikeCount = {get; set;}
public bool ParentDisabledBoolean = {get; set;}
}
Then you create the child model in parent view and pass the child view model when calling partial view
#Html.Partial("_BlogLikeAndDislike", childViewModel)
Finally set the model in Partial view
#model GbngWebClient.Models.ChildViewModels
<div>
#* Get the parent view's values that were passed via a model. *#
<i class="BlogLike fa fa-my-size fa-thumbs-up"></i> | <i> #Model.ParentLikeCount</i>
<i class="BlogDisLike fa fa-my-size fa-thumbs-down"></i> | <i> #Model.ParentDisLikeCount</i>
</div>
You can do this, on your Razor Syntax. Declare your new instance of your Model which corresponds to the model on your Partial View:
#{
var entityPartial = new PartialViewModel(); //Make sure to complete the namespace here
//Then attach the properties on your variable:
entityPartial.parentBlogId = #Model.BlogPublishedByBlogId.BlogId;
}
Afterwards, put this on your Partial HTML Helper, just pass the entity variable that you declare on the argument:
#Html.Partial("_BlogLikeAndDislike", entityPartial)
That's it. Make sure it PartialViewModel on my example here is the same model on your Partial View.

retrieve data from different columns of single table into a single view page in mvc razor

I am doing a project and I got confused in a particular session that I have a table called deposits
public partial class Deposit
{
public int Id { get; set; }
public string Title { get; set; }
public string SavingBank { get; set; }
}
created a controller called Products and an ActionResult called Deposits
public ActionResult Deposits()
{
var ShowResult = db.Deposits.ToList();
return View(ShowResult);
}
When I check the code using breakpoints a got all the values from the table but in the view page , I need to get the data of each item from table with different places in that single view page(eg- I need to get the data of savingBank from table at the top of the view page, FixedDeposit at the end of the view page etc, all the entries should be made on the single page),
#model List<Project.Models.Deposit>
<div class="saving_cont">
<div class="container">
<div class="row">
<h3 class="main_hed">Saving Bank Account</h3>
<div class="col-lg-3 col-md-3 col-sm-3 col-xs-12">
<img src="../assests/image/saving_bank.png" class="img-responsive">
</div>
<div class="col-lg-9 col-md-9 col-sm-9 col-xs-12">
#Html.Raw(Model.SavingBank)
</div>
</div>
</div>
</div>
<br>
but when I run the code it shows a compilation error that " 'List' does not contain a definition for 'SavingBank' and no extension method 'SavingBank' accepting a first argument of type 'List' could be found (are you missing a using directive or an assembly reference?)"
why is this error coming?? Why can't I retrieve different columns of table into a single page ?? can anyone please help me to solve my problem ??
Model is of the type List<Deposit>, not Deposit. SavingBank is a property of a single Deposit.
If you are targeting a single item in the list, you will have access to that property:
foreach(Deposit deposit in Model)
{
<div>
#Html.Raw(deposit.SavingBank)
</div>
}
You could also do something like Model.First().SavingBank if that's what you're after.

ASP.NET MVC: Passing a string to a view

I have a controller that looks like this:
public class PersonController : Controller
{
public ActionResult Result()
{
var s = new PersonResult();
s = GetPerson(ViewBag.PersonInfo);
return View(s);
}
[...]
}
The controller calls the view Result which looks like this:
#model My.Class.Library.DTO.PersonController
#if (Model != null && Model.Persons.Count > 0)
{
#Html.Partial("Persons", #Model.Persons)
}
So the model can hold many Persons. Persons is sent to its own view like this (view Persons):
#using My.Class.Library.DTO
#model List<Person>
<section>
#foreach (Person person in #Model)
{
#Html.Partial("Person", person)
}
</section>
So I'm sending each Person person to my view Person. And in that view I'm drawing each Person like so:
#model Person
#if (Model.Fields.TryGetValue("description", out description)
{
var descSplit = description.Split('#');
foreach (string s in descSplit)
{
<div class="row-fluid">
<div class="span2">Person</div>
<div class="span10">#s</div>
</div>
}
}
But instead of doing that, I want to pass the string s to its own view. Something like this:
#model Person
#if (Model.Fields.TryGetValue("description", out description)
{
var descSplit = description.Split('#');
<section>
#foreach (string s in descSplit)
{
#Html.Partial("Description", s)
}
</section>
}
But "s" is just a primitive type: a string. How do I pass that to my view "Description"? What should my view "Description" look like? I'm thinking something like this:
#model string
<div class="row-fluid">
<div class="span2"><b>TEST</b></div>
<div class="span10">#s</div>
</div>
But that's not correct... What should my model be and how can I present the string (s) that I'm sending from the other view?
Your code looks right but in your partial view, try using the Model property.
#model string
<div class="row-fluid">
<div class="span2"><b>TEST</b></div>
<div class="span10">#Model</div>
</div>
When you strongly type your Views/PartialViews, you have to use the Model property to read the value you have passed as a Model to this View/PartialView.

rename mvc model object in Razor View

I'm using MVC 4 and usually Visual Studio will create all the views for you. I have one form that just has one field and I want to just embed the create form into the Index View.
So the Index View has something like #model IEnumerable<Models.LinkModel>
So I access it by iterating through the Model collection.
But if I try to embed the form for the create action I need #model Models.LinkModel
and it is accessed by Model.Name as well. Is there a way to do this or use a different variable name?
Ok here is some extra info.
SO I have a model.
public class LinkModel
{
public string LinkUrl {get;set;}
}
I have a controller that has the Create and Index ActionResults.
Now in the Index view I have
#model IEnumerable<Models.LinkModel>
#{
ViewBag.Title = "Links";
}
I can do all my fancy logic to list all the links.
#foreach(link in Model)
{
<p>link.LinkUrl<p>
}
The Create View has this
#model Models.LinkModel // Note that it is just one item not IEnumerable
#{
ViewBag.Title = "Add Link";
}
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
<fieldset class="editor-fieldset">
<legend>LinkModel</legend>
<div class="editor-label">
#Html.LabelFor(model => model.LinkUrl)
</div>
<div class="editor-field">
#Html.TextBoxFor(model => model.LinkUrl)
</div>
<p>
<input type="submit" value="Add Link" />
</p>
</fieldset>
}
Now it seems pretty stupid to have a create form for just one field. I want to put this form on the Index page. Problem is that I access the object using the variable Model. I wanted to know if there is a way to have two seperate instances or be able to access the Model objects with different names.
Have a composite model with a list of items and 1 single item for the create
public class IndexModel {
public LinkModel CreateModel {get; set;}
public IEnumerable<LinkModel> Items {get; set;}
}
#model IndexModel
#using(Html.BeginForm("create")) {
#Html.EditorFor(m => m.CreateModel.Name);
}
#foreach(var item in Model.Items) {
#item.Name
}

Passing Data across multiples views using mvc 3 and EF

maybe this question is seen repeatedly around here but i was not able to find a answers.
my project is about reservations for hotels. I have a class Reservation witch has a Icollection of ChoosenRooms and a class that represents de User making the reservation, and other stuff like dates and other stuff.
The process is this:
In my first view I get the chosen rooms, dates, etc, then i pass that to my second view where i´m going to get the user info, and then i have a third view where i want to show all the gathered information so the user can finally click a button to save the data.
My problem is that i need to pass the reservation object class across all these views. In my testing i see that primitive types pass just fine BUT The iColletion of ChoosenRooms is lost when i post back from the view to the next controller action.
can someone post some example how to, Posting back from a view to a controller, complex types like ChoosenRooms inside another class Reservations, are not lost in the process?
Or maybe explain why this info is lost?
the code:
public class Reserva
{
public virtual int ID { get; set; }
[NotMapped]
public string[] q { get; set; }
[Display(Name = "Cliente")]
public virtual Utilizador utilizador { get; set; }
[Display(Name = "Quarto")]
public virtual ICollection<Quartos> ChoosenRooms{ get; set; }
[Display(Name = "Serviços Adicionais")]
public virtual ICollection<ReservasItens> itens { get; set; }
The view
#model SolarDeOura.Models.Reserva
#{
ViewBag.Title = "AddReservaUser";
var _reserva = TempData["reserva"] as Reserva;
}
<h2>AddReservaUser</h2>
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
<fieldset>
<legend>Reserva</legend>
<div class="editor-label">
#Html.LabelFor(model => model.dtEntrada)
</div>
<div class="editor-field">
#Html.DisplayFor(model => model.dtEntrada)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.dtSaida)
</div>
<div class="editor-field">
#Html.DisplayFor(model => model.dtSaida)
</div>
<div class="editor-label">
#Model.q.Count() Choosen Rooms
</div>
#foreach (var q in Model.ChoosenRooms)
{
<ul>
<li>
#Html.DisplayFor(modelitem => q.descricao)
</li>
</ul>
}
posting back from here is the Problem. In this view " #foreach (var q in Model.ChoosenRooms)" has data but posting back the data is lost.
The concept of model binder at this point was not very clear to me and some knowledge about this topic is all it takes to solve the question.
In resume:
The view gets a model which is a complex type: class [reserva] has a collection of [ChoosenRooms] which is also a complex type.
The line #Html.DisplayFor(modelitem => q.descricao) renders the necessary html elements to display the data, but not the necessary html to be posted back to the controller (input element or hidden field ) so the model binder fails.
Also the controller (post) action argument didn't had the property name that matches the field, in this case it needed to be a String[] type since its a collection of values.
I would also recommend reading about Display Templates and Editor Templates.

Resources