Sam Street
Sam Street

Reputation: 306

Why is my model null?

Being new to c# I can't figure out the issue I am having. I have created a view and still, my model is null, what could be causing this?

Below is 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);
        }
    }
}

View:

@{
    ViewBag.Title = "Index";
    @model Prigmore2013_01.Models.GuessingGame
}
<h2>Guessing The Digits</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>
    <table>
        <tr>
            <td>Your Guess</td>
            <td>Spot On</td>
            <td>Near Miss</td>
        </tr>
        <!-- Need to loop here -->
        @if (Model != null)
        {
            for (var i = 0; i < Model.Guesses.Count(); i++)
            {
                foreach (var item in Model.Guesses)
                { 
            <tr>
                <td>@Html.DisplayFor(x => item.Digits)</td>
                <td>@Html.DisplayFor(x => item.RightDigitRightPosition)</td>
                <td>@Html.DisplayFor(x => item.RightDigitWrongPosition)</td>
            </tr>
                }
            }
        }
        else
        {
            <p>Fail - Model is null</p>
        }
    </table>

    <button type="submit" name="Submit">Submit</button>
</form>
<form action="Exercise09/StartNewGame" method="post">
    <button type="submit" name="Submit">New Game</button>
</form>

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 ViewResult Index()
        {
            return View("Index");
        }



        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 theGame = this.Session["GameState"] as GuessingGame;
            theGame.Target.Clear();
            var rand = new Random();

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


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

I think I am along the right lines but can't understand what is causing this problem? Would someone be able to link me to appropriate reading material for a further understanding so that I can prevent this in the future.

Upvotes: 0

Views: 1053

Answers (2)

Aaron Palmer
Aaron Palmer

Reputation: 8992

Your view is expecting:

@model Prigmore2013_01.Models.GuessingGame

But you are passing:

return View("Index", theGame.Guesses);

Either change your view to expect a List<Prigmore2013_01.Models.Guess>:

@model List<Prigmore2013_01.Models.Guess>

Or change your controller to send a Prigmore2013_01.Models.GuessingGame to the view:

return View("Index", theGame);

Based on your code it would seem more intuitive to change the return types of your controller methods to return the GuessingGame object.

Upvotes: 2

marteljn
marteljn

Reputation: 6516

Your model is GuessingGame and you are passing a List<Guess>. In your view change it to:

@model List<Prigmore2013_01.Models.Guess>

Also, on your Index action method you are not passing anything as a model to the view so that would also cause it to be null.

Bottom line, you either have to change your view to accept the proper type or change your controller action methods to pass the proper type.

Upvotes: 1

Related Questions