Posting ViewModel to MVC Controller - Still Cannot Get Working

Kmcnet 1,066 Reputation points
2023-05-04T02:26:19.4166667+00:00

Sorry to bother everyone again with this repost, but I am still having problems getting my code to work. Essentially, what I am trying to understand is how to post a ViewModel back to a controller and ultimately, log it to a database. The receiving controller will need to accept

public List<tbl_Log_ReviewOfSystems>

The Controller:


        [HttpPost]
        public IActionResult InsertReviewOfSystems(ReviewOfSystemsVM model)
        {

            return Content(model.ReviewOfSystems.Count.ToString());

        }

Posted data example:

EnteredBy: Someone

[0].ClientID: 1

[0].QuestionID: 8112

[0].CategoryCode: 1

[0].Category: General

[0].EnglishDescription: BMI

[0].QuestionResponse: None

[1].ClientID: 1

[1].QuestionID: 2092

[1].CategoryCode: 1

[1].Category: General

[1].EnglishDescription: BODYACHES

[1].QuestionResponse: None

Resulting in NullReferenceException: Object reference not set to an instance of an object.

Changing ViewModel to:

public List<tbl_Log_ReviewOfSystems>? ReviewOfSystems { get; set; } = new List<tbl_Log_ReviewOfSystems>() { };

returns 0. EnteredBy returns correct value in both scenarios. What am I doing wrong?

Developer technologies ASP.NET ASP.NET Core
Developer technologies ASP.NET Other
{count} votes

1 answer

Sort by: Most helpful
  1. AgaveJoe 30,126 Reputation points
    2023-05-04T10:36:32.7233333+00:00

    but I am still having problems getting my code to work. Essentially, what I am trying to understand is how to post a ViewModel back to a controller and ultimately, log it to a database. The receiving controller will need to accept

    The problem is due to not following the model binding naming convention. The data model example (post parameter names) maps to List<tbl_Log_ReviewOfSystems> not ReviewOfSystemsVM. The input names are missing "tbl_Log_ReviewOfSystems" in the post parameter names. Therefore the model binder is unable to map the parameter name to the model property name.

    The post parameters should have the naming convention below. As you can see, the parameter names are using the same "dot" syntax that C# uses.

    EnteredBy: Hello World
    tbl_Log_ReviewOfSystems[0].ClientID: 1
    tbl_Log_ReviewOfSystems[0].VisitID: 9999999
    tbl_Log_ReviewOfSystems[0].MRNumber: 5396
    tbl_Log_ReviewOfSystems[0].QuestionID: 8112
    tbl_Log_ReviewOfSystems[0].CategoryCode: 1
    tbl_Log_ReviewOfSystems[0].Category: General
    tbl_Log_ReviewOfSystems[0].EnglishDescription: BMI
    tbl_Log_ReviewOfSystems[0].QuestionResponse: None
    tbl_Log_ReviewOfSystems[1].ClientID: 1
    tbl_Log_ReviewOfSystems[1].VisitID: 9999999
    tbl_Log_ReviewOfSystems[1].MRNumber: 5396
    tbl_Log_ReviewOfSystems[1].QuestionID: 2092
    tbl_Log_ReviewOfSystems[1].CategoryCode: 1
    tbl_Log_ReviewOfSystems[1].Category: General
    tbl_Log_ReviewOfSystems[1].EnglishDescription: BODYACHES
    tbl_Log_ReviewOfSystems[1].QuestionResponse: None
    

    Unfortunately, you did not provide the code causing the problem. We have no idea how your code works and cannot provide an accurate solution.

    Example View.

    @model ReviewOfSystemsVM
    
    @{
        ViewData["Title"] = "Index";
    }
    
    <h1>Index</h1>
    
    <form method="post" action="/SystemReview/InsertReviewOfSystems1">
        @Html.TextBoxFor(model => model.EnteredBy)
        <table class="table">
            <thead>
                <tr>
                    <th>
                        @Html.LabelFor(model => Model.tbl_Log_ReviewOfSystems[0].ClientID)
                    </th>
                    <th>
                        @Html.LabelFor(model => Model.tbl_Log_ReviewOfSystems[0].VisitID)
                    </th>
                    <th>
                        @Html.LabelFor(model => Model.tbl_Log_ReviewOfSystems[0].MRNumber)
                    </th>
                    <th>
                        @Html.LabelFor(model => Model.tbl_Log_ReviewOfSystems[0].QuestionID)
                    </th>
                    <th>
                        @Html.LabelFor(model => Model.tbl_Log_ReviewOfSystems[0].CategoryCode)
                    </th>
                    <th>
                        @Html.LabelFor(model => Model.tbl_Log_ReviewOfSystems[0].Category)
                    </th>
                    <th>
                        @Html.LabelFor(model => Model.tbl_Log_ReviewOfSystems[0].EnglishDescription)
                    </th>
                    <th>
                        @Html.LabelFor(model => Model.tbl_Log_ReviewOfSystems[0].QuestionResponse)
                    </th>
                    <th>
                        @Html.LabelFor(model => Model.tbl_Log_ReviewOfSystems[0].DateEntered)
                    </th>
                    <th></th>
                </tr>
            </thead>
            <tbody>
                @for (var i = 0; i < Model.tbl_Log_ReviewOfSystems.Count; i++)
                {
                    <tr>
                        <td>
                            @Html.TextBoxFor(modelItem => Model.tbl_Log_ReviewOfSystems[i].ClientID)
                        </td>
                        <td>
                            @Html.TextBoxFor(modelItem => Model.tbl_Log_ReviewOfSystems[i].VisitID)
                        </td>
                        <td>
                            @Html.TextBoxFor(modelItem => Model.tbl_Log_ReviewOfSystems[i].MRNumber)
                        </td>
                        <td>
                            @Html.TextBoxFor(modelItem => Model.tbl_Log_ReviewOfSystems[i].QuestionID)
                        </td>
                        <td>
                            @Html.TextBoxFor(modelItem => Model.tbl_Log_ReviewOfSystems[i].CategoryCode)
                        </td>
                        <td>
                            @Html.TextBoxFor(modelItem => Model.tbl_Log_ReviewOfSystems[i].Category)
                        </td>
                        <td>
                            @Html.TextBoxFor(modelItem => Model.tbl_Log_ReviewOfSystems[i].EnglishDescription)
                        </td>
                        <td>
                            @Html.TextBoxFor(modelItem => Model.tbl_Log_ReviewOfSystems[i].QuestionResponse)
                        </td>
                        <td>
                            @Html.DisplayFor(modelItem => Model.tbl_Log_ReviewOfSystems[i].DateEntered)
                        </td>
                    </tr>
                }
            </tbody>
        </table>
        <div>
            <input type="submit" value="submit" />
        </div>
    </form>
    
    
    

    I want to point out that I provided an excellent blog that explains how the model binding naming convention works in your previous post. Please read the blog. There's is a lot of very good information that will help you move forward.

    https://www.learnrazorpages.com/razor-pages/model-binding

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.