我有一个视图,我在分页列表中显示搜索结果和排序。我将列标题添加为链接,以使用户能够以这种方式基于列进行排序:
<tr>
<th>
@Html.ActionLink("Reference No", "Index",
new { sortOrder = ViewBag.RefNoSortParm, currentFilter = ViewBag.CurrentFilter })
</th>
<th>
@Html.ActionLink("Category", "Index",
new { sortOrder = ViewBag.CatSortParm, currentFilter = ViewBag.CurrentFilter })
</th>
... Some other columns
</tr>
我也这样添加了一个寻呼机:
Page @(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber) of @Model.PageCount
@Html.PagedListPager(Model, page => Url.Action("Index",
new { page, sortOrder = ViewBag.CurrentSort, currentFilter = ViewBag.CurrentFilter }))
我使用的动作如下:
private Registry_fssEntities db = new Registry_fssEntities();
public ActionResult Index(string sortOrder, SearchTransacModel searchModel, SearchTransacModel currentFilter, int? page)
{
var model = from c in db.TRANSACs
select c;
ViewBag.CurrentSort = sortOrder;
ViewBag.DispDateSortParm = String.IsNullOrEmpty(sortOrder) ? "DispDate" : "";
ViewBag.RefNoSortParm = sortOrder == "RefNo" ? "RefNo_desc" : "RefNo";
ViewBag.CatSortParm = sortOrder == "Cat" ? "Cat_desc" : "Cat";
if (searchModel.DATEDISPFROM != null || searchModel.DATEDISPTO != null || searchModel.DATEDISPFROM != null || searchModel.OFFICERNAME != null || searchModel.APPNAME != null || searchModel.REFNO != null || searchModel.PROCNAME != null)
{
page = 1;
}
else
{
searchModel = currentFilter;
}
if (searchModel != null)
{
if (!String.IsNullOrEmpty(searchModel.DATEDISPFROM))
{
ViewBag.DispFrom = searchModel.DATEDISPFROM.ToString();
}
else
{
searchModel.DATEDISPFROM = "01/01/" + DateTime.Today.Year.ToString();
ViewBag.DispFrom = "01/01/" + DateTime.Today.Year.ToString();
}
if (!String.IsNullOrEmpty(searchModel.DATEDISPTO))
{
ViewBag.DispTo = searchModel.DATEDISPTO.ToString();
}
else
{
searchModel.DATEDISPTO = "31/12/" + DateTime.Today.Year.ToString();
ViewBag.DispTo = "31/12/" + DateTime.Today.Year.ToString();
}
}
if (searchModel != null)
{
var tRANSACs = new TransacBusinessLogic();
model = tRANSACs.GetTransacs(searchModel);
ViewBag.currentFilter = searchModel;
}
List<TransacViewModel> TransactionList = new List<TransacViewModel>();
foreach (var item in model)
{
TransactionList.Add(new TransacViewModel {
TRANSID = item.TRANSID,
REFNO = item?.REFNO,
PROCESS = item?.PROCESS,
//CATEGORY = item.PROCESS.CATEGORY,
DOCTYPE = item?.DOCTYPE,
DATEDEL = returnasdate(item.DATEDEL),
DATEDISP = returnasdate(item.DATEDISP),
APPNAME = item?.APPNAME,
OFFICER = item?.OFFICER,
DATEREG = item.DATEREG
});
}
switch (sortOrder)
{
case "DispDate":
TransactionList = TransactionList.OrderBy(x => x.DATEDISP).ToList();
break;
case "RefNo":
TransactionList = TransactionList.OrderBy(t => t.REFNO).ToList();
break;
case "RefNo_desc":
TransactionList = TransactionList.OrderByDescending(t => t.PROCESS.CATEGORY.DETAIL).ToList();
break;
case "Cat":
TransactionList = TransactionList.OrderBy(t => t.PROCESS.CATEGORY.DETAIL).ToList();
break;
case "Cat_desc":
TransactionList = TransactionList.OrderByDescending(t => t.REFNO).ToList();
break;
default:
TransactionList = TransactionList.OrderByDescending(t => t.DATEDISP).ToList();
break;
}
int pageSize = 6;
int pageNumber = (page ?? 1);
return View(TransactionList.ToPagedList(pageNumber, pageSize));
}
SearchTransacModel
是用于包含搜索参数的模型,因为我将它们传递给控制器。
当我通过提交按钮提交搜索表单时,它工作正常,我使用ViewBag
将此搜索条件发送回视图:ViewBag.currentFilter = searchModel;
但是当我点击任何排序操作链接时,我会丢失搜索参数。当我到达控制器时,currentFilter
为空。
我将currentFilter作为查询字符串传递,并将搜索模型分配给它,就像在这种情况下一样:
@Html.ActionLink("Reference No", "Index", new { sortOrder = ViewBag.RefNoSortParm, currentFilter = ViewBag.CurrentFilter })
有人可以帮忙吗?我是MVC btw的新人。
答案 0 :(得分:3)
您无法将视图中的值传递回控制器。
相反,您应该在视图中使用模型绑定将信息传递给post方法。
答案 1 :(得分:3)
您可以使用此类操作:
public ActionResult Index(SearchModel searchModel, string sortColumn, string sortOrder)
{
ViewBag.SearchModel = searchModel;
ViewBag.SortColumn= sortColumn;
ViewBag.SortOrder = sortOrder;
var business = new BusinessLogic();
var model = business.Search(searchModel, sortColumn, sortOrder);
return View(model);
}
您可以通过这种方式简单地混合一些路线值。这样,搜索选项和排序选项都将保留在请求之间:
@{
var routeValues = new RouteValueDictionary(ViewBag.SearchModel ?? new { });
routeValues["sortColumn"] = ViewBag.SortColumn;
routeValues["sortOrder"] = ViewBag.SortOrder;
}
@Html.ActionLink("Link Text", "Action", routeValues);
注意:强>
根据这个答案中的想法,你可以简单地创建一个方法,它甚至可以混合2个对象来为你创建路线值。
您还可以将排序选项封装在SortOption
类中,并将其放在ViewBag
中并在模型绑定中使用它。
System.Linq.Dynamic
将帮助您获得更加动态,干净的排序代码。
要详细了解此类SearchModel
和BusinessLogic
技术的优势,请查看Filter/Search using Multiple Fields - ASP.NET MVC
此要求的常见方案是,例如,网页的页面链接或网格的列链接,显示搜索和排序的结果。如果您在网格上使用此技术,则分页链接应保留搜索选项并在请求之间排序选项。但是为了生成列标题链接,对于每个列,您应该使用不同的合适排序顺序和排序列;对于其名称等于当前排序列的列,排序顺序应与当前排序顺序相反。列标题也应该保留页面索引。
答案 2 :(得分:0)
从viewbag读取后,您可以在查询字符串中传递过滤器值。假设您的SearchTransacModel
课程具有DATEDISPFROM
和OFFICERNAME
属性,
public class SearchTransacModel
{
public string DATEDISPFROM { set; get; }
public string OFFICERNAME { set; get; }
}
您可以将值作为路由值发送,其中键将是属性名称(SearchTransacModel类),值将是您拥有的值。
@{
var filter = ViewBag.CurrentFilter as SearchTransacModel;
}
@Html.ActionLink("Reference No", "Index", new { sortOrder = ViewBag.RefNoSortParm,
DATEDISPFROM = filter!=null? filter.DATEDISPFROM:"",
OFFICERNAME = filter != null ? filter.OFFICERNAME : "" })
模型绑定器将能够将查询字符串值映射到您的currentFilter
对象。
我建议您不要使用相同类型的2个参数(currentFilter&amp; searchModel)。
答案 3 :(得分:0)
虽然可以使用 ViewBag 来实现您的目标,但它仍然不是为此而设计的。
相反,您应该创建一个模型并使用它与您的控制器和视图进行通信。
将您的退货模式更改并对齐得更大。
public TransactionsViewModel
{
public SearchTransacModel SearchModel { get; set; }
public List<TransacViewModel> TransactionList { get; set; }
}
现在您可以放弃使用 ViewBag.currentFilter 并仅使用此模型。