1

I am new to asp.net mvc and am having some issues. What I am trying to do is display a div on the Index that allows a user to enter name and choose values from drop down lists. Then on "Generate Password" Hide the initial div and display a div "Hi 'UserName' you entered 'value1', 'value2'. Eventually what I want is to capture the UserName and use the value from the drop downs to create a random password (haven't started that module yet "ugh". What it will do is say Hello 'UserName' your new password is 'password'. and the password will contain the length that they have picked and the max num of alpha characters that they want. Every time I try I get the following error.

System.NullReferenceException was unhandled by user code

on this

 @Html.DropDownListFor(m => m.LenOfPass, Model.Lengths, "Please select...", new { @class = "form-control" })

[UPDATED CODE BASED ON @Haney's Response]

New code same error;

Controller;

using System;
using PassGen.Models;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.ComponentModel.DataAnnotations;


namespace PassGen.Controllers
{
public class HomeController : Controller
{

    private IEnumerable<int> GetLengths()
    {
        return new List<int>
        {
            8,10,15,20,25
        };
    }

    private IEnumerable<int> GetAlpha()
    {
        return new List<int>
        {
            1,2,3,4,5
        };
    }
    private IEnumerable<SelectListItem> GetLengthList(IEnumerable<int> elements)
    {
        var passLens = new List<SelectListItem>();
        foreach (var len in elements)
        {
            string lengths = Convert.ToString(len);
            passLens.Add(new SelectListItem { Value = lengths, Text = lengths });
        }
        return passLens;
    }
    private IEnumerable<SelectListItem> GetAlphaList(IEnumerable<int> element)
    {
        var alphaMax = new List<SelectListItem>();
        foreach (var alpha in element)
        {
            string alphas = Convert.ToString(alpha);
            alphaMax.Add(new SelectListItem { Value = alphas, Text = alphas });
        }
        return alphaMax;
    }

    [HttpGet]
    public ViewResult Index()
    {
        ViewBag.ShowDetails = false;
        var LenOfPass = GetLengths();
        var MaxOfAlpha = GetAlpha();
        var model = new PassGenerator();

        model.LenOfPass = new List<SelectListItem>(); // Note initialization of the property
        model.Lengths = GetLengthList(LenOfPass);
        model.Alphas = GetAlphaList(MaxOfAlpha);

        return View(model);
    }

    [HttpPost]
    public ActionResult Index(PassGenerator response)
    {
        ViewBag.ShowDetails = false; 
        if (ModelState.IsValid)
        {
            ViewBag.ShowDetails = true;

            ViewBag.UserName = response.UserName;
            ViewBag.PassLength = response.LenOfPass;
            ViewBag.AlphaMax = response.MaxOfAlpha;

            return PartialView ("Index",response);

        }
        else
        {
            //There is a validation error
            return View();
        }

    }
  }
}

Model;

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Security;
using System.Security.Cryptography;
using System.ComponentModel.DataAnnotations;
using System.Text;

namespace PassGen.Models
{
public class PassGenerator
{
    [Required(ErrorMessage = "Please enter your name!")]
    public string UserName { get; set; }

    //This property will hold Length of password chosen by User.
    [Required(ErrorMessage = "Please choose a length for your password!")]
    public int LenOfPass { get; set; }

    //This will hold Lengths for selection
    public IEnumerable<SelectListItem> Lengths { get; set;}

    //This property will hold Maximum number of Alphanumeric characters chosen by User.
    [Required(ErrorMessage = "Please choose the maximum number of alphanumeric characters that you want included!")]
    public int MaxOfAlpha { get; set; }

    //This will hold values for Max Alphanumeric.
    public IEnumerable<SelectListItem> Alphas { get; set;}

    //This property will hold the Random Password that is generated
    public string RandPass { get; set;}

  }
}

Index not changed, please excuse me for being a newbie on this. Index:

@model PassGen.Models.PassGenerator

@{
Layout = null;
}

<!DOCTYPE html>

<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
<script src="~/Scripts/jquery-2.1.1.min.js" type="text/javascript"></script>
</head>
<body>
<div class="inital-form">
    @using (Html.BeginForm()) { 
        @Html.ValidationSummary()
        <p>Your Name: @Html.TextBoxFor(x => x.UserName)</p>
        <p>Please choose the length of your password:
            @Html.DropDownListFor(m => m.LenOfPass, Model.Lengths, "Please select...", new { @class = "form-control" })
        </p>
        <p>Please choose the Maximum number of Alphanumeric characters you would like included:
            @Html.DropDownListFor(m => m.MaxOfAlpha, Model.Alphas, "Please select...", new { @class = "form-control" }) 
        </p>
        <input type="submit" value="Generate Your Password" />
    }
</div>
@if (ViewBag.ShowDetails) { 
<div class="response-section">
    <h1>Hello @Html.DisplayFor(m => m.UserName)</h1>
    <p>You have entered the following information;</p>
    <ul>
        <li>Your requested length for your password: @Html.DisplayFor(m => m.LenOfPass)</li>
        <li>Maximum number of Alphanumeric Characters required: @Html.DisplayFor(m => m.MaxOfAlpha)</li>
    </ul>
</div>
}
</body>
</html>
Cœur
  • 37,241
  • 25
  • 195
  • 267
daspixl
  • 13
  • 3
  • You still have this: model.LenOfPass = new List(). This property on your model is an int, not a List. – Matt M Dec 23 '14 at 20:37
  • @MattyM I still don't understand. are you saying that I should change the model code to public List LenOfPass { get; set; }? I have tried that and now I get. An exception of type 'System.NullReferenceException' occurred in App_Web_ncrwhue0.dll but was not handled in user code Additional information: Object reference not set to an instance of an object. – daspixl Dec 23 '14 at 21:14
  • Almost all cases of `NullReferenceException` are the same. Please see "[What is a NullReferenceException in .NET?](http://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-in-net)" for some hints. – John Saunders Dec 23 '14 at 21:36
  • @topdawg25 No, keep it an int, but remove the line I referenced above from your controller GET method. – Matt M Dec 24 '14 at 02:53
  • @MattyM, I have modified the code as seen above and now I get, The ViewData item that has the key 'LenOfPass' is of type 'System.Int32' but must be of type 'IEnumerable'. So sorry for not understanding. – daspixl Dec 24 '14 at 13:39
  • @topdawg25 That's because in your POST action, you're returning the "Index" view, but your model (response) is missing the Legnths and Alphas properties. Add this to your POST (just before your return statement) and it should give what you're looking for: var LenOfPass = GetLengths(); var MaxOfAlpha = GetAlpha(); response.Lengths = GetLengthList(LenOfPass); response.Alphas = GetAlphaList(MaxOfAlpha); – Matt M Dec 24 '14 at 14:22

1 Answers1

1

You never initialize the property LenOfPass on your PassGenerator instance, so it remains null. Then, when referencing it in the View, a NullReferenceException is thrown. Alternative for your controller:

public ViewResult Index()
{
    ViewBag.ShowDetails = false;
    var LenOfPass = GetLengths();
    var MaxOfAlpha = GetAlpha();
    var model = new PassGenerator();
    model.LenOfPass = new List<SelectListItem>(); // Note initialization of the property

    model.Lengths = GetLengthList(LenOfPass);
    model.Alphas = GetAlphaList(MaxOfAlpha);


    return View(model);
}

In most programming languages and C# for certain, trying to reference a null variable, field, or property will cause a NullReferenceException.

Also of note: in general a select list will result in a single value. LenOfPass thus should not be IEnumerable<SelectListItem> and instead be string, int, or whatever type you expect the value to be set to.

public int LenOfPass { get; set; }

This will not cause an exception because int is a struct AKA value type and cannot be null.

Haney
  • 32,775
  • 8
  • 59
  • 68
  • Wouldn't LenOfPass need to be a single value (int), not a List, since I would think you'll want this bound to a single value selected from the list of options held in model.Lengths? – Matt M Dec 23 '14 at 19:07
  • @MattyM yeah I realized that shortly after initially writing my answer. Please see my updated answer. – Haney Dec 23 '14 at 19:08
  • If I try your code @Haney I get the following error.Error 1 Cannot implicitly convert type 'System.Collections.Generic.List' to 'int' – daspixl Dec 23 '14 at 19:22
  • @topdawg25 you need to adjust for the `int` value everywhere... View, Controller, Model. That is a compile-time error. – Haney Dec 23 '14 at 19:42
  • @Haney please see the updated code above, still not working. – daspixl Dec 23 '14 at 20:12
  • @topdawg25 you must listen to the IDE (Visual Studio). It's giving you a compile time error to fix. At this point your issue is with misunderstanding code fundamentally, which is OK (everybody has to learn!). However, I cannot fill in the blanks for you. You must experiment and learn. :) – Haney Dec 23 '14 at 20:17