ASP.NET MVC: UrlReferrer или куда послать пользователя
Сайтостроение | создано: 26.03.2013 | опубликовано: 27.03.2013 | обновлено: 13.01.2024 | просмотров: 12425 | всего комментариев: 2
Не редко возникает потребность перенаправить пользователя на страницу, с которой он пришел. Например, вы просматриваете список записей и уже дошли до 13-ой страницы, нажимаете редактировать запись номер 138. И скорее всего после сохранения изменений вы захотите вернуться именно на 13 страницу списка. Не так ли?!
Задача на статью
Предыстория описана в описании статьи, а значит сразу к делу. Чтобы вернуть пользователя “обратно”. Надо знать откуда он пришел. Самый просто способ это сделать – использовать
HttpContext.Request.UrlReferrer
А чтобы не писать его создадим кое-какой класс или несколько. Итак первым делом, создадим атрибут (класс) ReferrerHoldAttribute, который унаследуем от ActionFilterAttribute:
public class ReferrerHoldAttribute : ActionFilterAttribute {
public override void OnActionExecuting(ActionExecutingContext filterContext) {
var referrer = filterContext.RequestContext.HttpContext.Request.UrlReferrer;
if (referrer != null) {
filterContext.RouteData.Values.Add("referrer", referrer);
}
base.OnActionExecuting(filterContext);
}
}
Думаю, пояснений не требуется. Далее просто будем его использовать. Для того чтобы “понять” откуда пришел пользователь, надо поставить атрибут над методом контролера. А затем просто его использовать:
[ReferrerHold]
public ActionResult Edit(int id) {
var product = _smart.Products.GetById(id);
if (product != null) {
TempData["referrer"] = ControllerContext.RouteData.Values["referrer"];
FillGeneralDictionaries();
var model = product.MapTo<Product, ProductShowViewModel>();
return View(model);
}
return RedirectToAction("http404", "error");
}
В первой строке поставили, далее в TempData[“referrer”] запихнули значение полученное из маршрута. А потом из POST-метода вызвали Redirect, чтобы перекинуть пользователя обратно:
[HttpPost]
public ActionResult Edit(ProductViewModel model) {
if (ModelState.IsValid) {
var product = _smart.Products.GetById(model.Id);
Mapper.Map(model, product);
product.UpdatedAt = DateTime.Now;
product.UpdatedBy = User.Identity.Name;
_smart.Products.Update(product);
_smart.Logs.Log("Новый товар \"{0}\" успешно изменен", model.Name);
_smart.Commit();
if (TempData["referrer"] != null) {
return Redirect(TempData["referrer"].ToString()); //"all", "catalog");
}
return RedirectToRoute("Catalog");//"all", "catalog");
}
FillGeneralDictionaries();
return View(model);
}
Здесь тоже обойдемся без пояснений.
Развитие темы
Что можно предложить в продолжение темы. Дальше можно сделать свой собственный ActionResult, обозвав его, например, ReferrerResult, и унаследовав от базового класса реализовать обработку:
ControllerContext.RouteData.Values["referrer"];
Или также можно сделать базовый контролер, который всегда будет “знать кто, куда и откуда пришел”.
Заключение
Большое количество поступающих вопросов относительно озвученной тему породило данную статью, которая получилась короткой в силу своей тривиальности.
Комментарии к статье (2)
Не понятно, с какой целью вводится ReferrerHoldAttribute
Вводится с целью показать как работают аттрибуты. Не самый полезный класс, но зато понятен принцип и направление дальнейших действий.