Sam Street
Sam Street

Reputation: 306

Accessing Controller Method From View

I am new to C# and MVC, I am in the process of creating a guessing game in order to learn the skills required to create an MVC product. I have the View made and I can submit guesses to my Controller no problem. I wish to now see all the previous guesses the user has submitted but can't figure out what the issue is.

My View:

@model Prigmore2013_01.Models.GuessingGame

@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>
<h2>Guessing Game</h2>
<p>Insert your 3 guesses into the textboxes below</p>
<form action="Exercise09/GuessTheDigits" method="post">
    <label for="guesses">Guess 1: @Html.TextBoxFor(x => x.Guesses[0], new { style = "width:12px", MaxLength = "1" }) Guess 2: @Html.TextBoxFor(x => x.Guesses[1], new { style = "width:12px", MaxLength = "1" }) Guess 3: @Html.TextBoxFor(x => x.Guesses[2], new { style = "width:12px", MaxLength = "1" })</label>
    <br />

    <label for="pastGuesses">Your Previous Guesses</label>
    <!-- Need to loop guesses -->

    <!-- End looping guesses -->
    <br />
    <button type="submit" name="Submit">Submit</button>
</form>
<form action="Exercise09/StartNewGame" method="post">
    <button type="submit" name="Submit">New Game</button>
</form>

My Controller:

using Prigmore2013_01.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace Prigmore2013_01.Tests
{
    public class Exercise09Controller : Controller
    {
        //
        // GET: /Exercise09/

        public ActionResult Index()
        {
            return View();
        }

        public ViewResult ShowPreviousGuesses()
        {
            if (HttpContext.Session["GameState"] == null)
            {
                HttpContext.Session["GameState"] = new GuessingGame();
            }

            GuessingGame theGame = this.Session["GameState"] as GuessingGame;
            return View("Index", theGame.Guesses);
        }

        public ViewResult ShowGuessesMade()
        {
            return View();
        }

        public ActionResult GuessTheDigits(List<int> guesses)
        {
            if (HttpContext.Session["GameState"] == null)
            {
                HttpContext.Session["GameState"] = new GuessingGame();
            }

            GuessingGame theGame = this.Session["GameState"] as GuessingGame;

            theGame.GuessTheHiddenDigits(guesses);

            return RedirectToAction("Index", theGame.Guesses);
        }

        public RedirectToRouteResult StartNewGame()
        {
            GuessingGame newTarget = this.Session["GameState"] as GuessingGame;
            newTarget.Target.Clear();
            var rand = new Random();

            for (int i = 0; i < 3; i++)
            {
                if(!newTarget.Target.Contains(rand.Next(1, 10)))
                {
                    newTarget.Target.Add(rand.Next(1, 10));
                }
            }

            return RedirectToRoute(new
            {
                controller = "Exercise09",
                action = "Index"
            });
        }
    }
}

My Model:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace Prigmore2013_01.Models
{
    public class GuessingGame
    {
        private Random _random;

        public GuessingGame()
        {
            this._random = new Random();
            this.Guesses = new List<Guess>();
            this.Target = new List<int>(){ 1, 2, 3 };
        }

        public List<int> Target { get; set; }
        public List<Guess> Guesses { get; set; }

        public List<Guess> ShowGuessesMade()
        {
            return Guesses;
        }
        public void NewGame()
        {
            this.Target.Clear();
            var count = 4;
            for (var i = 1; i < count; i++)
            {
                var swap = _random.Next(1, 9);

                if (!this.Target.Contains(swap))
                {
                    this.Target.Add(swap);
                }
            }
        }
        public void GuessTheHiddenDigits(List<int> guesses)
        {
            Guess g = new Guess() { Digits = guesses };
            //compare the lists
            var list = this.Target;
            var list2 = g.Digits;

            for (int i = 0; i < list.Count; i++)
            {
                if (list[i] == list2[i])
                {
                    g.RightDigitRightPosition++;
                }
            }
            //Now calculate how many digits in guesses are just plain wrong
            List<int> result = g.Digits.Except(this.Target).ToList();
            g.RightDigitWrongPosition = g.Digits.Count - result.Count - g.RightDigitRightPosition;

            //handle duplicates
            if (list.Count != list2.Distinct().Count())
            {
                // set thet right digit wrong position
                for (int i = 0; i < list2.Distinct().Count(); i++)
                {
                    g.RightDigitWrongPosition = i;
                }
            }
            this.Guesses.Add(g);
        }
    }
}

Previous attempts:

Previously I have tried the following; foreach and for loop: The following doesn't loop and causes a runtime error saying that Object reference not set to an instance of an object.

@if(Model.Guesses != null)
    {
        foreach(var item in Model.Guesses)
        {
            Html.DisplayFor(x => x.Guesses.Count());
        }
    }

When I attempt the next for loop the var i = 0 causes an error saying Object reference not set to an instance of an object.

for(var i = 0; i < Model.Guesses.Count(); i++)
{
    Html.DisplayFor(x => x.Guesses.Count())
}

How will I be able to view the previous guesses a user has made by displaying them on my View?

Upvotes: 0

Views: 92

Answers (1)

Andrei
Andrei

Reputation: 56688

Since your view is strongly typed with Prigmore2013_01.Models.GuessingGame, you should pass correct object to the View method:

public ViewResult ShowPreviousGuesses()
{
    ...
    return View("Index", theGame);
}

With what you have now ASP.NET MVC was not able to convert Guesses list to the GuessingGame object, resulting the Model being null.

Upvotes: 1

Related Questions