0

我有一个视图,其中有一个链接列表,每个链接都是公司设有办事处的区域。

每次我选择一个区域时,我都会得到一个进程列表。对于每个流程,我都会获得一个下拉列表,从中选择流程的所有者以及要选择的测试复选框列表。

在我的控制器中,我将 string[] OwnerId 作为下拉列表中选择的值。问题是,我从所有下拉列表中获取所有值,而不仅仅是那些被选中的值。我怎样才能得到我选择的那些?

这是我的看法

@using CTTModel
@using TestingTool.ViewModels
@model TestRunModel
@{
    ViewBag.Title = "Create";
}
<h2>
    Create</h2>
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
@using (Html.BeginForm())
{
    @Html.ValidationSummary(true)
    <fieldset>
        <legend>Regions</legend>
        @foreach (Region region in Model.Regions)
        {
            @Html.ActionLink(@region.Name, "Create", new { id = region.Id })<br />
        }

        <div class="editor-field">
            @foreach (ProcessModel process in Model.Processes)
            {
                <h1>@process.Name</h1>

                **List<User> users = ViewBag.Users;

                <select id="OwnerId" name="OwnerId" >

                    @foreach (User user in users)
                    {
                        <option value="@user.Id">@user.Name</option>
                    }

                </select>**  

                <table>
                    <tr>
                          @{
                    int cnt = 0;

                    foreach (TestModel testModel in process.Tests)
                    {
                        if (cnt++ % 3 == 0)
                        {
                                      @:  </tr> <tr> 
                                  }
                                  @: <td> 
                                  <input type="checkbox" 
                                         name="selectedTests" 
                                         value="@testModel.Id/@testModel.ProcessId/@testModel.RegionId" 
                                       @(Html.Raw(testModel.Active ? "checked=\"checked\"" : "")) />
                                  @testModel.Name @::  @testModel.Description
                                  @:</td>
                              }
                              @: </tr>
                          }
                </table>
            }
        </div>

        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>

    <fieldset>
        <legend>Test Screen</legend>
    </fieldset>   
}
<div>
    @Html.ActionLink("Back to List", "Index")
</div>

这是我的控制器。Create Post 什么也没做,我试图首先获得正确的值。

//
        // GET: /TestPreparation/Create

        public ActionResult Create(int id = 1)
        {
            TestRunModel testRunModel = new TestRunModel();

            foreach (Region region in _db.Regions)
            {
                testRunModel.Regions.Add(region);
            }

            TestRun testRun = _db.TestRuns.OrderByDescending(x => x.Id).First();

            foreach (TestRunProcessRegion region in testRun.GetProcessesForRegion(_db.Regions.Single(i => i.Id == id)))
            {
                ProcessModel process = new ProcessModel
                    {
                        Code        = region.ProcessRegion.Process.Code,
                        Description = region.ProcessRegion.Process.Description,
                        Name        = region.ProcessRegion.Process.Name,
                        Process     = region.ProcessRegion.Process.Id
                    };

                foreach (SubProcess subProcess in region.ProcessRegion.Process.SubProcesses)
                {
                    foreach (Risk risk in subProcess.Risks)
                    {
                        foreach (Test test in risk.Tests)
                        {
                            TestModel testModel = new TestModel
                                {
                                    Id = test.Id,
                                    Name = test.Name,
                                    Description = test.Description,
                                    ProcessId = region.ProcessRegion.Process.Id,
                                    RegionId = region.ProcessRegion.Id
                                };

                            process.Tests.Add(testModel);
                        }
                    }
                }

                testRunModel.Processes.Add(process);
            }


            var users = new List<User>();
            foreach (User user in _db.Users)
            {
                users.Add(new User
                {
                    Id = user.Id,
                    Name = user.Name,
                });
            }

            ViewBag.Users = users;

            return View(testRunModel);
        } 

        //
        // POST: /TestPreparation/Create

        [HttpPost]
        public ActionResult Create(string[] OwnerId, string[] selectedTests, string[] processes)
        {
            if (ModelState.IsValid)
            {
                //_db.TestRunStatus.Add(testrunstatus);
                //_db.SaveChanges();
                return RedirectToAction("Index");  
            }

            return View();
        }
4

1 回答 1

0

你没有得到任何数据的原因是你的 Post Action 的方法签名需要是

public ActionResult Create(string OwnerId ...) //preferably int depending on what OwnerId is

这是因为您只从下拉框中选择了一项。因此,如果您使用此签名而不是 string[],Model binder 会将所选值传递回您的操作。

说了这么多,还是更好的实践和“MVC方式”来使用,

Html.DropDownFor(x => x.UserID)它真的让事情变得更容易:)

这适用于所有 html 输入控件:

http://www.asp.net/mvc/tutorials/getting-started-with-aspnet-mvc3/cs/examineing-the-edit-methods-and-edit-view

更新

我认为最好的办法是在ProccessModel类中添加一个 OwnerID。因为ProccessModel看起来IEnumberable<ProccessModel> Processes包含在 ViewModel 中,您可以使用默认的 MVC 模型绑定器通过以下方式获取要绑定的模型。

Phil Haack 曾在博客上写过关于绑定到列表的文章:

http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx

改编自 Phil 的帖子,我认为您将不得不这样做:

<% for (int i = 0; i < Model.Processes.Count; i++) { %>

  <%: Html.SelectListFor(model => model.Processes[i].OwnerID, (IEnumerable<SelectListItem>)ViewBag.Users) %> 
<% } %>

将 ViewBag.User 更改为:

 var users = _db.Users.Select(x => new SelectListItem(){
                                   text = x.Name, 
                                   value = x.Value
                              });

修改发布操作:

[HttpPost]
public ActionResult Create(TestRunModel model)
{
    foreach(var process in model.Porcesses)
   {
      process.OwnerID // This should be a user selected value
   }
   // code removed for brevity 
}

如果您愿意,我可以帮助获取 TestModel 值,但我现在需要做一些工作;)

于 2012-11-27T13:01:49.470 回答