0
votes

I'm using MVC3 with EF 4.1 and trying to edit a model which has a drop down list which is the reference to a parent object. Here are the models:

public class Section
{
    public Guid SectionId { get; set; }
    public string Title { get; set; }
    public virtual ICollection<Article> Articles { get; set; } 
}

public class Article
{
    public Guid ArticleId { get; set; }
    public DateTime? DatePosted { get; set; }
    public string Title { get; set; }
    public string ArticleBody { get; set; }
    public Section Section { get; set; }        
}

Here's the controller action to render the GET part of the edit:

public ActionResult Edit(Guid id)
{
    Article article = db.Articles.Find(id);
    var sections = db.Sections.ToList();
    var secIndex = sections.IndexOf(article.Section);
    ViewBag.SectionId = new SelectList(sections, "SectionId", "Title", secIndex);            
    return View(article);
}

And the View

@model CollstreamWebsite.Models.Article

@using (Html.BeginForm()) {
    @Html.ValidationSummary(true)
    <fieldset>
        <legend>Article</legend>
        @Html.HiddenFor(model => model.ArticleId)

        <div class="editor-label">
            @Html.LabelFor(model => model.DatePosted)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.DatePosted)
            @Html.ValidationMessageFor(model => model.DatePosted)
        </div>

        ...

        <div class="editor-label">
            @Html.LabelFor(model => model.Section)
        </div>
        <div class="editor-field">
            @Html.DropDownList("SectionId")
        </div>

        <p>
            <input type="submit" value="Save" />
        </p>
    </fieldset>
}

And finally the POST action for the edit

[HttpPost]
public ActionResult Edit(Article article)
{
    if (ModelState.IsValid)
    {
        db.Entry(article).State = EntityState.Modified;
        db.SaveChanges();
        return RedirectToAction("Index");
    }
    return View(article);
}

The problem I have is that when the HttpPost Edit comes back, article.Section is null. How do I force the View to bind the Section to the article being edited.

Any help appreciated.

1

1 Answers

4
votes

Don't push your Model straight to your View. Use ViewModel instead.

Something like this:

ViewModel

public class EditArticleViewModel
{

    ///All the properties for your Article
    ///The SelectListItems for your Sections

    public List<SelectListItem> Sections{ get; set; }
    public String SelectedSection{ get; set; } 


}

Edit Get

[HttpGet]
public ActionResult Edit(Guid id)    
{

     EditArticleViewModel oEditArticleViewModel = new EditArticleViewModel();

     //Fill in the SelectLists
     List<SelectListItem> Sections= new List<SelectListItem>();
     Sections.Add(new SelectListItem() { Text = "TheSelectedSection", Value = SectionId.ToString(), Selected = true});     

     foreach(Section otherSection in AllPossibleSections)
     {
        Sections.Add(new SelectListItem() { Text = otherSection.Title, Value = otherSection.Id, Selected = false});
      }

      oEditArticleViewModel.Sections = Sections;


    return View(oEditArticleViewModel );
}

Your View

@Html.DropDownListFor(model => model.SelectedSection, Model.Sections)
//All other needed properties with their textboxes etc.

Edit Post

[HttpPost]
public ActionResult Register(EditArticleViewModel oPostedViewModel)
{
    if (ModelState.IsValid)
    {
       //Get the Article and fill in the new properties etc.
       //You can get the selectedSection from the SelectedSection Property, just cast it to a Guid.


        RedirectToAction("Index", "Home");
    }            

    //Something went wrong, redisplay the form for correction.
    //Make sure to fill in the SelectListItems again.
    return View(oPostedViewModel);
}

Hope it helps