将新订单发送回MVC控制器

时间:2012-06-10 19:23:52

标签: asp.net-mvc-3 jquery-ui jquery-ui-sortable

使用JQuery sortable,并尝试将新订单发送回我的控制器,但没有太多运气。我的观点是:

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。有什么想法吗?

1 个答案:

答案 0 :(得分:2)

您正在编写foreach循环,绝大多数都违反了表单输入字段的naming conventions,默认模型绑定器期望使用集合。如果您不遵守既定的电线格式,则不能指望默认的模型绑定器能够在POST操作中为模型重新水化。

实际上,为什么不使用视图模型和编辑器模板?它们使ASP.NET MVC中的所有内容都变得微不足道。

因此,让我们定义一个反映您的视图要求的视图模型(或至少在您的问题中显示的那些=&gt;您当然可以使用您想要处理的其他属性来丰富它):

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>