views:

348

answers:

6

I finished NerdDinner tutorial and now I'm playing a bit with project. Index page shows all upcoming dinners:

    public ActionResult Index()
    {
        var dinners = dinnerRepository.FindUpComingDinners().ToList();
        return View(dinners);
    }

In DinnerRepository class I have method FindAllDinners and I would like to add to above Index method number of all dinners, something like this:

    public ActionResult Index()
    {
        var dinners = dinnerRepository.FindUpComingDinners().ToList();
        var numberOfAllDinners = dinnerRepository.FindAllDinners().Count();
        return View(dinners, numberOfAllDinners);
    }

Of course, this doesn't work. As I'm pretty new to OOP I would need help with this one.

Thanks,
Ile

+10  A: 

Create view model:

public class DinnerViewModel
{
    public List<Dinner> Dinners { get; set; }
    public int NumberOfAllDinners { get; set; }
}

public ActionResult Index()
{
    var dinners = dinnerRepository.FindUpComingDinners().ToList();
    var numberOfAllDinners = dinnerRepository.FindAllDinners().Count();
    return View(new DinnerViewModel { Dinners = dinners, NumberOfAllDinners = numberOfAllDinners } );
}
LukLed
+3  A: 

You need to create a "wrapper" object that contains the objects you wish to pass as public properties of it. For instance, create an object called DinnerViewModel and give it two properties and set these with two properties, one a List called Dinners and one an int called DinnerCount. Then pass the DinnerViewModel to the view and you can then access Model.Dinners and Model.DinnerCount

Dan Diplo
A: 

Just simply use dinners.Count property instead.

Millionbonus
A: 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Ajax;
using Nerd.Model;
using Nerd.Models;

namespace Nerd.Controllers
{

    // ViewModel Classes
    public class DinnerViewModel
    {
        List<Dinner> Dinners { get; set; }
        int DinnerCount { get; set; }
    }

    public class DinnerController : Controller
    {
        private DinnerRepository dinnerRepository = new DinnerRepository();

        //
        // GET: /Dinner/

        public ActionResult Index()
    {
        var dinners = dinnerRepository.FindUpComingDinners().ToList();
        int dinnerCount = dinnerRepository.FindAllDinners().Count();

        return View(new DinnerViewModel {Dinners = dinners, DinnerCount = dinnerCount});
    }

       ...
    }
}

I tried this way but I get error that Dinners and DinnerCount are inaccessible. If I place public in front of them in DinnerViewModel this error disappears. Finally, I get this error:

The model item passed into the dictionary is of type 'Nerd.Controllers.DinnerViewModel' but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable`1[Nerd.Model.Dinner]'.

Index.aspx inherits this:

Inherits="System.Web.Mvc.ViewPage<IEnumerable<Nerd.Model.Dinner>>"

Where did I go wrong? Thanks for help!

ile
sorry for posting as answer but comment is character limited
ile
`public List<Dinner> Dinners { get; set; }`. Define Dinners and DinnerCount as public.
LukLed
@ile: You have to change view type to `Inherits="System.Web.Mvc.ViewPage<DinnerViewModel>"`.
LukLed
still don't know how to handle this error that appears in view: <br>he model item passed into the dictionary is of type 'Nerd.Controllers.DinnerViewModel' but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable`1[Nerd.Model.Dinner]'.
ile
still nothing... I changed inherits to this: Inherits="System.Web.Mvc.ViewPage<Nerd.Models.DinnerViewModel>", and now comes this error:<br>foreach statement cannot operate on variables of type 'Nerd.Models.DinnerViewModel' because 'Nerd.Models.DinnerViewModel' does not contain a public definition for 'GetEnumerator'
ile
if i try "System.Web.Mvc.ViewPage<IEnumerable<Nerd.Models.DinnerViewModel>>" than I have this error:<br>'Nerd.Models.DinnerViewModel' does not contain a definition for 'DinnerID' and no extension method 'DinnerID' accepting a first argument of type 'Nerd.Models.DinnerViewModel' could be found (are you missing a using directive or an assembly reference?)
ile
when trying to display results in View page I think this needs to be modified: ...<% foreach (var item in Model) { %>....
ile
@ile: You have to change it to: `<% foreach (var item in Model.Dinners) { %>`. Don't take this wrong, but you have to work on your C# skills a little more. They prevent you from using MVC properly.
LukLed
I'm aware of my bad knowledge of C# (I'm total beginner), but I got a task to learn asp.net mvc first, so this inverse type of learning makes it pretty hard task. Anyway, thanks a lot for helping!
ile
what you advised me to do also didn't help...
ile
What is you question now? The first question or the second one where you answered your own question with more code? Anyway, I think you are having a problem where your view expects a collection of Dinner objects (IEnumerable or List) but you keep sending a single Dinner object to it.In the View where you display a List of Dinners, you should have this System.Web.Mvc.ViewPage<IEnumerable<Nerd.Models.DinnerViewModel>>but in the View where you display the details of one single Dinner you should have this:System.Web.Mvc.ViewPage<Nerd.Models.DinnerViewModel>. HTH
mare
Yes, I have a problem with View file, at least I think so because there is no any error in back-end code. I didn't know that IEnumerable<> serves to display List of Dinners... well, this was helpful, I'll explore it later to see if it will finally solve my problem.Mare, thanks for comment!
ile
+1  A: 

In your case I would prefer the solution mentioned by LukLed.

In general you could of course also transfer multiple values from your controller to your view using ViewData:

ViewData["dinners"] = dinners;
ViewData["numberOfAllDinners"] = 150;
...

For more information also take a look at this link.

hkda150
Oh, I even read in book about this but I totally forgot about this ViewData :) Thanks!
ile
A: 

Guys, if you are talking about when you try to go to edit or create and you get this error, this should be the solution. I was encountering the same thing and this was a very easy fix. This is a little long, but it really is only a one line fix for each method. So, if the above dilemma was your issue, please continue to read and it might help you. Feel free to email me if you don't understand my wording


I figured it out. It seems as if everyone is trying to create or add elaborate methods to do fix an error that is extremely simple to fix. Remember, you start off using the ViewData inherts in you .aspx filesand returning the same in you return statements. Because of that, I figure that it was an issue with the Inherits attribute on the top of the ASP.NET files. But, if you are getting the error when trying to create or edit a new Dinner when you are on the 'Upcoming Dinners' page (generated from the Details.aspx and the LINQ file that gets all Dinners that are after todays date), go into your 'Controllers' directory, specifically the DinnerController.cs. Then look at the Edit and or Create methods. the answer lies right here. If you put breakpoints on these methods, you should be able to figure it out. If not, continue reading:

Look where it fails, the 'return...' line. Maybe I am the only person who forgot to change this, but my error is the same as people are getting in this page and this os how I fixed it.....the 'return(dinner)' line, in Create and Edit (and any others that you are having issues with), they are using the NerDinner.Model.Dinner / ViewData method. However, if you change it to the ViewModel return method instead, it should fix it, For example: 'return(new DinnerFormViewModel(dinner));', it should work for you. I hope this helps, as it was what my issue was. Just a simple overlook.

P.S. - I am not trying to insult anyone createing these extra methods. Maybe they are doing them for a reason. But if it is for an error that requires a logical fix, creating all of these new methods confuses the f@#$ out of me because I think that I should have done it that way and now I have to learn something new. So please, don't take any offense. It is just when you are trying to learn something new and you run into an error, and a hack is to write something new, it just turn my brain into marshmellow and I have to quit. But, of course your help is greatly appreciated:

-wrikgee

When angry, count ten; when very angry, a hundred - Thomas Jefferson

wrikgee