MVC page needs to get data from multiple models - asp.net-mvc

I am new to MVC.
I have a page which display list of categories. The same page also has a text box to search category. What do I need to do in order to use two models in one single page.
namespace MvcWebsite.Models.User
{
public class ListOfCategories
{
public int lngCatId { get; set; }
public Byte intStatus { get; set; }
public string txtTitle { get; set; }
public ListOfCategories()
{
intStatus = 1;
}
}
public class SearchBox
{
public string txtSearch { get; set; }
}
}

Create a model that incorporates both models - this is called a ViewModel
public class UserViewModel
{
public ListOfCategories ListOfCategories { get; set; }
public SearchBox SearchBox { get; set; }
// optional method to load data into the viewmodel
}

Create a ViewModel class which contains all the properties required for view.

what I understand from your question is that you want to use properties of both two models from a single page. If that is then you need to use the concept of ViewModels , which is known for the solution of such situations. You simply need to create another which will be some thing like this :
public class ThirdModel
{
public ListOfCategories ListOfCategories { get; set; } // properties from one model
public SearchBox SearchBox { get; set; } // properties from second model
}
Now you can access properties of both models in a single model.Thanks

Related

Viewmodel set up Aspt.net MVC 6

I'm having trouble understanding how to implement a ViewModel in Asp.net MVC, I have the following tables:
Form
ID, Data
Report
ID, FormID, Owner, Category, Status, SubmissionDate
ReportValues
ID, ReportID, Title, Value
I'm looking for a way to display and edit Report and ReportValues in the one ViewModel where ReportValues.ReportID = Report.ID
ReportValues will have multiple entries that relate to a Report.
I have had a look at similiar questions on here and tried following a tutorial ( http://techfunda.com/howto/262/list-data-using-viewmodel ) and coming up empty handed.
If you need any more information let me know and thanks in advance for any replies!
Your View Model is nothing more than a class. You can solve this many ways, but here's an example.
Create your 3 classes like you normally would.
public class Form
{
public int Id { get; set; }
public string Data { get; set; }
}
public class ReportValues
{
public int Id { get; set; }
public int ReportId { get; set; }
public string Title { get; set; }
public string Value { get; set; }
}
public class Report
{
public int Id { get; set; }
public int FormId { get; set; }
public string Owner { get; set; }
public string Category { get; set; }
public string Status { get; set; }
public DateTime SubmissionDate { get; set; }
}
Then, create your ViewModel class to include the three above classes like this.
public class ReportViewModel
{
public Form Form { get; set; }
public ReportValues ReportValues { get; set; }
public Report Report { get; set; }
}
In your view you can access your three classes and their properties as you would in your controller. Model.Form.Id
Depending on your data types, ReportValues will likely be a property of Report, but that's entirely up to your data structure. You will need to populate the classes using whatever method you want (Entity Framework, ADO, etc.) before you can pass them to your view and use them.

How to map a list of checkboxes options to a model first class?

I have this list of options in my web form:
And I want to work with model-first. But I'm very noob with MVC and Model-first, so I don't know how to better represent this in my model class.
Should I make one attribuite for each item? Or should I make an array where each position is one option (maybe using enums)?
public bool[] Comportamento { get; set; }
// or
public Comportamento[] Comportamento { get; set; }
// or
public bool Manso { get; set; }
public bool Arisco { get; set; }
...
You should have a class CompartamentoViewModel that looks like this:
public class CompartamentoViewModel
{
public int Id { get; set; }
public string Description { get; set; }
}
Then, in your main view model:
public class MyViewModel
{
// List of all objects for the view
public List<CompartamentoViewModel> Compartamentos { get; set; }
// List of ints to retrieve selected values
public List<int> SelectedCompartamentos { get; set; }
}
In the view, use the description for the text and the ID for the value. In the post, populate SelectedCompartamentos with the list of selected IDs.
Disclaimer: I have no idea how to pluralise "Compartamento."

MVC: Correct way to add extra field to child object into view without making things complicated

I'm trying to do something i that feels like a small task, but i cannot figure out a simple way to do it. All my approaches for doing this gets really complex for a simple task.
I have these models:
public class Blog
{
public int Id { get; set; }
public String Name { get; set; }
public virtual ICollection<Post> Posts { get; set; }
}
public class Post
{
public int Id { get; set; }
public String Name { get; set; }
public int BlogId { get; set; }
public virtual ICollection<Comment> Comments { get; set; }
}
public class Comment
{
public int Id { get; set; }
public String CommentText { get; set; }
public int PostId { get; set; }
public int UserProfileUserId { get; set; }
}
public class UserProfile
{
public int UserId { get; set; }
public string UserName { get; set; }
public String FirstName { get; set; }
public String LastName { get; set; }
}
In the Added Comments partial view, i want to show the full user name of the user that made a comment. If i just use my base classes in my views and partial views, i get everything i need except full user name on added comments. So far, i've thought of the following ways:
ViewModels - This will result in creating a ViewModel for each of my Classes and then populate / map them manually in my controller.
Code in Views - I have the UserProfileUserId so i can just ask the repository from the view but this Kills the MVC in MVC so i don't want to do it.
Actually Adding UserProfileFirstName and UserProfileLastName to the Comment Class as foreign keys - This feels like filling the database with view specific data. It doesn't belong in a relational database.
Using regular SQL and Query the database - Just because i know SQL, this -could- be a way to do it. but then again i'm killing the MVC in MVC.
How should i do this? Where is my silly overlooked option? I've searched a lot but could not find an answer, but this could be related to me not knowing all the technical terms yet. Sorry if this is answered 1000 times before.
Ideally i would change my domain model to include a Author property of type UserProfile and load that data as well using a JOIN (Comment table and User table)
public class Comment
{
public int Id { get; set; }
public String CommentText { get; set; }
public int PostId { get; set; }
public UserProfile Author { get; set; }
}
EDIT : As per the questions in the comment
This is how i will do this.
My Repositary method will have these methods
List<Comment> GetCommentsForPost(int postId);
BlogPost GetPost(int postId);
I would have ViewModel for representing a single blog post like this
public class PostViewModel
{
public int PostID { set;get;}
public string PostText { set;get;}
public string AuthorDisplayName { set;get;}
public List<CommentViewModel> Comments { set;get;}
public PostViewModel()
{
Comments=new List<CommentViewModel>();
}
}
public class CommentViewModel
{
public int CommentID {set;get;}
public string Text { set;get;}
public string AuthorDisplayName { set;get;}
}
Now in your GET Action, Get the data from your Repositary and Map that to ViewModel and send it to view
public ActionResult ViewPost(int id)
{
var post=repositary.GetPost(id);
if(post!=null)
{
PostViewModel vm=new PostViewModel { PostID=id };
vm.PostText=post.Name;
var comments=repo.GetCommentsForPost(id);
foreach(var item in comments)
{
vm.Comments.Add(new CommentViewModel { CommentID=item.Id,
AuthorDisplayName=item.Author.FirstName});
}
return View(vm);
}
return View("NotFound");
}
Now your view will be strongly typed to The PostViewModel
#model PostViewModel
<h2>#Model.PostText</h2>
#Html.Partial("Comments",Model.Comments)
And your partial view(Comments.cshtml) will be strongly typed to a collection of CommentViewModel
#model List<CommentViewModel>
#foreach(var item in Model)
{
<div>
#item.Text
<p>Written by #item.AuthorDisplayName</p>
</div>
}
Now our views are not depending directly to Domain models. This allows us to bring data from another source tomorrow if we need (Ex :Get comments from a web service) and simply map to our view model.
Some notes
Do not add too much of code to Views. Let's keep it pure HTML as much as possible. No data access calls directly from Views!
I manually mapped the domain model to viewmodel for your understanding. You may use a mapping library like Automapper to do so. Also you may move part of the code we have in the GET action method to another servier layer so that it can be reused in multiple places.

Eagerly Load Navigation Property that is List<OfSomeBaseClass>

Using EF Code First and given an Entity that contains a List, how can I eagerly load the entire object graph for that entity:
Example:
public class Foo
{
public int Id { get; set; }
public List<BarBase> Bars { get; set; }
}
public class BarBase
{
public int Id { get; set; }
public string Text { get; set; }
}
public class BarTypeA : BarBase
{
public List<Baz> Bazes { get; set; }
}
public class BarTypeB : BarBase
{
public List<Quux> Quuces { get; set; } { get; set; }
}
If BarBase were not a base class that could contain instances of several different subtypes, I could use
.Include("Bars").Include("Bars.Bazes")
If I try
.Include("BarBase").Include("BarBase.Bazes").Include("BarBase.Quuces")
I get the error
A specified Include path is not valid. The EntityType 'BarBase' does
not declare a navigation property with the name 'Bazes'.
But how do I handle the situation that Bars can contain different concrete types, and I want to eagerly load all of those instances including the List<T> contained in those concrete types?
This is reported problem in EF currently without a solution.

Display data from multiple models in one view

In the MVC 3 i want to display data from two models viz. Student and Enrollment into a single view.
Student model
public class Student
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int student_id { get; set; }
public string student_name { get; set; }
public string father { get; set; }
}
Enrollment model
public class Enrollment
{
[Key]
public int enrollment_id { get; set; }
public string rollno { get; set; }
public int student_id { get; set; }
public string registration_no { get; set; }
public date registration_date { get; set; }
}
My ViewModel looks like this
public class StudentEnrollmentViewModel
{
public Student_Info Student_Info { get; set; }
public Enrollment_Info Enrollment_Info { get; set; }
[Key]
public int ID { get; set; }
}
How do I retrieve the data from the two model and assign it to a viewmodel so that I can display it in a view? I am using Repository Design Pattern.
Generally speaking, a controller would be responsible for contacting the model, storing the result set returned in a variable/array/struc that the view would consume. The model and view components/classes would be registered in the controller.
An example:
<event-handler event="display.institutions" access="public">
<notify listener="userInstitutionRights" method="getInstitutionsWithDataRightsNOXML" resultKey="request.institutions" />
<view-page name="userNav" contentKey="request.userNav"/>
<view-page name="userInstitutions" contentKey="request.pageContent"/>
<announce event="assemblePage" />
</event-handler>
Event display.institutions is calling a model component userInstitutionRights and storing the result in a resultKey request.institutions and is including two view pages userNav, userInstitutions where the resultKey is available to each.
You can use DynamicPage, Look into following example
We need to use a Dynamic view page. (More Information)
Follow following steps:
Create DynamicViewPage type
public class DynamicViewPage : ViewPage
{
public new dynamic Model { get; private set; }
protected override void SetViewData(ViewDataDictionary viewData)
{
base.SetViewData(viewData);
Model = ViewData.Model;
}`
}
Your Controller will look like
public ActionResult Account(string returnUrl)
{
LoginModel loginmodel = null;//Initialize Model;
RegistrationModel registrationModel = null ;//Initialize Model;
// Any Extra logic
return View("Account", new
{
Login = loginmodel,
Register = registrationModel
});
}
your View should Inherit from
Inherits="DynamicViewPage"
Now #Model.Login will give you Loginmodel
#Model.Register will give you RegisterModel
It should work as you expected.........

Resources