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

データが返されない理由は、ポスト アクションのメソッド シグネチャが

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

これは、ドロップダウン ボックスから項目を 1 つだけ選択するためです。したがって、string[] ではなくこのシグネチャを使用すると、Model バインダーは選択された値をアクションに返します。

そうは言っても、それはより良い実践であり、「MVC Way」を使用することです。

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

アップデート

ProccessModel最善の方法は、OwnerID をクラスに追加することだと思います。ViewModelに含まれているProccessModelように見えるためIEnumberable<ProccessModel> Processes、デフォルトの 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
                              });

Post アクションを変更します。

[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 に答える