MVC3 - 参数值始终为null

时间:2012-01-03 02:57:10

标签: ajax asp.net-mvc-3 parameter-passing partialviews

我正在尝试使用两个部分视图和Ajax进行“高级搜索”视图。我定义了一个“SearchFilter”实体,它具有所有可用搜索条件的属性。在“_Filter”局部视图(OnSuccess AjaxOption)中提交时,我需要将其传递给更新“_Results”局部视图的“ListResults”操作。

问题是我总是得到一个null实体作为ListResults操作的传入参数。

代码如下:

AdvancedSearchView.cshtml

@model MyApp.ViewModels.SearchFormViewModel
@{
    ViewBag.Title = "Advanced search";
}
    <div id="divFilter">
        @Html.Partial("_Filter", Model)
    </div>
    <div id="divResults">
        @Html.Partial("_Results", Model.ResultsList)
    </div>

_Filter.cshtml

@model MyApp.ViewModels.SearchFormViewModel
<script type="text/javascript">
    function getForm(url, divName) {
        var obj = new Date();
        url = (url.indexOf('?', 0) != -1) ? url + '&uid=' + obj.getTime() : url + '?uid=' + obj.getTime();
        $.get(url, function (data) {
            $("#" + divName).html(data);
        });
    }
</script>

    @using (Ajax.BeginForm("Search", null, new AjaxOptions
    {
        UpdateTargetId = "divFilter",
        InsertionMode = InsertionMode.Replace,
        OnSuccess="getForm('"+Url.Action("ListResults", "Products", new { myFilter = Model.CurrentFilter}) + "','divResults')"
    }, new { id = "idSearchForm" }))
    {
        <fieldset style="width: 800px; line-height: 1.4em;">
            <legend>Configure your search filters</legend>
        ...
        </fieldset>
        <input type="submit" value="Rechercher" class="submit" style="width: 280px" />
    }

控制器

    public ActionResult Search()
    {
SearchFilter currentFilter = new SearchFilter();
List<Product> filteredProductsList = repository.FindProducts_Filtered(currentFilter);
          return View("AdvancedSearchView", new AdvancedSearchFormViewModel(currentFilter, filteredProductsList/* , necessary select lists */));
    }

    [HttpPost]
    public ActionResult Search(AdvancedSearchFormViewModel model)
    {
        SearchFilter currentFilter = model.CurrentFilter;
        // set the necessary select lists

        List<Product> filteredProductsList = repository.FindProducts_Filtered(currentFilter);
        return PartialView("_Filter", AdvancedSearchFormViewModel(currentFilter, filteredProductsList/* , necessary select lists */));
    }

    public ActionResult ListResults(SearchFilter myFilter)
    {
        List<Product> filteredProductsList = repository.FindProducts_Filtered(currentFilter);
        return PartialView("_Results", filteredProductsList);
    }

视图模型

public class AdvancedSearchFormViewModel
    {
        // Properties
        public SearchFilter CurrentFilter { get; set; }
        public List<Product> ResultsList { get; set; }
        // some SelectLists

        // Constructor

        public AdvancedSearchFormViewModel()
        {}

        public AdvancedSearchFormViewModel(SearchFilter pCurrentFilter, List<Product> pResultsList, /* necessary select lists*/)
        {
            CurrentFilter = pCurrentFilter;
            ResultsList = pResultsList;
            // the SelectLists
        }
    }

我毫不怀疑我做错了什么,但我看不出它是什么。

生成的BeginForm HTML标记如下:

<form action="/Products/Search" data-ajax="true" data-ajax-mode="replace" data-ajax-success="getForm(&#39;/Products/ListResults?myFilter=MyApp.Models.SearchFilter&amp;uid=2622ea0e-d7dc-48fa-b65d-519978ee40b3&#39;,&#39;divResults&#39;)" data-ajax-update="#divFilter" id="idSearchForm" method="post">

1 个答案:

答案 0 :(得分:1)

您为ListResults操作的myFilter参数获取空值的原因是因为这是您要提交给服务器的内容:

/Products/ListResults?myFilter=MyApp.Models.SearchFilter&uid=2622ea0e-d7...

默认的模型绑定器试图将字符串“MyApp.Models.SearchFilter”转换为MyApp.Models.SearchFilter的一个实例,但它无法做到。

我无法看到此模型对象的代码,但您应该尝试单独发送每个参数,以便modelbinder能够从其属性构造SearchFilter的实例:

OnSuccess="getForm('"+Url.Action("ListResults", "Products", new { 
    Prop1 = Model.CurrentFilter.Prop1, 
    Prop2 = Model.CurrentFilter.Prop2, 
    etc...
})...

评论1后更新

要回答有关在URL中显示参数值的问题,这就是HTTP的工作原理。如果您不想在URL中显示发送到服务器的任何参数,那么您将需要执行HTTP POST而不是HTTP GET。

但是,只要您的操作是幂等的,就应该使用HTTP GET。当输入提交应以某种方式改变应用程序的状态时,应保留HTTP POST。实际上,我不同意您使用[HttpPost]进行public ActionResult Search(AdvancedSearchFormViewModel model)操作方法。由于它所做的只是返回要查看的数据,因此它是一种幂等行为。

也就是说,没有什么可以阻止您违反此指南并执行HTTP POST而不是GET。就个人而言,我没有看到URL参数的问题。你一直在网上看到它们。例如,see the URL for this link

HTTP不了解复杂对象,只了解文本。要通过HTTP发送复杂对象的数据,需要将它们分解为文本部分。要通过HTTP GET发送这样的数据,它们必须位于URL中。