如何从MVC中的表单中检索两个模型?

时间:2015-05-19 06:33:51

标签: asp.net-mvc

假设以下域模型。

public class SystemRequirement
{
   public int SystemRequirementID { get; set; }
   public Platforms Platform { get; set; }
   public string CPU { get; set; }
   public string RAM { get; set; }
   public string Dsiplay { get; set; }
   public string Discription { get; set; }

   public int GameID { get; set; }
   public virtual Game Game { get; set; }
}


public class Game
{
    public int GameID { get; set; }
    public string Name { get; set; }
    public Genres Genre { get; set; }
    public DateTime ReleaseDate { get; set; }
    public bool Multiplay { get; set; }
    public string About { get; set; }

    public virtual List<SystemRequirement> SystemRequirements { get; set; }
}

public class GameSystemViewModel
{
    public Game Game { get; set; }
    public SystemRequirement SystemRequirement { get; set; }
}

我想制作一个表格,允许添加一个包含其系统要求的新游戏。

enter image description here

&#13;
&#13;
@model KeyStore.WebUI.Models.GameSystemViewModel

@{
    ViewBag.Title = "Add";
    Layout = "~/Views/Shared/_AdminLayout.cshtml"; 
}


<div class="container">
    @using (Html.BeginForm("Add", "GameAdmin", FormMethod.Post, new { enctype = "multipart/form-data" }))
    {
        <div class="panel">
            <div class="panel-heading">
                <h3>Add New Game</h3>
            </div>

            <div class="panel-body">

                @Html.LabelFor(m => m.Game.Name)
                @Html.TextBoxFor(m => m.Game.Name)

                @Html.LabelFor(m => m.Game.Genre)
                @Html.TextBoxFor(m => m.Game.Genre)

                @Html.LabelFor(m => m.Game.ReleaseDate)
                @Html.TextBoxFor(m => m.Game.ReleaseDate)

                @Html.LabelFor(m => m.Game.Multiplay)
                @Html.CheckBoxFor(m => m.Game.Multiplay)

                @Html.LabelFor(m => m.Game.About)
                @Html.TextAreaFor(m => m.Game.About)


            </div>
        </div>

        <div class="panel">
            <div class="panel-heading">
                <h3>System Requirements</h3>
            </div>

            <div class="panel-body">

                @Html.LabelFor(m => m.SystemRequirement.Platform)
                @Html.TextBoxFor(m => m.SystemRequirement.Platform)

                @Html.LabelFor(m => m.SystemRequirement.CPU)
                @Html.TextBoxFor(m => m.SystemRequirement.CPU)

                @Html.LabelFor(m => m.SystemRequirement.RAM)
                @Html.TextBoxFor(m => m.SystemRequirement.RAM)

                @Html.LabelFor(m => m.SystemRequirement.Dsiplay)
                @Html.TextBoxFor(m => m.SystemRequirement.Dsiplay)


                @Html.LabelFor(m => m.SystemRequirement.Discription)
                @Html.TextAreaFor(m => m.SystemRequirement.Discription)


            </div>
        </div>

        <div class="panel-footer">
            <input type="submit" value="Save" class="btn btn-primary" />
        </div>

    }
</div>
&#13;
&#13;
&#13;

我的控制器类有这三个动作。

  1. 添加:制作游戏视图
  2. [HttpPost]添加:获取对象并使用linq将其保存在数据库中
  3. 控制器代码:

    &#13;
    &#13;
    public ViewResult Add()
    {
      GameSystemViewModel g = new GameSystemViewModel();
      g.Game = new Game();
      g.SystemRequirement = new SystemRequirement();
      return View(g);
    }
    
    
    [HttpPost]
    public ActionResult Add(GameSystemViewModel g)
    {
      Game mygame = new Game();
      mygame = g.Game;
      mygame.SystemRequirements.Add(g.SystemRequirement);
      gameRepository.Save(mygame);
      return RedirectToAction("Add");
    }
    &#13;
    &#13;
    &#13;

    但是在发布表单时会发生以下错误。正如您在Locals中看到的,SystemRequirement不是NULL。

    enter image description here

    问题是什么,我该如何解决?

1 个答案:

答案 0 :(得分:3)

您需要创建一个包含(SystemRequirement)和(Game)类的复合视图模型,如下所示:

public class CombinedViewModel{

public SystemRequirement { get; set; }
public Game { get; set; }

}

和您的控制人员:

public ViewResult Add(){
    CombinedViewModel MyModel = new CombinedViewModel();
    MyModel.SystemRequirement = new SystemRequirement();
    MyModel.Game = new Game();
    return View(MyModel);
}


    [HttpPost]
    public ActionResult Add(CombinedViewModel pModel){
        Game game = new Game();
        game = pModel.Game;
        game.SystemRequirements = new List<SystemRequirement>();
        game.SystemRequirements.Add(pModel.SystemRequirement);
        gameRepository.Save(game);
        return RedirectToAction("Add");
    }

视图将是:

@model CombinedViewModel

@{
    ViewBag.Title = "Add";
    Layout = "~/Views/Shared/_AdminLayout.cshtml"; }


<div class="container">
    @using (Html.BeginForm("Add", "GameAdmin", FormMethod.Post, new { enctype = "multipart/form-data" }))
    {
        <div class="panel">
            <div class="panel-heading">
                <h3>Add New Game</h3>
            </div>

            <div class="panel-body">

                @Html.LabelFor(m => m.Game.Name)
                @Html.TextBoxFor(m => m.Game.Name)

                @Html.LabelFor(m => m.Game.Genre)
                @Html.TextBoxFor(m => m.Game.Genre)

                @Html.LabelFor(m => m.Game.ReleaseDate)
                @Html.TextBoxFor(m => m.Game.ReleaseDate)

                @Html.LabelFor(m => m.Game.Multiplay)
                @Html.CheckBoxFor(m => m.Game.Multiplay)

                @Html.LabelFor(m => m.Game.About)
                @Html.TextAreaFor(m => m.Game.About)


            </div>
        </div>

        <div class="panel">
            <div class="panel-heading">
                <h3>System Requirements</h3>
            </div>

            <div class="panel-body">

                @Html.LabelFor(m => m.SystemRequirements.Platform)
                @Html.TextBoxFor(m => m.SystemRequirements.Platform)

                @Html.LabelFor(m => m.SystemRequirements.CPU)
                @Html.TextBoxFor(m => m.SystemRequirements.CPU)

                @Html.LabelFor(m => m.SystemRequirements.RAM)
                @Html.TextBoxFor(m => m.SystemRequirements.RAM)

                @Html.LabelFor(m => m.SystemRequirements.Dsiplay)
                @Html.TextBoxFor(m => m.SystemRequirements.Dsiplay)


                @Html.LabelFor(m => m.SystemRequirements.Discription)
                @Html.TextAreaFor(m => m.SystemRequirements.Discription)


            </div>
        </div>

        <div class="panel-footer">
            <input type="submit" value="Save" class="btn btn-primary" />
        </div>

    } </div>