Pass Custom View Object from Controller to View - c#

I have a simple problem. In my controller I take join of two tables and return like this:
data = ...
select new { Contacts = item, Applications = items, Answers = j }
This is working fine. I am getting what I want: e.g. 62 data objects with the attribues I want.
But in the view how do I access these set of data points?
simple #model dynamic is not working? There must be some way to do this.

The best way to do that is by creating a ViewModel which will contain all the attributes that you need to display in your view.
public class DataViewModel {
public Contacts {get;set}
public Application {get;set;}
public Answers {get;set;}
}
Create a list of your "DataViewModel"
List<DataViewModel> Datas = new List<DataViewModel>();
After doing that, you will have to assign the values of each element in your controller after getting them from your "data" variable that you created by simply using a foreach loop.
foreach (var instance of data) {
// Assign those values here
}
You'll have to pass the list of your data (ViewModel) to your view from your controller like this :
return View(Datas);
and to call the list of your ViewModel in your view like this :
#model IEnumerable<models.DataViewModel>

Create an 'umbrella' model like:
public DataModel
{
public Contacts contacts {get;set}
public Application applications {get;set;}
public Answers answers {get;set;}
}
On controller:
select new DataModel(){ Contacts = item, Applications = items, Answers = j }
And have on View:
#model DataModel

Class
public DataModel
{
public Contacts {get;set}
public Application {get;set;}
public Answers {get;set;}
}
Controller
DataModel model = new DataModel();
model.Contacts = items;
model.Application = item;
model.Answers= items;
return View(model);
View
#model DataModel
// will get all three tables data here
#Model.Contacts
#Model.Application
#Model.Answers

Related

How do I dynamically assign a value to an MVC grid based on the value from another column in the row

I have a dataset currently that has 4 columns for values lets call them odd_low, odd_high, and even_low, even_high and I want to have two columns in the grid (LOW and HIGH) and have the values set based on the value of another column which will simply be 'O' or 'E' - This column is named side
Here's a quick sample (right now the column is bound to the odd fields only)
columns.Add(model => model.ODD_LOW).Titled("Low House #").Sortable(sortable);
columns.Add(model => model.ODD_HIGH).Titled("High House #").Sortable(sortable);
columns.Add(model => model.SIDE).Titled("Side").Sortable(sortable);
My guess is that I'll need to accomplish this using a script, but I'm not sure how to dynamically access the rows and fields.
I don't see the need for a dynamic datagrid in the scenario you discribed.
When using MVC, it's a good practice to use a ViewModel object to represent data. This way, your controller is resposible for getting the data from your business / service layer and map the result to your ViewModel object.
Using this aproach you can create an object with your view's properties and just bind it to your gridview and other controlls.
Your ViewModel object would look like this:
public class MyViewModelItem {
public int LowHouse { get; set; }
public int HighHouse { get; set; }
public char Side { get; set; }
}
public class MyViewModel {
// Your other view's properties
public List<MyViewModelItem> List { get; set; }
}
And your controller like this:
public class MyController : Controller {
private readonly IMyService myService;
public MyController()
{
myService = new MyService(); // Consider Dependency Injection
}
public ActionResult Index() {
var data = myService.List();
var myModel = MapMyModel(data);
return View(myModel);
}
private MyViewModel MapMyModel(IEnumerable<YOUR_ENTITY> data) {
var myModel = new MyViewModel();
myModel.List = new List<MyViewModelItem>();
foreach (var item in data)
{
myModel.List.Add(new MyViewModelItem {
LowHouse = item.ODD_LOW,
HighHouse = item.ODD_HIGH,
Side = [your logic]
})
}
}
}
References:
Use ViewModels to manage data & organize code in ASP.NET MVC applications
ASP.NET MVC View Model Patterns

Passing multiple models to view [duplicate]

