1

I want a text box, bound to an array, to post the form when its changed.

I was following this post to get it to work but the property on my model is always null. Why?

Model

public class TestModel
{
    public int[] MyInts;
}

Controller

public ActionResult Index(TestModel model)
{
    if (model.MyInts == null) // <-- Always true
    {
        model.MyInts = new int[] { 1, 2, 3, 4 };
    }
}

View

@model TestModel

@using (Html.BeginForm("Index", "Test", FormMethod.Post, new { id = "TestForm" }))
{
<table class="table">
  <thead>
    <tr>
        <th />
@for (int i = 0; i < Model.MyInts.Count(); i ++)
{
        <th>
            @Html.TextBoxFor(x => Model.MyInts[i],  new { onchange = "this.form.submit();" })
        </th>
}
TedTrippin
  • 3,525
  • 5
  • 28
  • 46
  • Can you show the input json which the Endpoint get called with. – Twenty Oct 01 '19 at 17:31
  • An index is a `Get` not a `Post` by default, you need to create another method to simulate a `Post` for the form. If you want the array to be bound by default, loose the null check and bind the contents to the `Get` with a `return View(Model)` – Greg Oct 01 '19 at 17:31
  • @greg Even though the same approach works in my other forms (where the model has no arrays) I gave your advice a go. I created another method, same signature but different name, to no avail. – TedTrippin Oct 01 '19 at 17:41
  • So, what exactly do you want it to do? Just update the array on change? – Greg Oct 01 '19 at 20:22

1 Answers1

0

Your MyInts in TestModel is declared as a field.

Instead it must be a public property with get and set.

Change it to:

public class TestModel
{
    public int[] MyInts { get; set; }
}

Furthermore, as mentionned in the comments, your controller must contain a GET and POST Index action method.

public class TestController : Controller
{
    public ActionResult Index()
    {
        var viewModel = new TestModel {
            MyInts = new [] { 1, 2, 3, 4 }
            };

        return View(viewModel);
    }

    [HttpPost()]
    public ActionResult Index(TestModel model)
    {
        if (model.MyInts == null) 
        {
            model.MyInts = new int[] { 1, 2, 3, 4 };
        }

        // ...

        return RedirectToAction("Index");
    }
}
pfx
  • 20,323
  • 43
  • 37
  • 57
  • Thank you, what a stupid thing for me to forget! FWIW, I haven't bothered with separate GET/POST methods, still works. – TedTrippin Oct 02 '19 at 18:07