2012-03-19 24 views
54

Mam podstawową metodę edycji w moim kontrolerze, która przekierowuje z powrotem do listy najwyższego poziomu ("Indeks"), gdy edycja się powiedzie. Standardowe zachowanie po rusztowaniu MVC.C# ASP.NET MVC Powróć do poprzedniej strony

Próbuję zmienić tę metodę edycji, aby przekierować z powrotem na poprzednią stronę (nie indeks). Ponieważ moja metoda edycji nie korzystała z domyślnego zmapowanego parametru wejściowego "id", najpierw spróbowałem użyć tego do przekazania poprzedniego adresu URL.

W moim Edycja metody „get”, użyłem tej linii chwycić poprzedni adres URL i to działało w porządku:

ViewBag.ReturnUrl = Request.UrlReferrer; 

Potem wysłał zwrotny adres URL do edycji „post” metody za pomocą mojego formularza w ten sposób:

@using (Html.BeginForm(new { id = ViewBag.ReturnUrl })) 

To tutaj odpadły koła. Nie można poprawnie pobrać adresu URL z parametru id.

*** UPDATE: SOLVED ** *

Korzystanie przykład Garry jako przewodnika, zmieniłem parametr z "id" do "i" returnUrl stosowany ukryty pole do przekazania mojego parametru (zamiast tagu formularza). Lekcja: należy używać tylko parametru "id", w jaki sposób ma być używany i zachować proste. Teraz działa. Oto mój zaktualizowany kod z uwagami:

Po pierwsze, pobieram poprzedni adres URL za pomocą Request.UrlReferrer, tak jak zrobiłem to po raz pierwszy.

// 
    // 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); 
    } 

i teraz przekazać parametr ReturnURL z modelu do metody [HttpPost] za pomocą ukrytego pola formularza:

@using (Html.BeginForm()) 
{ 
    <input type="hidden" name="returnUrl" value="@ViewBag.returnUrl" /> 
    ... 

W metodzie [HttpPost] możemy wyciągnąć parametr z ukryte pole i przekierowanie do niego ....

// 
    // 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

Nawet jeśli nie używasz 'id', nie użyłbym go do przekazania adresu URL. To wygląda na włamanie i jestem pewien, że jest lepszy sposób na zrobienie tego. –

+0

Tak, Eirc masz rację. Używałem brzydkiego hacka. To moja pierwsza aplikacja MVC. Próbowałem wielu rzeczy i czytałem wiele postów, a hack był moją najlepszą próbą. Naprawiłem to na przykładzie Gary'ego. Dzięki, –

Odpowiedz

44

jestem zakładając (proszę mnie poprawić, jeśli się mylę), że chcesz, aby ponownie wyświetlić stronę edycji, jeśli nie powiedzie się i edycja tego używasz zrobić przekierowanie.

Możesz mieć więcej szczęścia, po prostu zwracając widok ponownie, niż próbując przekierować użytkownika, w ten sposób będziesz mógł używać ModelState do wyprowadzania jakichkolwiek błędów.

Edit:

aktualizowany w oparciu o informacje zwrotne. Możesz umieścić poprzedni URL w viewModelu, dodać go do ukrytego pola, a następnie użyć go ponownie w akcji, która zapisuje zmiany.

Na przykład:

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 RedirectToAction(viewModel.PreviousUrl); 
    } 
    else 
    { 
     ModelState.AddModelError("There was an error"); 
     return View(viewModel); 
    } 
} 

Sposób BeginForm dla widoku nie trzeba korzystać z tego powrotu URL albo, powinieneś być w stanie uciec z:

@model ViewModel 

@using (Html.BeginForm()) 
{ 
    ... 
    <input type="hidden" name="PreviousUrl" value="@Model.PreviousUrl" /> 
} 

Wracając do Wpisanie formularza w nieprawidłowy adres URL wynika z tego, że podajesz URL jako parametr "identyfikator", więc routing automatycznie formatuje Twój adres URL ze ścieżką zwrotną.

To nie zadziała, ponieważ formularz zostanie wysłany do kontrolera, który nie będzie wiedział, jak zapisać zmiany. Najpierw musisz wysłać do swojej akcji składowania, a następnie obsłużyć przekierowanie w niej.

+2

+1. + Więcej, gdybym mógł. – Fenton

+0

Tak, ale potrzebuję go do przekierowania z powrotem do poprzedniej strony, jeśli edycja się powiedzie. Myślę, że to nie działało, ponieważ używałem "id". Zmieniłem parametr na "url", jak pokazano poniżej i wygląda na to, że zadziałało w mojej pierwszej próbie, ale muszę przetestować to więcej .... trzymaj się i opublikuję to, co mam. Jestem nowy, aby publikować na tej stronie i podejmować temat, aby się do tego przyzwyczaić. –

+0

W takim przypadku możesz umieścić poprzedni adres URL w ViewBag przy początkowym ładowaniu strony edycji, a następnie umieścić go w ukrytym polu. Następnie możesz uzyskać do niego dostęp jako część swojego ViewModel w akcji post i przekierować do niego. Wolałbym coś takiego niż wysyłanie go za pośrednictwem zapytania. Jeśli chcesz podać przykład, daj mi znać. –

Powiązane problemy