我在局部视图中定义了一个webgrid。 (这是一个MVC 4项目。)webgrid不是局部视图中的唯一内容,因此webgrid绑定到局部视图模型中的List。
当单击列标题时,网格将填充和排序,但是当我通过调用操作方法(通过使用Ajax.BeginForm设置的表单发布)重新填充网格,然后单击列标题时,网格内容消失。 (action方法使用用户在表单上提供的搜索条件查询数据库。)
可能导致这种情况的原因是什么?怎么解决?
部分视图以:
开头@model DonationImport.Models.GiftWithSplits
部分视图的内容在指定的表格中:
@using (Ajax.BeginForm("SearchConstit", "Batch", new AjaxOptions { HttpMethod = "POST", UpdateTargetId = "constitSearchArea" }))
WebGrid的定义如下:
@{
var constitGrid = new WebGrid(source: Model.SearchResults, rowsPerPage: 100, ajaxUpdateContainerId: "constitGrid");
<div style="overflow-x: scroll; width: 100%;">
<div style="width: 1910px;">
@constitGrid.GetHtml(htmlAttributes: new { id = "constitGrid" },
columns: constitGrid.Columns(
constitGrid.Column(format: @<text><button onclick="selectConstituent('@item.Constituent_ID')" >select</button></text>, style: "searchResultsColumnWidth"),
constitGrid.Column("Constituent_ID", header: "ConstitID", style: "searchResultsColumnWidth", format: @<text>@Html.ActionLink((string)item.Constituent_ID, "PriorGifts", new { constitID = item.Constituent_ID }, new { target = "Prior Payments" })</text>),
constitGrid.Column("IsActive", header: "Active", style: "searchResultsColumnWidth"),
constitGrid.Column("LastName", header: "Last", style: "searchResultsColumnWidth"),
constitGrid.Column("FirstName", header: "First", style: "searchResultsColumnWidth"),
constitGrid.Column("MiddleInitial", header: "M.I.", style: "searchResultsNarrowColumnWidth"),
constitGrid.Column("Spouse", header: "Spouse", style: "searchResultsColumnWidth"),
constitGrid.Column("EmailAddress", header: "E-mail", style: "searchResultsWideColumnWidth"),
constitGrid.Column("AddressLine1", header: "Address Line 1", style: "searchResultsWideColumnWidth"),
constitGrid.Column("City", header: "City", style: "searchResultsWideColumnWidth"),
constitGrid.Column("State", header: "State", style: "searchResultsColumnWidth"),
constitGrid.Column("Zip", header: "Zip", style: "searchResultsWideColumnWidth"),
constitGrid.Column("SearchResultsText", header: "Search Results", style: "searchResultsWideColumnWidth"),
constitGrid.Column("IsActivePledge", header: "Pledge", style: "searchResultsNarrowColumnWidth"),
constitGrid.Column("ReceiptWarning", header: "Receipt Warning", style: "searchResultsWideColumnWidth"),
constitGrid.Column("IsMember", header: "Mbr", style: "searchResultsNarrowColumnWidth")),
alternatingRowStyle: "altrow")
</div>
</div>
}
点击一下:
<input type="submit" value="Search" />
在表单中,调用的action方法如下:
[HttpPost]
public PartialViewResult SearchConstit(DonationImport.Models.GiftWithSplits g)
{
GiftWithSplits giftWithSplits = new GiftWithSplits(); // model (object) to be returned to the partial view
// send back gift data which we are currently using
giftWithSplits.GiftToVerify = g.GiftToVerify;
// search using provided data
string middleInitial = empty2null(g.GiftToVerify.SourceMiddleName);
if (!string.IsNullOrWhiteSpace(middleInitial))
middleInitial = middleInitial.Substring(0, 1); // just supply the initial, not the entire name
string zip = empty2null(g.GiftToVerify.SourceZip);
if (!String.IsNullOrWhiteSpace(zip))
zip = zip.Substring(0, 5); // we want only the first 5 digits of the zip
giftWithSplits.SearchResults = db.SearchDonor(null, g.GiftToVerify.DonationSourceCode, empty2null(g.SourceAcctMemo), null, empty2null(g.GiftToVerify.SourceLastName),
empty2null(g.GiftToVerify.SourceFirstName), middleInitial, empty2null(g.GiftToVerify.SourceAddress1),
empty2null(g.GiftToVerify.SourceCity), empty2null(g.GiftToVerify.SourceState), zip, empty2null(g.GiftToVerify.SourceCountry),
empty2null(g.GiftToVerify.SourceEmailAddress), empty2null(g.GiftToVerify.SourcePhone)).ToList();
if (giftWithSplits.SearchResults.Count == 0)
{
SearchDonor_Result emptyResult = new SearchDonor_Result();
emptyResult.Constituent_ID = "[None Found]";
giftWithSplits.SearchResults.Add(emptyResult);
}
return PartialView("_ConstitSearch", giftWithSplits);
}
你可能会说,我是这个MVC方法的初学者。
其他想法(稍后补充)......
问题的根源似乎是WebGrid HTML帮助列标题生成的链接基于与生成网格的操作方法相关的URL。首次显示网格时,链接为:/ Batch / Verify / 34?sort = FirstName&amp; sortdir = ASC,因为网格是作为整个验证视图的一部分构建的(来自验证操作方法)。但是,当搜索手动输入的搜索条件时,网格是从SearchConstit操作方法构建的,该方法仅填充部分视图,因此列标题链接中的URL现在为:/ Batch / SearchConstit?sort = FirstName&amp; sortdir = ASC。
此外,“搜索”按钮与POST相关联,因为它需要从表单字段传递数据以用作搜索条件;而WebGrid列标题使用的是GET,显然没有办法强制它们进行POST。因此,问题似乎归结为如何从表单字段传递搜索条件而不发布表单。
我可以想到使用Session变量的可能解决方案,但是我对这样做犹豫不决。
另一种选择可能是放弃使用WebGrid。
有什么想法吗?
答案 0 :(得分:0)
当我在寻找同样问题的解决方案时,我找到了你的问题。我也面临同样的问题。我用网格来显示数据。 我使用过滤器/分页。我也使用文本框在网格中搜索。 我正在打电话进行搜索。当我点击过滤器和分页按钮时,Webgrid正在消失。我谷歌很多,没有找到任何解决方案。最后我找到了解决方案,因此想到发布。 你需要使用get ajax调用而不是post call来解决你的问题。不要使用beginform post进行搜索。
Index.cshtml is my main view. Here i m rendering partial view (_GridPartialView.cshtml). Index view has one webgrid and search text box.
I am using ajax call to search in webgrid. Ajax code is mention below.
**Index.cshtml:**
@model List<Login>
@{
ViewBag.Title = "User";
}
<h2 style="background-color: grey">User</h2>
<table>
<tr>
<td>
<input type="text" id="txtSearch" placeholder=" Search..." onkeyup="Search()" />
@Html.ActionLink("Create New User", "CreateUser")</td>
</tr>
<tr>
<td>
<div id="divPartialView">
@Html.Partial("~/Views/Shared/_GridPartialView.cshtml", Model)
</div>
</td>
</tr>
</table>
<script type="text/javascript">
function Search() {
var searchVal = $("#txtSearch").val();
$.ajax({
type: "GET",
url: '/User/Search',
data: { searchString: searchVal },
dataType: 'html',
success: function (data) {
$('#divPartialView').html(data);
}
});
}
</script>
_GridUserPArtialView.cshtml: This is partial view used in index view.
@model List<Login>
<script src="../../Scripts/jquery-1.7.1.min.js" type="text/javascript"></script>
<style type="text/css">
.webGrid { margin: 4px; border-collapse: collapse; width: 500px; background-color:#FCFCFC;}
.header { background-color: #C1D4E6; font-weight: bold; color: #FFF; }
.webGrid th, .webGrid td { border: 1px solid #C0C0C0; padding: 5px; }
.alt { background-color: #E4E9F5; color: #000; }
.gridHead a:hover {text-decoration:underline;}
.description { width:auto}
.select{background-color: #389DF5}
</style>
@{
var grid = new WebGrid(null, canPage: true, rowsPerPage: 5, selectionFieldName: "selectedRow", ajaxUpdateContainerId: "grid");
grid.Pager(WebGridPagerModes.NextPrevious);
grid.Bind(Model, autoSortAndPage: true, rowCount: Model.Count);}
<div id="grid">
@grid.GetHtml(
tableStyle: "webGrid", mode: WebGridPagerModes.All,
firstText: "<< First",
previousText: "< Prev",
nextText: "Next >",
lastText: "Last >>",
headerStyle: "header",
alternatingRowStyle: "alt",
selectedRowStyle: "select",
columns: grid.Columns(
grid.Column("UserName", "User Name", style: "description"),
grid.Column("FirstName", "First Name"),
grid.Column("LastName", "Last Name"),
grid.Column("Action", format: @<text>
@if (@item.LoginUserName != "administrator"){
@Html.ActionLink("Edit", "Edit", new { id=item.LoginUserName})
@Html.ActionLink("Delete","Delete", new { id = item.LoginUserId},new { onclick = "return confirm('Are you sure you wish to delete this user?');" })
}
</text>, style: "color:Gray;" , canSort: false)
))
</div>
**UserController.cs**: This is Search action method inside. usercontroller. It is HTTPGET.
[HttpGet]
public PartialViewResult Search(string searchString)
{
List<Login> userListCollection = new List<Login_User>();
userListCollection = Login_User_Data.GetAllUsers();
if (Request.IsAjaxRequest())
{
if (!string.IsNullOrEmpty(searchString))
{
Log.Info("UserController: Index() Started");
var searchedlist = (from list in userListCollection
where list.FirstName.IndexOf(searchString,StringComparison.OrdinalIgnoreCase) >=0
|| list.LoginUserName.IndexOf(searchString, StringComparison.OrdinalIgnoreCase) >= 0
|| list.LastName.IndexOf(searchString, StringComparison.OrdinalIgnoreCase) >= 0
select list
).ToList();
return PartialView("~/Views/Shared/_GridPartialView.cshtml", searchedlist);
}
else
{
Log.Info("UserController: Search(Login_User user) Ended");
return PartialView("_GridPartialView", userListCollection);
}
}
else
{
return PartialView("_GridPartialView", userListCollection);
}
Log.Info("UserController: Search() Ended");
}
Hope this will help you. Let me know if you have any concern.
From: www.Dotnetmagics.com
答案 1 :(得分:0)
解决方案很简单,你需要做一个GET,每当你对web网格进行排序或分页时,它都会尝试获取数据并点击一个HttpGet Action,这将按如下方式工作:
[HttpGet]
public ActionResult YourActionMethod()
{
return PartialView("YourView",YourModel);
}
最好的部分是,在排序时,请求也会发送一个名为“sortBy”的参数,你可以在这里使用它,并决定你想用绑定模型和网格做什么。您可以使用浏览器中的“开发人员工具”检查排序标题将点击的URL。
注意:默认情况下,它所操作的操作方法与控制器名称相同。