1

I want to pass an input model from a partial view to a controller. I'm rather new to MVC so still trying to understand how the default model binder works.

Via AJAX (listBox) a controller passes back a partial view and inserts into table id=searchResults.

@model ViewModels.LocationViewModel
@using (Ajax.BeginForm("ProcessSearch", "SearchR", new AjaxOptions
{
    HttpMethod = "GET",
    InsertionMode = InsertionMode.Replace,
    UpdateTargetId = "searchResults",
}))

{ 
    <div>@Html.ListBoxFor(xxx)</div>
    <input id="Search" type="submit" value="Search" />
}

Here is the controller and ViewModel that populates the partial view

public class OrderViewModel
{
    public string Description       { get; set; }
    public string Status            { get; set; }     
}

public ActionResult ProcessSearch(SearchViewModel search)
{
     select new OrderViewModel{
                Status=f.STATUS,
                Description=f.DESCRIPTION}).ToList();
     return PartialView(model);
}

同じメイン ビューに、さらに別のビュー モデルにバインドしたいフォームがあります。部分ビューのモデルからデフォルトのバインダーを実装する方法がわかりません。これを正しく説明していない場合は、お詫び申し上げます。それが理にかなっていることを願っています。

@using (Html.BeginForm("Testing", "SearchR", FormMethod.Post))
{ 
    <div>@Html.DropDownListFor(yyy)</div>
    <input id="Reshop" type="submit" value="Reshop" />
}
<table id="searchResults"></table>


public ActionResult Testing(RSOrderViewModel rOrder)
{
    return Content("hey");
}

public class RSOrderViewModel 
{
    public string yyy { get; set; }
    public IEnumerable<OrderViewModel> sovm { get; set; }
}


@model List<ViewModels.OrderViewModel>

@{ViewData.TemplateInfo.HtmlFieldPrefix = "sovm";
   }

 <table id="searchResults">
    <tr>
        <th>Order Id</th>
        <th>Order Detail</tr>

@for (int i = 0; i < Model.Count; i++)
{
    <tr>
        <td>
         @Html.DisplayFor(x => x[i].OrderId)
        </td>
        <td>
         @Html.DisplayFor(x => x[i].OrderDetail)
        </td>
    </tr>
}

</table>
4

1 に答える 1

3

テーブルは2番目のフォームの外側にあります。したがって、TestingアクションにPOSTすると、コントローラーに送信されるのはドロップダウンリストの値だけです。このテーブルに格納されているコレクションを送信する場合は、AJAXを使用するか、テーブルをフォーム内に配置する必要があります。

@using (Html.BeginForm("Testing", "SearchR", FormMethod.Post))
{ 
    <div>@Html.DropDownListFor(yyy)</div>
    <table id="searchResults"></table>
    <input id="Reshop" type="submit" value="Reshop" />
}

もちろん、フォーム内にテーブルを配置しても、フォームを送信したときにサーバーに何かが送信されるわけではありません。POSTバックされる値を含む入力フィールド(ユーザーに表示されたくない場合は非表示)を配置する必要があります。また、これらの入力フィールド名は、リストにバインドするための標準の規則に従う必要があります。

部分ビューがどのように表示されるかを実際に示したわけではありませんが、規則が尊重されるように表示される例を次に示します。たとえば、バインドするOrderViewModelに2つのプロパティ、OrderIdとOrderDetailがあるとします。

@model IEnumerable<OrderViewModel>
@{
    // We set the name prefix for input fields to "sovm"
    // because inside your RSOrderViewModel the collection 
    // property you want to bind to this table is called sovm
    // and in order to respect the convention the input names
    // must be in the following form "sovm[0].OrderId", "sovm[1].OrderId", ...
    ViewData.TemplateInfo.HtmlFieldPrefix = "sovm";
}
<thead>
    <tr>
        <th>Order Id</th>
        <th>Order detail</th>
    </tr>
</thead>
<tbody>
    @Html.EditorForModel()
</tbody>

次に、モデルの要素ごとにレンダリングされるエディターテンプレートを作成できます(~/Views/Shared/EditorTemplates/OrderViewModel.cshtml):

@model OrderViewModel
<tr>
    <td>@Html.EditorFor(x => x.OrderId)</td>
    <td>@Html.EditorFor(x => x.OrderDetail)</td>
</tr>

テンプレートの名前は、バインドするコレクションで使用されるタイプの名前です(IEnumerable<OrderViewModel> sovm { get; set; }=> OrderViewModel.cshtml)。~/Views/Shared/EditorTemplates複数のコントローラー間で再利用できる場合、または~/Views/XXX/EditorTemplatesXXXが現在のコントローラーであるフォルダー内の現在のコントローラーに固有の場合も、フォルダー内に配置する必要があります。

于 2012-04-13T05:54:25.987 に答える