locked
Model object becomes null in the POST of ActionMethod in ASP.NET MVC. Please help RRS feed

  • Question

  • User1094269964 posted

    HI Team,

    I am totally new to ASP.NET MVC. Doing a small project and ran into the below issue.

    Issue 1: The code : @Html.LabelFor(Model => Model.Users[i].UserName) is not binding the values

    Issue 2: Lets say using button click and jquey I will add more rows and it should also added to the list and should be availble in the httpost

    Issue 3: When I click on Save button the ViewModel becomes null in the public ActionResult Index(FormCollection col, SampleViewModel viewModel) method

    How to resolve all the above issue,. Please help

    Below is the complete code

    namespace StronglyTypedModelViewDemo.Models
    {

    public class User
    {
    public string AppName { get; set; }
    public string UserName { get; set; }
    public string Comment { get; set; }
    }
    public class SampleViewModel
    {
    public List<User> Users { get; set; }
    }
    }

    -----

    public class SampleController : Controller
    {
    // GET: Sample
    public ActionResult Index()
    {
    SampleViewModel viewModel = new SampleViewModel();
    viewModel.Users = new List<User>();
    viewModel.Users.Add(new User() { UserName = "User1", AppName = "App1", Comment = "Comment1" });
    viewModel.Users.Add(new User() { UserName = "User2", AppName = "App2", Comment = "Comment2" });
    viewModel.Users.Add(new User() { UserName = "User3", AppName = "App3", Comment = "Comment3" });
    viewModel.Users.Add(new User() { UserName = "User4", AppName = "App4", Comment = "Comment4" });
    return View(viewModel);
    }

    [HttpPost]
    public ActionResult Index(FormCollection col, SampleViewModel viewModel)
    {
    return View();
    }
    }

    ----

    View 

    @model StronglyTypedModelViewDemo.Models.SampleViewModel

    @{
    ViewBag.Title = "Index";
    }

    <h2>Index</h2>

    @using (Html.BeginForm("Index", "Sample", FormMethod.Post))
    {
    <div class=" form-group">
    <div class="col-xs-4">
    <table class="table table-condensed" id="table1">
    <thead>
    <tr>
    <th scope="col">UserName</th>
    <th scope="col">AppName</th>
    <th scope="col">Comment</th>
    </tr>
    </thead>
    <tbody>
    @for (int i = 0; i < Model.Users.Count; i++)
    {
    <tr>
    <td>
    @Html.LabelFor(Model => Model.Users[i].UserName)
    </td>
    <td>
    @Html.LabelFor(Model => Model.Users[i].AppName)
    </td>
    <td>
    @Html.LabelFor(Model => Model.Users[i].Comment)
    </td>
    </tr>
    }
    </tbody>
    </table>
    </div>

    <div class=" form-group">
    <button type="submit" class="btn btn-default" name="btn-save" id="btn-save">
    <span>Add More rows by Javascript or Jquery or anyotherways</span>
    </button>
    </div>

    <div class="form-group">
    <hr class="hr-default"/>
    </div>
    <div class=" form-group">
    <button type="submit" class="btn btn-default" name="btn-save" id="btn-save">
    <span>Save</span>
    </button>
    </div>
    </div>
    }

    Tuesday, June 16, 2020 8:18 PM

Answers

  • User1094269964 posted

    Super.

    Thank You

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, June 17, 2020 8:58 AM

