0

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

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

代码如下:

高级搜索视图.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">
4

1 回答 1

1

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

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

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

我看不到此模型对象的代码,但您应该尝试单独发送每个参数,以便模型绑定器能够从其属性中构造 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 参数没有问题。你总是在网上看到它们。例如,请参阅此链接的 URL

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

于 2012-01-03T14:13:22.807 回答