Search code examples
asp.net-mvcasp.net-mvc-4razorasp.net-mvc-viewmodel

ASP.NET MVC View doesn't return the Child Objects of One-To-Many Relationship to the Controller Action


I have two classes with one-to-many relationship.

public class Article
{
  [Key]
  public virtual int Id { get; set; }
  public virtual string Title { get; set; }
  public virtual int SortOrder { get; set; }
  public virtual ArticleList ArticleList{ get; set; }
}

public class ArticleList 
{
    public ArticleList()
    {
        Articles = new List<Article>();
    }

    [Key]
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }

    public virtual ICollection<Article> Articles { get; set; }
 }

This is the controller get action. Here all the articles related to the ArticleList are loaded correctly.

        public ActionResult EditArticleList(int id)
    {
        ArticleList articleList = unitOfWork.ArticleListRepository.GetById(id);

        return View(articleList);
    }

This is the controller post action. Here when the view returns data, the articles related to the ArticleList are not returned inside the ArticleList object.

public ActionResult EditArticleList(ArticleList articleList)
{

}

This is the corresponding view.

@model Domain.Entities.ArticleList

@{
    Layout = null;
 }

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>EditArticleList</title>

</head>
<body>
    @using (Html.BeginForm())
    {   
         @Html.AntiForgeryToken()

    <div class="form-horizontal">
        <h4>ArticleList</h4>
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        @Html.HiddenFor(model => model.Id)

        <div class="form-group">
            @Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })
            </div>
        </div>

        @foreach (var p in Model.Articles)
        {
            <div>
                <h3>@p.Title</h3>
                <h4>@p.Created</h4>

                @Html.ActionLink(p.Title, "Edit", "AdminArticle", new { id = p.Id }, null)

            </div>
        }

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Save" class="btn btn-default" />
            </div>
        </div>
    </div>

    <div class="form-horizonthal">
        <div class="form-group">

            <input type="button" class="btn btn-default" id="btnsubmit" value="get Value" />
        </div>
    </div>
}

The problem is why the view doesn't return the Articles related to the ArticleList to the controller post action?


Solution

  • They are not supposed to be returned. The only data that you get back from the view is the data that is posted as a part of the form. In your form you have inputs for Id and Name - that is what posted, and nothing else.

    In fact, these related articles should not be posted, you should not be using the web page as a container for all of your objects and your state. You have the database for that. So the correct approach would be to load related articles again in your post action.