All replies

  • User-474980206 posted

    labels don't post back data. only named and enabled  input, select and textarea's  post back data. you will need to copy the data to hidden fields if you want it posted. also when jquery adds a form field, the name must be the proper binding syntax. 

     

    Tuesday, June 16, 2020 9:58 PM
  • User1094269964 posted

    Understood. Thanks for your response. I totally forgot the Label wont do data post.

    how can  i use foreach loop intead of for loop like below one. I am interested in foreach loop

    @for (int i = 0; i < Model.Users.Count; i++)
    {
    <tr>
    <td>
    @Html.LabelFor(Model => Model.Users[i].UserName)
    </td>
    <td>
    @Html.LabelFor(Model => Model.Users[i].AppName)
    </td>
    <td>
    @Html.LabelFor(Model => Model.Users[i].Comment)
    </td>
    </tr>
    }

    Wednesday, June 17, 2020 7:32 AM
  • User1686398519 posted

    Hi,bsurendiran

    According to your needs, I made an example, please refer to it.

    • For testing, I connected to the database.
    • For your first question, you can use "DisplayTextFor".And I used "foreach" in the example, you can refer to it.
    • For your second question, I used jquery and modal in the example.
    • For the third question, you can, I use ajax to submit.

    Controller

        public class SampleController : Controller
        {
            public MVCTestContext db = new MVCTestContext();
            public ActionResult Index()
            {
                SampleViewModel viewModel = new SampleViewModel();
                viewModel.Users = db.Users.ToList();
                return View(viewModel);
            }
            [HttpPost]
            public ActionResult Index(List<User> userlist)
            {
                if (userlist != null)
                {
                    userlist.ForEach(u =>
                    {
                        db.Users.Add(u);
                        db.SaveChanges();
                    });
                }
                return Json(new {Message="success"},JsonRequestBehavior.AllowGet);
            }
        }

    Index

    @model MVCTest.Models.SampleViewModel
    @using MVCTest.Models
    @{
        ViewBag.Title = "Index";
    }
    <h2>Index</h2>
    @{ 
        var user = new User();
    }
    <div class=" form-group">
        <div class="col-xs-4">
            <table class="table table-condensed" id="table1">
                <thead>
                    <tr>
                        <th scope="col">UserName</th>
                        <th scope="col">AppName</th>
                        <th scope="col">Comment</th>
                    </tr>
                </thead>
                <tbody>
                    @foreach (var item in Model.Users)
    {
    <tr>
    <td>
    @Html.DisplayTextFor(model=>item.UserName)
    </td>
    <td>
    @Html.DisplayTextFor(model => item.AppName)
    </td>
    <td>
    @Html.DisplayTextFor(model => item.Comment)
    </td>
    </tr>
    } </tbody> </table> </div> <div id="AddModal" class="modal fade" tabindex="-1" role="dialog"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button> <h4 class="modal-title">ADD</h4> </div> <div class="modal-body"> <div> <div class="col-xs-3"> @Html.DisplayNameFor(usermodel => user.UserName) @Html.TextBoxFor(usermodel => user.UserName, new { @class = "form-control" }) </div> <div class="col-xs-3"> @Html.DisplayNameFor(usermodel => user.AppName) @Html.TextBoxFor(usermodel => user.AppName, new { @class = "form-control" }) </div> <div class="col-xs-3"> @Html.DisplayNameFor(usermodel => user.Comment) @Html.TextBoxFor(usermodel => user.Comment, new { @class = "form-control" }) </div> <div class="col-xs-3"> <br /> <button id="singleAdd"><i class="glyphicon glyphicon-plus"></i></button> </div> </div> <div> <table class="table table-condensed" id="table2"> <thead> </thead> <tbody> </tbody> </table> </div> </div> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">Close</button> <button type="submit" class="btn btn-primary" name="btn-save" id="btn-save">Save</button> </div> </div> </div> </div> <div class="col-xs-8"> <div class=" form-group col-xs-12"> <button id="AddButton" type="button" class="btn btn-default" name="btn-save"> <span>Add More rows by Javascript or Jquery or anyotherways</span> </button> </div> </div> </div> @section scripts{ <script> var count = 0; $("#AddButton").click(function () { $("#AddModal").modal('show'); }); $("#singleAdd").click(function () { if (count == 0) { var $tr0 = $('<tr><th scope="col"> UserName</th><th scope="col">AppName</th><th scope="col">Comment</th></tr>'); $tr0.appendTo('#table2 thead'); } var $tr = $('<tr class="info"></tr>'); var $td1 = $('<td> '+ $("#user_UserName").val() + '</td>'); $td1.appendTo($tr); var $td2 = $('<td>' + $("#user_AppName").val() + '</td>'); $td2.appendTo($tr); var $td3 = $('<td>' + $("#user_Comment").val() + '</td>'); $td3.appendTo($tr); count++; $tr.appendTo('#table2 tbody'); }); $('#btn-save').click(function(){ var addTableArray = []; $('#table2 tbody tr[class="info"]').each(function () { var tds = $(this).find('td'); var userdata = { UserName: $(tds[0]).html(), AppName: $(tds[1]).html(), Comment: $(tds[2]).html() } addTableArray.push(userdata); }); $.ajax({ type: 'POST', url: '@Url.Action("Index", "Sample")', dataType: 'json', contentType: 'application/json; charset=utf-8', data: JSON.stringify(addTableArray), success: function () { window.location.href = '@Url.Action("Index", "Sample")'; } }); }); </script> }

    Here is the result.

     

    Best Regards,

    YihuiSun

    Wednesday, June 17, 2020 7:55 AM
  • User1094269964 posted

    Super.

    Thank You

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, June 17, 2020 8:58 AM