首页 > 解决方案 > 通过 HTML BeginForm 传递列表和模型实例

问题描述

目前我正在学习asp.net mvc5时做一个项目。我的数据库中有一个多对多的关系,我正在研究一种解决方案,将某个表中的某些演员附加到另一个表中的电影。这是他们的模型。

public class Movie
{
    public Movie()
    {
        this.Actors = new HashSet<Actor>();
        this.Customers = new HashSet<Customer>();
    }

    public int Id { get; set; }
    [Required]
    public string Name { get; set; }
    [Required]
    public string Genre { get; set; }
    [Required]
    public DateTime ReleaseDate { get; set; }
    [Required]
    public DateTime AddDate { get; set; }
    public virtual ICollection<Actor> Actors { get; set; }
    public virtual ICollection<Customer> Customers { get; set; }

}
public class Actor
{
    public Actor()
    {
        this.Movies = new HashSet<Movie>();
    }
    public int id { get; set; }
    [Required]
    public string Name { get; set; }
    public virtual ICollection<Movie> Movies { get; set; }
    public DateTime BirthDate { get; set; }
}

所以我想出了一个想法,在 AddActors 页面上检查演员并将它们添加到所选电影中这是视图:

@model Movie_Rentals.ViewModels.AddActorViewModel
@{
    ViewBag.Title = "AddActors";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>Add Actors Form</h2>
@using (Html.BeginForm("SaveActors", "Movies"))
{
foreach (var a in Model.Actors)
{
    <ul>
        <input type="checkbox" name="addactors" value="@Model.Actors" />
            @Html.DisplayFor(modelItem => a.Name);
        <br />
    </ul>
}
@Html.HiddenFor(m => m.Movie)
<button type="submit" class="btn btn-primary">Save</button>
}

提交表单后,我们进入控制器

public ActionResult SaveActors(FormCollection formCollection)
    {
        var movieInDb = /*???*/;
        {
            foreach (/*var actor in formCollection*/)
            {
                movieInDb.Actors.Add(actor);
            }
            _context.SaveChanges();
        }
        return RedirectToAction("Details", "Movies", new { id = movieInDb.Id });

    }

问题是如何从传递给控制器​​的表单中获取电影和演员?是否有另一种方法可以将检查的演员列表和电影传递给控制器​​,而不是使用 HTML BeginForm?

UPD。我发现如果我使用 HTML BeginForm,数据将被链接,所以我没有将 FormCollection 传递给控制器​​,而是尝试传递电影和演员列表,看看它是否会对我有任何帮助。所以现在将结果保存到 Db 的控制器看起来像这样

public ActionResult SaveActors(List <Actor> actors, Movie movie)
    {
        foreach (var a in actors)
        {
            movie.Actors.Add(a);
        }
        _context.SaveChanges();

        return RedirectToAction("Details", "Movies", new { id = movie.Id });
    }

但我得到 System.NullReferenceException。列表似乎是空的。我也相信我实际上没有电影的实例。现在我真的被困在这里了。

标签: c#asp.net-mvcrazor-pageshtml.beginform

解决方案


您的复选框列表不会在发布时绑定回模型,您需要以这种方式构建它,以便它使用和索引,并且它应该按照您的意愿发布回您的控制器。

@using (Html.BeginForm("Index", "Home", FormMethod.Post))
{
    <ul>
    @for (int idx = 0; idx < Model.Actors.Count; idx++) {
        <li>
          @Html.HiddenFor(x=>Model.Actors[idx].ID)
          @Html.CheckBoxFor(x=>Model.Actors[idx].IsSelected)
          @Html.DisplayFor(x => Model.Actors[idx].Name)
           @Html.HiddenFor(x => Model.Actors[idx].HobbiesName)
        </li>

    }
    </ul>
    }

推荐阅读