MVC 3模型提交表单

3
我正在尝试将我的模型提交给控制器,但是FormCollection中的结果并不是我期望的。
我从自定义XML服务中收到一个TeamModel的IEnumerable。每个TeamModel都包含一个字符串和一个布尔值。字符串是团队的名称,布尔值表示用户是否想将其插入到数据库中。
控制器:
public ActionResult ImportTeams()
    {
        var xmlService = new XmlSoccerService();
        const string league = "Scottish Premier League";

        var model = xmlService.GetAllTeamsByLeagueAndSeason(league, "1112");
        ViewBag.League = league; 
        return View("~/Views/Admin/Database/ImportTeams.cshtml", model);
    }

    [HttpPost]
    public ActionResult ImportTeams(FormCollection collection , string league)
    {
        return RedirectToAction("ImportTeams");
    }

TeamModel:

public class TeamModel
{
    public string Name { get; set; }
    public bool Import { get; set; }
}

视图:

@model IEnumerable<TopTipFootball.XmlSoccer.Models.TeamModel>

@{
    ViewBag.Title = "Import Teams";
}

<h2>Select the teams to import into: @ViewBag.League</h2>

@using (Html.BeginForm())
{
    var league = ViewBag.League;

    @Html.HiddenFor(l => league)

    foreach (var team in Model)
    {
        <div class="editor-field">
            @Html.EditorFor(model => team.Import)
            @Html.DisplayFor(m => team.Name)      
        </div>
    }
    <p>
        <input type="submit" value="Import teams" />
    </p>
}

视图渲染的HTML中的一个元素:

<input checked="checked" class="check-box" data-val="true" data-val-required="The Import field is required." id="team_Import" name="team.Import" type="checkbox" value="true" />
<input name="team.Import" type="hidden" value="false" />
        Aberdeen      

一些问题:

  1. 如何确保我在提交回控制器时获得一个TeamModel的IEnumerable?
  2. 我传递联赛回控制器的方式是否正确?(通过隐藏字段传递)
1个回答

3

尝试使用for循环进行循环,例如:

for(int i = 0; i < Model.Count; i++) 
{
   @Html.EditorFor(model => Model[i].Import)
   @Html.DisplayFor(m => Model[i].Name)  
}

我相信这应该创建像Model_0_Import等的ID和名称,希望这将使其正确绑定您的提交。
是的,我已经以这种方式使用了隐藏字段。 当然,我假设联赛已经正确发布,只是项目列表没有?
编辑:您可以始终沿用使用viewModel而不是使用viewBag和Model的组合的方法吗?
这里有一个可能提供一些帮助的解决方案?
public ActionResult ImportTeams()
{
    const string league = "Scottish Premier League";

    var viewModel = new LeagueTeamViewModel
    {
       League = league;
    }

    var xmlService = new XmlSoccerService();        
    var model = xmlService.GetAllTeamsByLeagueAndSeason(league, "1112");

    viewModel.Teams.AddRange(xmlService.GetAllTeamsByLeagueAndSeason(league, "1112").Select(p => new TeamViewModel
    {
       Name = p.Name,
       Import = p.Import
    };

    return View("ImportTeams", viewModel);
}

[HttpPost]
public ActionResult ImportTeams(LeagueTeamViewModel viewModel)
{
}

public class LeagueTeamViewModel 
{
   public string League { get; set; }

   private List<TeamViewModel> _teams = new List<TeamViewModel>();

   public List<TeamViewModel> Teams
   {
      get { return _teams; }
      set { _teams = value; }
   }
}

public class TeamViewModel
{
   [DisplayName("Name")]
   public string Name { get; set; |

   [DisplayName("Imported")]
   public string Import { get; set; |
}

而你的视图
@model IEnumerable<LeagueTeamViewModel>
@{
    ViewBag.Title = "Import Teams";
}

<h2>Select the teams to import into: @Model.League</h2>

@using (Html.BeginForm())
{
    @Html.HiddenFor(model => model.League)

    for(int i = 0; i < Model.Teams.Count; i++) 
    {
        <div class="editor-field">
            @Html.EditorFor(model => model.Teams[i].Import)
            @Html.HiddenFor(m => model.Teams[i].Name)      
        </div>
    }
    <p>
        <input type="submit" value="Import teams" />
    </p>
}

嘿,谢谢。是的,那很好用。我不得不改成List而不是IEnumerable,但这没问题。我还必须添加另一个隐藏字段来存储团队名称,因为DisplayFor只输出文本而不是表单字段。现在又出现了一个问题,现在模型在控制器中绑定后,联赛返回为空字符串。这正常吗?是其中之一吗? - ChrisO
1
你可以尝试使用@Html.Hidden("league", league),但如果你问我,这有点繁琐。 - dreza
我刚刚看到你在上面的答案中的编辑。肯定会选择使用视图模型的方式,似乎比使用ViewBag更清晰。非常感谢你的帮助。 - ChrisO
希望这对您有用。ViewModel并不总是完美的解决方案,但在适当的情况下可以派上用场。 - dreza

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接