То, что я сделал для таких случаев, которые я нахожу простым, но мощным, сериализовало мой объект модели представления в JSON (в вашем случае SearchViewModel
), используя что-то вроде NewtonSoft JSON.net затем с полученной строкой JSON выполните простое сжатие строки с помощью класса zlib.net Zlib.DeflateStream
(вы также можете использовать что-то вроде AES Rijndael , но, несомненно, медленнее и вам нужна скорость в первую очередь), а затем передайте полученную строку Base64 через QueryString.
Затем, когда вы будете готовы использовать его снова (фактически это состояние представления), просто распакуйте строку JSON и десериализовайте ее из JSON в соответствующий объект .NET (снова в вашем случае SearchViewModel
).
Сработал для меня, и вы не получите URL-адрес, который является неуправляемым, или каких-либо реальных ощутимых воздействий на производительность, которые я видел только при сериализации нескольких полей формы.
Я скоро уточню пример кода.
ОБНОВЛЕНИЕ: Примеры кода ...
Вот что я бы сделал в вашем конкретном сценарии:
В Results(string, SearchViewModel)
действие:
public ActionResult Results(string encryptedUrlViewModel, string game, SearchViewModel vm)
{
SearchViewModel searchUrlViewModel = null;
if (!string.IsNullOrEmpty(searchUrl)) {
// only first submission, no url view model set yet, so compress it and store..
encryptedUrlViewModel = Convert.ToBase64String(
DeflateStream.CompressString(JsonConvert.SerializeObject(vm)));
ViewBag.EncryptedUrlViewModel = encryptedUrlViewModel;
}
else {
var jsonUrlViewModel = DeflateStream.UncompressString(Convert.FromBase64String(encryptedUrlViewModel));
searchUrlViewModel = JsonConvert.DeserializeObject(jsonUrlViewModel, typeof(SearchViewModel)) as SearchViewModel;
// at this point you should have a serialized 'SearchViewModel' object
// ready to use which you can then tweak your query below with.
}
var matches = _repository.AsQueryable()
.ColorOr(vm.Colors)
.WhereIf(vm.Name.IsNotEmpty(), x => x.Name.Contains(vm.Name.Trim()));
return View(matches.ToPagedList(1, 10));
}
На виду:
@Html.PagedListPager((IPagedList)Model, page => Url.Action("Results", new { encryptedUrlViewModel = ViewBag.EncryptedUrlViewModel }))
Код может потребовать некоторых настроек, непроверенных в вашем сценарии, но это будет что-то вроде этого, удачи:)
Однако вы должны подумать, что если вы хотите перенести запрос пользователя в URL через пейджинг, тогда можно подумать, почему форма не была создана как запрос GET
, а не как запрос POST
в первое место. По какой-то причине вы особенно хотели это POST
? Я думаю, GET
будет правильно переносить ваш массив Colors
, но убедитесь, что ваша модель представления настроена правильно. См. Эту статью в Haacked для привязки модели к спискам .