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 58

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-адрес с обратным путем.

это не будет работать, потому что ваш форма будет отправлена в действие контроллера, которое не будет знать, как сохранить изменения. Сначала вам нужно опубликовать свое действие сохранения, а затем обработать перенаправление в нем.