This question already has answers here:
The model item passed into the dictionary is of type .. but this dictionary requires a model item of type
(7 answers)
Closed 5 years ago.
I am developing an asp mvc 5 website. I have 3 models which are appointments, consultations and contacts. now i want to display all the details of these 3 models in a view called userdetails. What i have done so far
Created a view model
public class AllServices
{
public List<Contact> Contacts { get; set; }
public List<Appointment> Appointments { get; set; }
public List<Consultation> Consultations { get; set; }
}
Then created the controller action method
public ActionResult userdetails()
{
AllServices services = new AllServices();
services.Appointments = dbcontext.Appointments.ToList();
services.Consultations = dbcontext.Consultations.ToList();
services.Contacts = dbcontext.Contacts.ToList();
return View(services);
}
and in view i made
#model List<Astrology.ViewModels.AllServices>
....
#foreach(var item in Model)
{
#item.Appointments
}
but when i run the page iam getting an error like this
The model item passed into the dictionary is of type 'Astrology.ViewModels.AllServices', but this dictionary requires a model item of type 'System.Collections.Generic.List`1[Astrology.ViewModels.AllServices]'.
Can someone please help me with it. Iam stuck with this.
The error is telling you that you're only passing a single AllServices model when it expects a List of AllServices models. You need to either change the view to expect one model or put the single model into a list.
EDIT (adding code sample)
Change your Controller to something like this:
public ActionResult userdetails()
{
List<AllServices> lservices = new List<AllServices>();
AllServices services = new AllServices();
services.Appointments = dbcontext.Appointments.ToList();
services.Consultations = dbcontext.Consultations.ToList();
services.Contacts = dbcontext.Contacts.ToList();
lservices.Add(services);
return View(lservices);
}

MVC - how to send to the partial view ViewModel containing a list

I am the beginner in MVC and I have a web application, where in my controller I declare a list of objects (feedback from visitors) and then send it to the view, which displays it. It looks like this. Declaration:
public class TrekFeedbackItem
{
public string trekid { get; set; }
public string comment { get; set; }
public string author { get; set; }
public TrekFeedbackItem(string trekid, string comment, string author)
{ this.trekid = trekid;
this.comment = comment;
this.author = author;
}
}
And usage:
List<TrekFeedbackItem> feedbackList = new List<TrekFeedbackItem>
{
//constructor called, data entered into the list
}
return View(trekname, feedbackList);
However, now I need to pass also another list, lets call it relatedblogsList. As a first step, I decided to encapsulate my feedbackList into the ViewModel (and once it works, add another list of different objects.)
public class TrekViewModel
{
public List<TrekFeedbackItem> feedback { get; set; }
}
and fill the data like this:
TrekViewModel trek = new TrekViewModel();
trek.feedback = new List<TrekFeedbackItem>
{
//insert data here
};
return View(view, trek);
The problem is - how to send this model to the partial view and how to access it?
Thank a lot
You can pass data into the partial view like below
from the controller return this view:
return PartialView("_partial_viewname", trek);
then in the beginning of the partial view:
#model Models.TrekViewModel
after that you can use Model.feedback inside the partial view.
Set return type of your action controller to "PartialView" rather than "View".
return PartialView("_yourPartialViewName", yourObject);
In case, if application does not work as expected, build it and re-run it.

Domain Model Object to View Model Object in MVC

I want to use view model for displaying instead of domain model. I have got these view models classes:
public class ArticleDescriptionViewModel
{
public string Title { get; set; }
public DateTime DateCreated { get; set; }
}
public class HomePage
{
public List<ArticleDescriptionViewModel> Articles { get; set; }
}
In the domain model i have got:
public class ArticleDescription
{
public string Title { get; set; }
public DateTime DateCreated { get; set; }
}
And this service method:
public List<ArticleDescription> GetArticlesDescription()
{
var articleDescription= from a in _ctx.Articles
select new ArticleDescription
{ Title = a.Title, DateCreated = a.DateCreated };
return articleDescription.ToList();
}
in the controller i want to match my list inside of my view model class with the list returned by my domain model class.
public ActionResult Index()
{
HomePage HomePageInstance = new HomePage();
HomePageInstance.Articles = _repo.GetArticlesDescription();
return View(HomePageInstance);
}
I have got an error:
"Cannot implicitly convert type System.Collections.Generic.List (DBayonaCode.Domain.Services.Models.ArticleDescription)' to 'System.Collections.Generic.List(DBayonaCode.Models.ArticleDescriptionViewModel)'"
But these two classes are equivalent? I am doing something wrong. I appreciate your help?
ArticleDescription and ArticleDescriptionViewModel are two different types, so there's no implicit conversion between them. You need to map your Domain Model object to your View Model object, you can do that either manually or with a tool like AutoMapper.
You could write extension methods like these to do the mapping:
public static class Mappings
{
public static ArticleDescriptionViewModel ConvertToView(this ArticleDescription article)
{
// Mapping Code
// return new ArticleDescriptionViewModel { ... }
}
public static List<ArticleDescriptionViewModel> ConvertToViews(this List<ArticleDescription> articles)
{
List<ArticleDescriptionViewModel> articleViews = new List<ArticleDescriptionViewModel>();
foreach (ArticleDescription article in articles)
{
articleViews.Add(article.ConvertToView())
}
return articleViews;
}
}
While MVC default project template offer just one model folder, thus implicitly presenting the idea that models are one thing, in fact There are three types of data models potentially involved in an ASP.NET MVC application:
- Domain model objects will be passed from and to a middle tier services interfacing with databases.
- View Model objects are those that the Controller pass to the View.
- Input model objects are those that the default modelBinder or some custom modelBinder generates from the view, although in many cases the input models are the same view model objects.
Hope it helps.

