C# ASP.NET MVC вернуться на предыдущую страницу
у меня есть основной метод редактирования в моем контроллере, который перенаправляет обратно в список верхнего уровня ("индекс"), когда редактирование завершается успешно. Стандартное поведение после лесов MVC.
Я пытаюсь изменить этот метод изменить, чтобы перенаправить обратно на предыдущую страницу (не Индекс). Поскольку мой метод редактирования не использовал сопоставленный по умолчанию входной параметр "id", я сначала попытался использовать его для передачи в предыдущем URL.
в моем методе редактирования "get" я использовал эту строку, чтобы захватить предыдущий URL и он работал нормально:
ViewBag.ReturnUrl = Request.UrlReferrer;
затем я отправил этот URL-адрес возврата в метод редактирования "post", используя мой тег формы следующим образом:
@using (Html.BeginForm(new { id = ViewBag.ReturnUrl }))
теперь это место, где колеса отвалились. Я не смог правильно проанализировать URL-адрес из параметра id.
*** ОБНОВЛЕНИЕ: РЕШЕНО ***
используя пример Гарри в качестве руководства, я изменил свой параметр с " id " на "returnUrl" и использовал скрытое поле для передачи параметра (вместо тега form). Урок усвоен: используйте только параметр "id", как он должен был использоваться, и держите его простым. Теперь это работает. Вот мой обновленный код с Примечания:
во-первых, я хватаю предыдущий URL с помощью запроса.UrlReferrer, как я сделал в первый раз.
//
// GET: /Question/Edit/5
public ActionResult Edit(int id)
{
Question question = db.Questions.Find(id);
ViewBag.DomainId = new SelectList(db.Domains, "DomainId", "Name", question.DomainId);
ViewBag.Answers = db.Questions
.AsEnumerable()
.Select(d => new SelectListItem
{
Text = d.Text,
Value = d.QuestionId.ToString(),
Selected = question.QuestionId == d.QuestionId
});
// Grab the previous URL and add it to the Model using ViewData or ViewBag
ViewBag.returnUrl = Request.UrlReferrer;
ViewBag.ExamId = db.Domains.Find(question.DomainId).ExamId;
ViewBag.IndexByQuestion = string.Format("IndexByQuestion/{0}", question.QuestionId);
return View(question);
}
и теперь я передаю параметр returnUrl из модели в метод [HttpPost], используя скрытое поле в виде:
@using (Html.BeginForm())
{
<input type="hidden" name="returnUrl" value="@ViewBag.returnUrl" />
...
в [HttpPost] метод мы вытаскиваем параметр из скрытого поля и перенаправляем на него....
//
// POST: /Question/Edit/5
[HttpPost]
public ActionResult Edit(Question question, string returnUrl) // Add parameter
{
int ExamId = db.Domains.Find(question.DomainId).ExamId;
if (ModelState.IsValid)
{
db.Entry(question).State = EntityState.Modified;
db.SaveChanges();
//return RedirectToAction("Index");
return Redirect(returnUrl);
}
ViewBag.DomainId = new SelectList(db.Domains, "DomainId", "Name", question.DomainId);
return View(question);
}
1 ответ:
Я предполагаю (поправьте меня, если я ошибаюсь), что вы хотите, чтобы повторно отобразить страницу редактирования, если редактирование не удается, и для этого вы используете редирект.
вы можете иметь больше удачи, просто возвращая представление снова, а не пытаться перенаправить пользователя, таким образом, Вы сможете использовать ModelState для вывода любых ошибок тоже.
Edit:
обновление на основе обратной связи. Вы можете поместить предыдущий URL-адрес в viewModel, добавить его в скрытый поле затем использовать его снова в действии, которое сохраняет изменения.
например:
public ActionResult Index() { return View(); } [HttpGet] // This isn't required public ActionResult Edit(int id) { // load object and return in view ViewModel viewModel = Load(id); // get the previous url and store it with view model viewModel.PreviousUrl = System.Web.HttpContext.Current.Request.UrlReferrer; return View(viewModel); } [HttpPost] public ActionResult Edit(ViewModel viewModel) { // Attempt to save the posted object if it works, return index if not return the Edit view again bool success = Save(viewModel); if (success) { return Redirect(viewModel.PreviousUrl); } else { ModelState.AddModelError("There was an error"); return View(viewModel); } }
метод BeginForm для вашего представления также не должен использовать этот URL-адрес возврата, вы должны быть в состоянии уйти с:
@model ViewModel @using (Html.BeginForm()) { ... <input type="hidden" name="PreviousUrl" value="@Model.PreviousUrl" /> }
возвращаясь к публикации действия формы на неправильный URL-адрес, это связано с тем, что вы передаете URL-адрес в качестве параметра "id", поэтому маршрутизация автоматически форматирует Ваш URL-адрес с обратным путем.
это не будет работать, потому что ваш форма будет отправлена в действие контроллера, которое не будет знать, как сохранить изменения. Сначала вам нужно опубликовать свое действие сохранения, а затем обработать перенаправление в нем.