Как я могу передать некоторые объекты в ViewBag к действию? - Сохранить параметры поиска, сортировки и подкачки
У меня есть представление, которое я показываю результат поиска и сортировать в выгруженном списке. Я добавляю заголовки столбцов как ссылки, чтобы пользователь мог сортировать по столбцу следующим образом:
<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, кстати.
4 ответа
Вы можете использовать такие действия:
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
техника взглянуть на фильтр / поиск с использованием нескольких полей - ASP.NET MVCРаспространенным сценарием для этого требования является, например, для ссылок на страницы пейджера или ссылок на столбцы сетки, в которой отображаются результаты поиска и сортировки. Если вы используете этот метод в сетке, ссылки на подкачку должны сохранять параметры поиска и параметры сортировки между запросами. Но для генерации ссылок на заголовки столбцов для каждого столбца следует использовать разные подходящие порядок сортировки и столбец сортировки; также для столбца, имя которого равно текущему столбцу сортировки, порядок сортировки должен быть обратным текущему порядку сортировки. Кроме того, заголовки столбцов также должны сохранять индекс страницы.
Вы не можете передать значение из вашей viewbag обратно в контроллер.
Вместо этого вы должны использовать привязку модели в своем представлении, чтобы передать информацию в ваш метод публикации.
Вы можете передать значения фильтра в строке запроса после чтения из 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 & searchModel).
Хотя ViewBag можно использовать для достижения того, что вы ищете, он по-прежнему не предназначен для этой цели.
Вместо этого вы должны создать модель и использовать ее для связи с вашим контроллером и представлением.
Измените и выровняйте свою модель возврата, чтобы она была немного больше.
public TransactionsViewModel
{
public SearchTransacModel SearchModel { get; set; }
public List<TransacViewModel> TransactionList { get; set; }
}
Теперь вы можете отказаться от использования ViewBag.currentFilter и использовать только эту модель.