Convert model to list before passing it to view

I got this model in my project:
public class ListOfProducts
{
public List<string> ProductNames { get; set; }
public List<string> ProductUrls { get; set; }
}
The way I pass it to my view is:
public ActionResult Index()
{
var listOfUrls = GetListOfHrefs(); //Methods for giving values
var listOfProductNames = GetListOfProductNames();//Methods for giving values
var model = new ListOfProducts {ProductUrls = listOfUrls, ProductNames = listOfProductNames, ProductGtin = listofGti};
return View(model);
}
I would like to pass my model to the view as a list in order to loop through it the way i Want...Can I convert my model to a list before passing it?
Tried model.Tolist() but the intellisense could no find the Tolist-Part
EDIT:
I really need to acess both properties in the same context..In this case the Artice
<article id="post-62" class="post-62 x-portfolio type-x-portfolio status-publish has-post-thumbnail hentry has-post-thumbnail x-portfolio-5e9a5c5e0b6c2e1342bfccc9cacb084f x-portfolio-3ce959340d6fed7ed4f041884b46387c">
<div class="entry-wrap cf">
<header class="entry-header">
<h2 class="entry-title entry-title-portfolio">
<p>#product</p>
</h2>
</header>
</div>
<p>#url</p>
<span class="visually-hidden"><span class="author vcard"><span class="fn">addiadmin</span></span><span class="entry-title">Gluten & Mjölkfri Raggmunk</span><time class="entry-date updated" datetime="2014-05-21T08:23:32+00:00">05.21.2014</time></span>
</article>
its the same to ask "I wanna send MyClass as list ...", this is a basic OOB(Object-oriented programming) concept question IMO..so send List{MyClass} , you are sending one object name ListOfProducts which contains 2 lists, do you mean List{ListOfProducts} ? you can attach any Model , any parameters to the View as you want to them , modify it(any Model /ViewBag.Something) to your needs as you please , you are the game ruler
return View(new List<ListOfProducts >{model});
ListOfProducts is an object with properties that are lists.
I think what you are wanting is
#model ListOfProducts
foreach (var item in Model.ProductNames)
{
....
foreach (var item in Model.ProductUrls )
{
....
EDIT: Following on from your comments, you could do this (but see comments at end)
#for (int i = 0; i < Model.ProductNames.Count; i++)
{
<article id="post-62"...
<div class="entry-...
<header class="entry...
<h2 class="entry-title...
<p>Model.ProductNames[i]</p>
</h2>
</header>
</div>
<p>Model.ProductUrls[i]</p>
....
</article>
}
but this will only work if both ProductNames and ProductUrls contain exactly the same number of elements, in which case perhaps you should re-think your model
public class Product
{
public string Name {get; set;}
public string Url {get; set;}
}
Then create a List<Product> in you `Index' action method and pass that to the view
You cannot currently convert ListOfProducts to a list as it's has nothing to do with a list. It's a new type which you have defined in your code.
if you want it to be a list, you should inherit from IEnumerable for example or ICollection and implement the required functions.
Actually, to implement IEnumerable, you need a property in ListOfProducts that will contain all your List<String> so you could iterate on that !
If I assume that each entry in the list ProductNames matches one entry in ProductUrls, then what your really after is a list of Products and the design is missing the 'Product' class.
Create a class like:
public class Product
{
public string Name {get;set;}
public string Url {get; set;}
}
Now replace your 'ListOfProducts' with:
List<Product>()
Now you have a list of products. Your class ListOfProducts is not required.

Categories