Search code examples
c#asp.net-core-mvc

@foreach(var item in Model) is NullReferenceException


enter image description hereI am using ASP.NET Core MVC. I try to display text when I submit the form and get a reply.

I do manage to update the data to the database, but I want to display them on the browser.

When I try to do this I encounter a NullReferenceException error even though I have data in the database

This is my code - controller:

 public ActionResult CommentIndex()
    {
        return View();
    }

    [HttpPost]
    public ActionResult _CommentIndex(Comment comment, int id)
    {
        ModelState.Clear();
        _context.Add(comment);
        _context.Comments.Add(comment);
        _context.SaveChanges();

        List<Comment> commentList = _context.Comments.ToList();

        return PartialView(commentList);
    }

My partial view:

@model IEnumerable<PetShop.Data.Models.Comment>

  <div class="panel panel-primary">
        <div class="panel-heading">
           
        </div>
        <div class="panel-body">
            @if (Model != null || Model.Count() < 1)
            {
                using (Html.BeginForm("CommentIndex", "Category", FormMethod.Post))
                {
                    foreach (var item in Model)
                    {
                        <p>@item.Content</p>
                      
                    }
                }
            }
            else
            {
               <p>No results found</p>
            }
        </div>
    </div>

My view:

<div class="row">
    <div class="form-group">
        <div class="col-md-6">
            <form id="commentPartial">
                <label>Enter your comment</label>
                <input type="text" id="Content" name="Content" placeholder="Enter your comment" />
                <button type="submit" class="btn btn-primary">Post Comment</button>
            </form>
        </div>
    </div>
</div>
<div class="row">
    <div id="commentDisplay"></div>
</div>

ajax in view:

    @section scripts {
<script>
    $(document).ready(function () {
        $('#commentPartial').submit(function () {
            $.ajax({
                method: "POST",
                url: "/Category/CommentIndex",
                data: $(this).serialize(),
                success: function (result) {
                    $('#commentDisplay').html(result);
                }
            });
            return false;
        });
    });
</script>
}

My Model:

public class Comment
{
    public Comment() => Animal = new Animal();
    [Key]
    public int CommentId { get; set; }
    public int AnimalId { get; set; }
    public string Content { get; set; }

    [ForeignKey("AnimalId")]
    public virtual Animal Animal { get; set; }
}

Solution

  • As per your expectations assuming you are looking for something like below:

    Output

    enter image description here

    Controller Action For Initial Page

     public ActionResult CommentIndex()
            {
                return View();
            }
    

    View For Display Initial Page

    @{
    }
    <div class="row">
            <div class="form-group">
                <div class="col-md-6">
                    <form id="commentPartial">
                        <label>Enter your comment</label>
                        <input type="text" id="Content" name="Content" placeholder="Enter your comment" />
                        <button type="submit" class="btn btn-primary">Post Comment</button>
                    </form>
                </div>
            </div>
        </div>
        <div class="row">
            @*This is where your comment partial view will appear appear when user hits submit on our form*@
            <div id="commentDisplay"></div>
        </div>
    
    
    
    
        @section scripts {
        <script>
            $(document).ready(function () {
                //When the user hit the submit button we will post the form results to our partial view controller
                $('#commentPartial').submit(function () {
                    $.ajax({
                        method: "POST",
                        url: "/Controller/_CommentIndex",
                        data: $(this).serialize(),
                        success: function (result) {
                            //When then load our partial view into our containing div on the main page
                            $('#commentDisplay').html(result);
                        }
                    });
                    return false;
                });
            });
        </script>
        }
    

    Controller Action For Partial View

    [HttpPost]
    public ActionResult _CommentIndex([Bind("Content,AnimalId")] Comment comment, int id)
    {
        
        _context.Comments.Add(comment);
        _context.SaveChanges();
    
        List<Comment> commentList = _context.Comments.ToList();
    
        return PartialView(commentList);
    }
    

    Note: Feel free to implement your logic for ModelState.IsValid or any conditional you want according to your requirement.

    Model used in above controller

    public class Comment
        {
            public int CommentId { get; set; }
            public int AnimalId { get; set; }
            public string Content { get; set; }
        }
    

    Note: I am using on Content property for testing the scenario, feel free to modify as per your need.

    Partial View

    @model IEnumerable<DotNetMVCWebApp.Models.Comment>
    
        <div class="panel panel-primary">
                <div class="panel-heading">
                   
                </div>
                <div class="panel-body">
                    @if (Model != null || Model.Count() < 1)
                    {
                        using (Html.BeginForm("CommentIndex", "Home", FormMethod.Post))
                        {
                            foreach (var item in Model)
                            {
                                <p>@item.Content</p>
                              
                            }
                        }
                    }
                    else
                    {
                       <p>No results found</p>
                    }
                </div>
            </div>
    

    Note: While you would be creating this partial view remember to add Comment And add List kind of partial view.