我无法从我的视图中的下拉列表中获取所选值,而是在我的控制器中

时间:2012-11-26 23:25:43

标签: asp.net-mvc

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

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

在我的控制器中,我得到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>

这是我的控制者。创建帖子什么也没做,我正试图先获得正确的值。

//
        // 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();
        }

1 个答案:

答案 0 :(得分:0)

您没有收到任何数据的原因是因为Post Action的方法签名需要

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

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

说完这个,这是更好的练习和“MVC方式”使用,

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

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

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

更新

我认为最好的办法是将一个OwnerID添加到ProccessModel类。 因为ViewModel中包含的ProccessModel看起来是IEnumberable<ProccessModel> Processes,您可以使用defult MVC模型绑定器以下列方式获取Model to Bind。

菲尔·哈克(Phil Haack)对这里的名单进行了绑定:

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

改编菲尔的帖子我认为你必须做这样的事情:

<% 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值,但我现在需要做一些工作;)