再次 GET 时清除之前的 GET 参数(查询字符串参数)
我正在使用 MVC3、C#、Razor。我有一个视图 (Index.cshtml),其中包含对部分 (List.cshtml) 的引用。页面上还有一个 Ajax 表单(Ajax.BeginForm...),它是列表的过滤器。我一直在使用 Ajax 表单的默认 POST 方法,一切都运行良好。然而,有一件事并不像我的客户所期望的那样。当我过滤列表,然后单击某个项目以查看其详细信息 (Detail.cshtml),然后单击返回时,它不会显示过滤后的列表,而是恢复到整个列表。所以我想将我的表单方法更改为 GET 来解决这个问题(以及让我能够将一个人直接链接到过滤列表)。我这样做了,但它引入了一个新的异常现象。我过滤列表,然后选择一个项目的详细信息,然后单击“返回”。现在我得到了过滤列表(根据需要),但我也得到了 URL 中的查询字符串,该字符串会覆盖任何后续过滤列表的尝试。我不确定是否需要手动清除查询字符串,或者是否需要完全追求新的模式。这是相关代码:
Index.cshtml
...
@using (Ajax.BeginForm(new AjaxOptions { UpdateTargetId = "resultslist", LoadingElementId="loadingResults", OnComplete = "initializePage", HttpMethod="Get" }))
{
<div class="pane">Filter</div>
<div>
<div class="filterfield">
<div class="field">@Html.TextBox("keywords", "")</div>
<div class="fieldname">Keywords</div>
</div>
<div class="filterfield">
<div class="field">@Html.DropDownList("type", Model.Types, "")</div>
<div class="fieldname">Type</div>
</div>
<div class="filterfield">
<div class="field">@Html.DropDownList("category", Model.Categories, "")</div>
<div class="fieldname">Category</div>
</div>
<div class="filterfield">
<div class="field">@Html.DropDownList("subcategory", Model.Subcategories, "")</div>
<div class="fieldname">Subcategory</div>
</div>
<div class="filterfield">
<div class="field">@Html.Editor("capability","AutocompleteSingle", new { Id = "capability", Url = "/dp/api/pages/GetCapabilities" })</div>
<div class="fieldname">Capability</div>
</div>
<input id="filterButton" type="submit" value="Filter" />
<input type="button" onclick="$('form').clearForm();filterButton.click();" value="Clear" />
<div style="clear:both;"></div>
</div>
}
...
<div id="loadingResults" class="loading">
loading...
</div>
<div id="resultslist">
@Html.Partial("List", Model.Pages)
@if(!ViewBag.Cached) {
@:Building environments. Please wait. This may take a while.
}
</div>
PagesController.cs - Index Action
public ActionResult Index(string keywords, string category, string subcategory, string capability)
{
var pages = (CurrentEnvironment != null ? CurrentEnvironment.Pages.AsEnumerable() : new List<CustomPage>());
//apply filters if they exist
if (!string.IsNullOrEmpty(keywords))
pages = pages.Where(
page => page.Name.ToLower().Contains(keywords.ToLower()) ||
page.Category.ToLower().Contains(keywords.ToLower()) ||
page.Subcategory.ToLower().Contains(keywords.ToLower()) ||
page.Capabilities.Any(name => name.ToLower().Contains(keywords.ToLower())) ||
page.File.FullName.ToLower().Contains(keywords.ToLower()) ||
page.RevisionHistory.ToLower().Contains(keywords.ToLower()) ||
page.Summary.ToLower().Contains(keywords.ToLower())
);
if (!string.IsNullOrEmpty(category)) pages = pages.Where(p => p.Capabilities.Count > 0 && p.Category == category);
if (!string.IsNullOrEmpty(subcategory)) pages = pages.Where(p => p.Capabilities.Count > 0 && p.Subcategory == subcategory);
if (!string.IsNullOrEmpty(capability)) pages = pages.Where(p => p.Capabilities.Count > 0 && p.Capabilities.Any(c => c.ToLower().Contains(capability.ToLower())));
//build a view model
var result = new dp.ViewModels.PagesViewModel
{
Pages = pages.ToList(),
Types = pages.Select(p => p.Type).Where(t => !string.IsNullOrWhiteSpace(t)).Distinct().OrderBy(t => t).ToSelectItemList(t => t, t => t),
Categories = pages.Select(p => p.Category).Where(c => !string.IsNullOrWhiteSpace(c)).Distinct().OrderBy(c => c).ToSelectItemList(c => c, c => c),
Subcategories = pages.Select(p => p.Subcategory).Where(s => !string.IsNullOrWhiteSpace(s)).Distinct().OrderBy(c => c).ToSelectItemList(s => s, s => s)
};
if (!Request.IsAjaxRequest())
return View(result);
else
return PartialView("List", result.Pages);
}
提前致谢。
I'm using MVC3, C#, Razor. I have a view (Index.cshtml) that includes a reference to a Partial (List.cshtml). There is also an Ajax form (Ajax.BeginForm...) on the page that is a filter for the list. I've been using the default POST method for the Ajax form and everything works great. One thing doesn't work as my client expects, however. When I filter the list, then click on an item to view it's details (Detail.cshtml), and then click back it does not show me the filtered list but reverts to the entire list. So I would like to change my form method to a GET to fix this (as well as to give me the ability to link a person directly to a filtered list). I do this but it introduces a new anomoly. I filter my list, then choose an item for detail, then click back. Now I get my filtered list (as desired) but I also get the query string in the URL which overrides any subsequent attempts to filter the list. I'm not sure if I need to manually clear my query string or if I need to pursue a new schema altogether. Here's the pertinent code:
Index.cshtml
...
@using (Ajax.BeginForm(new AjaxOptions { UpdateTargetId = "resultslist", LoadingElementId="loadingResults", OnComplete = "initializePage", HttpMethod="Get" }))
{
<div class="pane">Filter</div>
<div>
<div class="filterfield">
<div class="field">@Html.TextBox("keywords", "")</div>
<div class="fieldname">Keywords</div>
</div>
<div class="filterfield">
<div class="field">@Html.DropDownList("type", Model.Types, "")</div>
<div class="fieldname">Type</div>
</div>
<div class="filterfield">
<div class="field">@Html.DropDownList("category", Model.Categories, "")</div>
<div class="fieldname">Category</div>
</div>
<div class="filterfield">
<div class="field">@Html.DropDownList("subcategory", Model.Subcategories, "")</div>
<div class="fieldname">Subcategory</div>
</div>
<div class="filterfield">
<div class="field">@Html.Editor("capability","AutocompleteSingle", new { Id = "capability", Url = "/dp/api/pages/GetCapabilities" })</div>
<div class="fieldname">Capability</div>
</div>
<input id="filterButton" type="submit" value="Filter" />
<input type="button" onclick="$('form').clearForm();filterButton.click();" value="Clear" />
<div style="clear:both;"></div>
</div>
}
...
<div id="loadingResults" class="loading">
loading...
</div>
<div id="resultslist">
@Html.Partial("List", Model.Pages)
@if(!ViewBag.Cached) {
@:Building environments. Please wait. This may take a while.
}
</div>
PagesController.cs - Index Action
public ActionResult Index(string keywords, string category, string subcategory, string capability)
{
var pages = (CurrentEnvironment != null ? CurrentEnvironment.Pages.AsEnumerable() : new List<CustomPage>());
//apply filters if they exist
if (!string.IsNullOrEmpty(keywords))
pages = pages.Where(
page => page.Name.ToLower().Contains(keywords.ToLower()) ||
page.Category.ToLower().Contains(keywords.ToLower()) ||
page.Subcategory.ToLower().Contains(keywords.ToLower()) ||
page.Capabilities.Any(name => name.ToLower().Contains(keywords.ToLower())) ||
page.File.FullName.ToLower().Contains(keywords.ToLower()) ||
page.RevisionHistory.ToLower().Contains(keywords.ToLower()) ||
page.Summary.ToLower().Contains(keywords.ToLower())
);
if (!string.IsNullOrEmpty(category)) pages = pages.Where(p => p.Capabilities.Count > 0 && p.Category == category);
if (!string.IsNullOrEmpty(subcategory)) pages = pages.Where(p => p.Capabilities.Count > 0 && p.Subcategory == subcategory);
if (!string.IsNullOrEmpty(capability)) pages = pages.Where(p => p.Capabilities.Count > 0 && p.Capabilities.Any(c => c.ToLower().Contains(capability.ToLower())));
//build a view model
var result = new dp.ViewModels.PagesViewModel
{
Pages = pages.ToList(),
Types = pages.Select(p => p.Type).Where(t => !string.IsNullOrWhiteSpace(t)).Distinct().OrderBy(t => t).ToSelectItemList(t => t, t => t),
Categories = pages.Select(p => p.Category).Where(c => !string.IsNullOrWhiteSpace(c)).Distinct().OrderBy(c => c).ToSelectItemList(c => c, c => c),
Subcategories = pages.Select(p => p.Subcategory).Where(s => !string.IsNullOrWhiteSpace(s)).Distinct().OrderBy(c => c).ToSelectItemList(s => s, s => s)
};
if (!Request.IsAjaxRequest())
return View(result);
else
return PartialView("List", result.Pages);
}
Thanks in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
是否考虑过使用单独的机制来维护列表/排序的状态?也许是通过 JavaScript 维护和加载的 cookie,或者可能是通过隐藏字段包含“控件”状态的自定义机制?
Have considered using a separate mechanism to maintain the state of the list/sorting? Maybe cookies that are maintained and loaded via JavaScript or potentially a custom mechanism for containing the state of the "control" via hidden fields?