3

I want to bind array from view to process it in controller method.

HTML generated

Model

public class Matrix
{
    public int[,] Numbers { get; set; }
}

View @model Project.Models.Matrix

@{
   var options = new AjaxOptions()
   {
    UpdateTargetId = "Matrix",
    };
}

@using (Ajax.BeginForm("Form", "Home", FormMethod.Post, options))
 {
 <div id="Matrix"> </div>
 <input type="submit" value="Rotate" name="ButtonType" />
  }

partial view

@model int[,]
@if (Model != null && Model.Length > 0)
{
<table id="numbers-container">
    @for (int column = 0; column < Model.GetLength(0); column++)
    {
        <tr>
            @for (int row = 0; row < Model.GetLength(1); row++)
            {
                var Numbers= Model[column, row];
                @Html.TextBoxFor(m => Numbers, new { id = $"{column}_{row}" })
            }
        </tr>
    }
</table>
 }

controller

   [HttpPost]
    public ActionResult SubmitForm(Matrix model, string ButtonType)

If I add some simple property ,it is filled in model, but array is null, MVC doesnot want to bind it because of ids and names in generated html are the same.How to change it to get filled array from form in controller? Need any help

1
  • Could you provide us with some sample model data, that you want to post, so we don't need to hardwire everything to reproduce? Commented May 6, 2019 at 11:17

2 Answers 2

1

The name of the property is Numbers in the Matrix class. But the html tag name is 'number' Which is not matching with the model's property. They have to match for default model binder to auto bind. The target property of the model should be one dimensional array.

You can change the codes as followings:

Model:

public class Matrix
{
    public int[] SelectedNumbers { get; set; }
    public int[,] Numbers { get; set; }
}

Cshtml:

@Html.TextBoxFor(m => Numbers, new { id = $"{column}_{row}", name="Numbers" })

In the controller you will get the selected values in model.Numbers

FYI - You should not have same Id assigned to multiple elements. You can have same name but different Ids. Assign the Id by concatenating the row number with the name.

Sign up to request clarification or add additional context in comments.

8 Comments

<input id="2_2" name="Numbers" type="text" value="48"> -I did changes in partial view and get reault in html - @Html.TextBoxFor(m => Numbers, new { id = $"{column}_{row}" }) but array is still empty in controller
That should work except the ajax data is not posted back by the form. I can see that you are setting the form data which is loaded with some ajax method. Can you share the html of the Matrix form? Where did you use the options object?
html of Matrix form is partial view, options are for partial view to build in after matrix being ready. Can be the problem that it is 2dimensional array?
That is also an issue. The posted values are suppose to be comma separated. e.g. 1,2,4 etc. You can have two properties in the Model. One can be two dimensional to render the html the other one is single dimensional. The name of the property which will receive the user input must match the name of the single dimensional property.
It is not clear for me about one more property.Can you provide code example?
|
1

I tried reproduce code, I changed mapping in cshtml file, It worked

In CS code

public class Matrix
    {
        public int[][] Numbers { get; set; }
    }

    public class MatrixController : Controller
    {
        // GET: Matrix
        public ActionResult Index()
        {

            int col = 2, row = 2;
            var matrix = new Matrix();
            matrix.Numbers = new int[col][];
            for (int i = 0; i < col; i++)
                matrix.Numbers[i] = new int[row];

            return View(matrix);
        }

        [HttpPost]
        public ActionResult SubmitForm(Matrix matrix, string ButtonType)
        {
            return null;
        }
    }

In cshtml

@model WebApplication1.Controllers.Matrix
@{
    var options = new AjaxOptions()
    {
        UpdateTargetId = "Matrix",
    };
}

@using (Ajax.BeginForm("SubmitForm", "Matrix", FormMethod.Post, options))
{
    <div id="Matrix">
        @if (Model != null && Model.Numbers.Length > 0)
        {
            <table id="numbers-container">
                @for (int column = 0; column < Model.Numbers.Length; column++)
                {
                    <tr>
                        @for (int row = 0; row < Model.Numbers[column].Length; row++)
                        {

                            @Html.EditorFor(x => Model.Numbers[column][row])
                        }
                    </tr>
                }
            </table>
        }
    </div>
    <input type="submit" value="Rotate" name="ButtonType" />
}

4 Comments

I have a rectangular array
You can set column = 5 row =3 for rectangular array
according to task it is n*n
not clear your requirement, if you want to n*n you can set column = n and row = n?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.