Taylor Liss
Taylor Liss

Reputation: 593

Object reference not set when passing TextAreaFor to controller

The app is designed to allow the user to enter a an IP address for a local machine and and it will then return the HDD information for that machine. It starts out with a default value already in the TextAreaFor box and performs the query for that value. This part works with no problem. But when a user tries to enter in their own value and hit the Refresh button, it keeps coming up with the error Object reference not set to an instance of an object.

I'm not sure why this is happening. It seems to me that clicking the button submits a POST action, which should kick off the second method in the controller. The current model is then passed to the controller with the values in the TextAreaFor attached and the mainCode() method is run on the new values.

Edit: According to What is a NullReferenceException, and how do I fix it? I am pretty sure that I am returning an empty model from my controller. I just don't see how. The form field should be sending the controller everything contained in TextAreaFor so the model should not be empty.

Edit2: I did some testing and the model is getting returned alright, but the values from TextAreaFor are not. When the mainCode() tries to do some logic to startDrives.startingDrives, it can't because that variable is empty for some reason.

Model:

namespace RelengAdmin.Models
{
    public class DriveInfo
    {
        public class DriveHolder
        {
            public string startingDrives {get; set;}
        }

        public DriveHolder startDrives = new DriveHolder();

        public void mainCode()
        {
            /****Code to return the HDD size omitted****/
        }
    }
}

View:

@using (Html.BeginForm())
{
    <input type="submit" value="Refresh" />

    @Html.TextAreaFor(model => model.startDrives.startingDrives, new {@class = "HDDTextBox"})
}

Controller:

namespace RelengAdmin.Controllers
{
    public class HDDCheckerController : Controller
    {
        [HttpGet]
        public ActionResult Index()
        {
            DriveInfo myDrive = new DriveInfo();
            myDrive.startDrives.startingDrives = "148.136.148.53"

            myDrive.mainCode();
            return View(myDrive);
        }

        [HttpPost]
        public ActionResult Index(DriveInfo model)
        {
            model.mainCode();
            return View(model);
        }
    }
}

Upvotes: 1

Views: 407

Answers (2)

steve v
steve v

Reputation: 3540

The issue is that your model's startDrives property is not actually declared as a property with getters and setters, so the model binder won't bind to it. I was able to duplicate the issue locally, and solve it by declaring the startDrives as a property and initializing it in the constructor.

public class DriveInfo
{

   public class DriveHolder
   {
      public string startingDrives { get; set; }
   }


   public DriveHolder startDrives { get; set; }

   public DriveInfo()
   {
      startDrives = new DriveHolder();
   }

   public void mainCode()
   {
      /****Code to return the HDD size omitted****/
   }    
}

Upvotes: 4

Grizzly
Grizzly

Reputation: 5943

Your question is a bit unclear of where the model is actually null.. but I would assume that when you hit your button, it goes to the correct action, but there is nothing in model because you haven't passed any specific values..

so try this:

CSHTML

@using (Html.BeginForm())
{
    <input type="submit" value="Refresh" />

    @Html.TextArea("startingDrive", "148.136.148.53", new {@class = "HDDTextBox"})
}

Controller

[HttpPost]
public ActionResult Index(string startingDrive)
{
    DriveInfo searchThisDrive = new DriveInfo();

    searchThisDrive.startDrives.startingDrives = startingDrive;
    searchThisDrive.mainCode();

    return View(searchThisDrive);
}

Let me know if this helps!

Upvotes: 1

Related Questions