1

ソート可能なJQueryを使用し、新しい注文をコントローラーに返送しようとしましたが、あまり運がありませんでした。私の見解は:

using (Ajax.BeginForm("EditTickerOrder", new AjaxOptions { InsertionMode = InsertionMode.Replace, HttpMethod = "POST", }))
{
    <div id="editableticker">
        @Html.HiddenFor(m => m.ProjectGUID)
        <ul id="sortablediv">
            @foreach (DGI.CoBRA.Tools.BussinessObjects.CollabLibrary.TickerObjects.Ticker t in Model)
            {
                <li class="ui-state-default" id="@t.pKeyGuid.ToString()">
                    <p>@Html.CheckBox(t.pKeyGuid.ToString(), t.Display, new { @class = "activechk" }) 
                        <span style="font-weight: bold">
                            @t.Text
                        </span>
                    </p>
                </li>
            }
        </ul>
    <input type="submit" value="Save New Ticker Order" />
}

そして私のコントローラーは:

[HttpPost]
public ActionResult EditTickerOrder(Guid ProjectGUID, List<string> items)
{
    TickerCollectionModel TickerData = new TickerCollectionModel();
    TickerData.ProjectGUID = ProjectGUID;
    TickerData.ListAllBySession(ProjectGUID);
    return PartialView("TickerList", TickerData);
}

それでも、list<string> items常にnullです。何か案は?

4

1 に答える 1

2

あなたはループを書いていますが、デフォルトのモデルバインダーがコレクションを操作するために期待するフォーム入力フィールドの命名規則foreachに間違いなく違反しています。確立されたワイヤ形式を尊重しない場合、デフォルトのモデルバインダーがPOSTアクションでモデルを再水和できるとは期待できません。

実際、ビューモデルとエディターテンプレートを使用してみませんか?それらはASP.NETMVCですべてを些細なものにします。

それでは、ビュー要件を反映するビューモデルを定義しましょう(または、少なくとも質問に示されているもの=>もちろん、処理したい追加のプロパティでモデルを強化することができます)。

public class TickerViewModel
{
    public Guid Id { get; set; }
    public bool IsDisplay { get; set; }
    public string Text { get; set; }
}

public class ProjectViewModel
{
    public Guid ProjectGUID { get; set; }
    public IEnumerable<TickerViewModel> Tickers { get; set; }
}

次に、DALレイヤーのクエリ、ドメインモデルの取得、このビュー用に定義したビューモデルへのドメインモデルのマッピング、およびビューモデルのビューへの受け渡しを担当するコントローラー。逆に、POSTアクションは、ビューからビューモデルを受け取り、ビューモデルをドメインモデルにマップし直し、処理のためにドメインモデルをDALレイヤーに渡し、ビューをレンダリングするか、成功アクションにリダイレクトします。

public class HomeController : Controller
{
    public ActionResult Index()
    {
        // TODO: those values come from a data layer of course
        var model = new ProjectViewModel
        {
            ProjectGUID = Guid.NewGuid(),
            Tickers = new[]
            {
                new TickerViewModel { Id = Guid.NewGuid(), Text = "ticker 1" },
                new TickerViewModel { Id = Guid.NewGuid(), Text = "ticker 2" },
                new TickerViewModel { Id = Guid.NewGuid(), Text = "ticker 3" },
            }
        };
        return View(model);
    }

    [HttpPost]
    public ActionResult Index(ProjectViewModel model)
    {
        // Everything will be correctly bound here => map the view model
        // back into your domain model and pass the domain model to 
        // your DAL layer for processing ...

        return Content("Thanks for submitting");
    }
}

ビュー(この例では、AJAXの代わりに標準フォームを使用しましたが、AJAXフォームに変換するのは簡単です):

@model ProjectViewModel

@using (Html.BeginForm())
{
    @Html.HiddenFor(m => m.ProjectGUID)
    <div id="editableticker">
        <ul id="sortablediv">
            @Html.EditorFor(x => x.Tickers)
        </ul>
    </div>
    <button type="submit">OK</button>
}

最後に、Tickersコレクションの各要素に対して自動的にレンダリングされる対応するエディターテンプレート(~/Views/Home/EditorTemplates/TickerViewModel.cshtml):

@model TickerViewModel

<li class="ui-state-default">
    <p>
        @Html.CheckBoxFor(x => x.IsDisplay, new { @class = "activechk" }) 
        @Html.LabelFor(x => x.IsDisplay, Model.Text)
        @Html.HiddenFor(x => x.Text)
        @Html.HiddenFor(x => x.Id)
    </p>
</li>
于 2012-06-10T19:35:06.397 に答える