我正在尝试使用两个部分视图和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('/Products/ListResults?myFilter=MyApp.Models.SearchFilter&uid=2622ea0e-d7dc-48fa-b65d-519978ee40b3','divResults')" data-ajax-update="#divFilter" id="idSearchForm" method="post">
答案 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中。