数据绑定MVC3

时间:2012-08-24 06:39:08

标签: ajax asp.net-mvc asp.net-mvc-3 data-binding

我不知道我做错了什么。 我有这种形式,这是复杂观点的一部分。

    @{
    var filtersAjaxOptions = new AjaxOptions
        {
            HttpMethod = "POST",
            InsertionMode = InsertionMode.Replace,
            UpdateTargetId = "clientList-body",
            OnBegin = "clientList.filterRequestStart()",
            OnComplete = "clientList.filterRequestComplete()",
            OnSuccess = "clientList.filterRequestSuccess()"
        };
    }
    <span class="clientFilters-filterValue inlineBlock">
        @using (Ajax.BeginForm(
            "Index",
            "ClientList",
            new {
                ProductId = Model.ClientListViewModel.Filters.ProductId,
                ClientFilter = Model.ClientListViewModel.Filters.ClientFilter,
                BillFilter = Model.ClientListViewModel.Filters.BillFilter,
                DateSortType = Model.ClientListViewModel.Filters.DateSortType,
                SortDirection = Model.ClientListViewModel.Filters.SortDirection
            },
            filtersAjaxOptions,
            new
            {
                id = "clientListDateFilter-form"
            }
        ))
        {
            @Html.TextBoxFor(
                m => m.ClientListViewModel.Filters.BeginDateRange,
                new
                {
                    @class = "dp-input textInput inlineBlock",
                    id = "dp-billDateFilterStart",
                }
            )
            @Html.TextBoxFor(
                m => m.ClientListViewModel.Filters.EndDateRange,
                new
                {
                    @class = "dp-input textInput inlineBlock",
                    id = "dp-billDateFilterEnd",
                }
            )
        }
    </span>

这是过滤器模型

    public class FilterModel
    {
        public FilterModel()
        {
            ClientFilter = ClientsEnum.All;
            BillFilter = ClientBillsEnum.All;
        }

        public string ProductId { get; set; }
        public ClientsEnum ClientFilter { get; set; }
        public ClientBillsEnum BillFilter { get; set; }
        public DateTime? BeginDateRange { get; set; }
        public DateTime? EndDateRange { get; set; }
        public DateSortType? DateSortType { get; set; }
        public SortDirection? SortDirection { get; set; }
    }

这部分是 ClientListController 方法索引

    public ActionResult Index(FilterModel filters)
    {
        var clientListViewModel = GetClientListViewModel(filters, 1, 1, PageSize);
        if (ControllerContext.HttpContext.Request.IsAjaxRequest())
            return PartialView("Partial/ClientListBody", clientListViewModel);
        return View(clientListViewModel);
    }

每当我提交上面的表格时,我都会看到“BeginDateRange”和“EndDateRange”字段为空,其他字段设置正确。虽然,当我在Watch中插入 Request.Form 时,我可以看到整个数据。

更新1 所以我设置了&lt; globalization&gt;在Web.config中:

    <globalisation responseHeaderEncoding="utf-8" culture="en-US">

然而它不起作用。和以前一样的结果。

更新2 此外,当我试图将所有routevalues数据放入@ Html.HiddenFor时,控制器只看到空值。同样,Request.Form正在填充。

所以问题是:如何将表单数据绑定到传入模型? TY

2 个答案:

答案 0 :(得分:1)

默认模型绑定器在绑定日期时使用当前的区域性日期时间格式。这意味着您必须在文本框中以正确的格式输入日期。另一方面,如果您需要固定格式,则可以在web.config(<globalization>元素)中使用固定文化或编写自定义模型绑定器:https://stackoverflow.com/a/7836093/29407


更新:

您需要指定正确的绑定前缀,因为您的输入字段的名称类似于ClientListViewModel.Filters.BeginDateRange,但您的控制器操作采用FilterModel作为参数而不是根视图模型:

public ActionResult Index([Bind(Prefix = "ClientListViewModel.Filters")] FilterModel filters)
{
    ...
}

但是现在这会打破其他值,所以你也需要调整你的视图:

@using (Ajax.BeginForm(
    "Index",
    "ClientList",
    null,
    filtersAjaxOptions,
    new
    {
        id = "clientListDateFilter-form"
    }
 ))
{
    @Html.HiddenFor(x => x.ClientListViewModel.Filters.ProductId)
    @Html.HiddenFor(x => x.ClientListViewModel.Filters.ClientFilter)
    @Html.HiddenFor(x => x.ClientListViewModel.Filters.BillFilter)
    @Html.HiddenFor(x => x.ClientListViewModel.Filters.DateSortType)
    @Html.HiddenFor(x => x.ClientListViewModel.Filters.SortDirection)

    @Html.TextBoxFor(
        m => m.ClientListViewModel.Filters.BeginDateRange,
        new
        {
            @class = "dp-input textInput inlineBlock",
            id = "dp-billDateFilterStart",
        }
    )
    @Html.TextBoxFor(
        m => m.ClientListViewModel.Filters.EndDateRange,
        new
        {
            @class = "dp-input textInput inlineBlock",
            id = "dp-billDateFilterEnd",
        }
    )
}

或者如果您想将它们作为表单网址的一部分发送,而不是使用隐藏字段:

@using (Ajax.BeginForm(
    "Index",
    "ClientList",
    new RouteValueDictionary 
    { 
        { "ClientListViewModel.Filters.ProductId", Model.ClientListViewModel.Filters.ProductId },
        { "ClientListViewModel.Filters.ClientFilter", Model.ClientListViewModel.Filters.ClientFilter },
        { "ClientListViewModel.Filters.BillFilter", Model.ClientListViewModel.Filters.BillFilter },
        { "ClientListViewModel.Filters.DateSortType", Model.ClientListViewModel.Filters.DateSortType },
        { "ClientListViewModel.Filters.SortDirection", Model.ClientListViewModel.Filters.SortDirection },
    },
    filtersAjaxOptions,
    new RouteValueDictionary
    {
        { "id", "clientListDateFilter-form" }
    }
 ))
{
    @Html.TextBoxFor(
        m => m.ClientListViewModel.Filters.BeginDateRange,
        new
        {
            @class = "dp-input textInput inlineBlock",
            id = "dp-billDateFilterStart",
        }
    )
    @Html.TextBoxFor(
        m => m.ClientListViewModel.Filters.EndDateRange,
        new
        {
            @class = "dp-input textInput inlineBlock",
            id = "dp-billDateFilterEnd",
        }
    )
}

答案 1 :(得分:0)

试试这个:

public ActionResult Index(FilterModel filters, FormCollection collection)
{
    UpdateModel(filters, "ClientListViewModel");
    var clientListViewModel = GetClientListViewModel(filters, 1, 1, PageSize);
    if (ControllerContext.HttpContext.Request.IsAjaxRequest())
        return PartialView("Partial/ClientListBody", clientListViewModel);
    return View(clientListViewModel);
}

并且在视野中:

@Html.TextBoxFor(
            m => m.ClientListViewModel.FilterModel.EndDateRange,
            new
            {
                @class = "dp-input textInput inlineBlock",
                id = "dp-billDateFilterEnd",
            }
        )

你有奇怪的命名。此外,最好使用隐藏字段,然后通过路由值传递值。