Ich habe eine grundlegende Bearbeitungsmethode in meinem Controller, die nach erfolgreicher Bearbeitung zu einer Liste der obersten Ebene („Index“) zurückleitet. Standardverhalten nach MVC-Gerüsten.
Ich versuche, diese Bearbeitungsmethode zu ändern, um zur vorherigen Seite (nicht zum Index) zurückzukehren. Da meine Edit-Methode nicht den standardmäßig zugeordneten Eingabeparameter "id" verwendete, habe ich zuerst versucht, damit die vorherige URL zu übergeben.
Bei meiner Edit-Methode "get" habe ich diese Zeile verwendet, um die vorherige URL abzurufen, und es hat einwandfrei funktioniert:
ViewBag.ReturnUrl = Request.UrlReferrer;
Ich habe diese Rückgabe-URL dann mithilfe meines Formular-Tags wie folgt an die Methode "Post" bearbeiten gesendet:
@using (Html.BeginForm(new { id = ViewBag.ReturnUrl }))
Hier fielen die Räder ab. Ich konnte die URL vom ID-Parameter nicht richtig analysieren.
***. UPDATE: Gelöst ** *
Am Beispiel von Garry habe ich meinen Parameter von "id" in "returnUrl" geändert und ein verstecktes Feld verwendet, um meinen Parameter zu übergeben (anstelle des Formular-Tags). Lektion gelernt: Verwenden Sie den Parameter "id" nur so, wie er verwendet werden sollte, und halten Sie ihn einfach. Es funktioniert jetzt. Hier ist mein aktualisierter Code mit Notizen:
Zuerst greife ich mit Request.UrlReferrer wie beim ersten Mal auf die vorherige URL zurück.
//
// 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);
}
und ich übergebe jetzt den Parameter returnUrl vom Modell an die Methode [HttpPost] unter Verwendung eines ausgeblendeten Feldes in der Form:
@using (Html.BeginForm())
{
<input type="hidden" name="returnUrl" value="@ViewBag.returnUrl" />
...
In der [HttpPost] -Methode ziehen wir den Parameter aus dem ausgeblendeten Feld und leiten ihn dorthin weiter ....
//
// 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);
}
quelle
id
, würde ich es nicht verwenden, um eine URL zu übergeben. Das scheint ein Hack zu sein, und ich bin sicher, es gibt einen besseren Weg, dies zu tun.Antworten:
Ich gehe davon aus (bitte korrigieren Sie mich, wenn ich falsch liege), dass Sie die Bearbeitungsseite erneut anzeigen möchten, wenn die Bearbeitung fehlschlägt, und verwenden Sie dazu eine Umleitung.
Möglicherweise haben Sie mehr Glück, wenn Sie die Ansicht erneut zurückgeben, anstatt zu versuchen, den Benutzer umzuleiten. Auf diese Weise können Sie den ModelState auch zur Ausgabe von Fehlern verwenden.
Bearbeiten:
Aktualisiert basierend auf Feedback. Sie können die vorherige URL in das viewModel einfügen, sie einem ausgeblendeten Feld hinzufügen und sie dann erneut in der Aktion verwenden, in der die Änderungen gespeichert werden.
Zum Beispiel:
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); } }
Die BeginForm-Methode für Ihre Ansicht muss diese Rückgabe-URL ebenfalls nicht verwenden. Sie sollten in der Lage sein, Folgendes zu erreichen:
@model ViewModel @using (Html.BeginForm()) { ... <input type="hidden" name="PreviousUrl" value="@Model.PreviousUrl" /> }
Wenn Sie zu Ihrer Formularaktion zurückkehren und eine falsche URL veröffentlichen, übergeben Sie eine URL als Parameter 'id', sodass das Routing Ihre URL automatisch mit dem Rückgabepfad formatiert.
Dies funktioniert nicht, da Ihr Formular an eine Controller-Aktion gesendet wird, die nicht weiß, wie die Änderungen gespeichert werden sollen. Sie müssen zuerst in Ihrer Speicheraktion posten und dann die darin enthaltene Umleitung durchführen.
quelle
redirectToAction
kann auch Parameter, Controller-Action-Variablen nehmen.Für ASP.NET Core Sie können das Attribut asp-route- * verwenden:
<form asp-action="Login" asp-route-previous="@Model.ReturnUrl">
Ein Beispiel: Stellen Sie sich vor, Sie haben einen Fahrzeugcontroller mit Aktionen
Index
Einzelheiten
Bearbeiten
und Sie können jedes Fahrzeug über den Index oder über Details bearbeiten. Wenn Sie also auf Bearbeiten aus Index klicken, müssen Sie nach der Bearbeitung zum Index zurückkehren. Wenn Sie auf Details bearbeiten klicken, müssen Sie nach der Bearbeitung zu den Details zurückkehren.
//In your viewmodel add the ReturnUrl Property public class VehicleViewModel { .............. .............. public string ReturnUrl {get;set;} } Details.cshtml <a asp-action="Edit" asp-route-previous="Details" asp-route-id="@Model.CarId">Edit</a> Index.cshtml <a asp-action="Edit" asp-route-previous="Index" asp-route-id="@item.CarId">Edit</a> Edit.cshtml <form asp-action="Edit" asp-route-previous="@Model.ReturnUrl" class="form-horizontal"> <div class="box-footer"> <a asp-action="@Model.ReturnUrl" class="btn btn-default">Back to List</a> <button type="submit" value="Save" class="btn btn-warning pull-right">Save</button> </div> </form>
In Ihrem Controller:
// GET: Vehicle/Edit/5 public ActionResult Edit(int id,string previous) { var model = this.UnitOfWork.CarsRepository.GetAllByCarId(id).FirstOrDefault(); var viewModel = this.Mapper.Map<VehicleViewModel>(model);//if you using automapper //or by this code if you are not use automapper var viewModel = new VehicleViewModel(); if (!string.IsNullOrWhiteSpace(previous) viewModel.ReturnUrl = previous; else viewModel.ReturnUrl = "Index"; return View(viewModel); } [HttpPost] public IActionResult Edit(VehicleViewModel model, string previous) { if (!string.IsNullOrWhiteSpace(previous)) model.ReturnUrl = previous; else model.ReturnUrl = "Index"; ............. ............. return RedirectToAction(model.ReturnUrl); }
quelle
Ich weiß, dass dies sehr spät ist, aber vielleicht hilft das jemand anderem.
Ich benutze eine Schaltfläche Abbrechen, um zur verweisenden URL zurückzukehren. Versuchen Sie in der Ansicht Folgendes hinzuzufügen:
@{ ViewBag.Title = "Page title"; Layout = "~/Views/Shared/_Layout.cshtml"; if (Request.UrlReferrer != null) { string returnURL = Request.UrlReferrer.ToString(); ViewBag.ReturnURL = returnURL; } }
Dann können Sie Ihre Schaltflächen wie folgt einstellen:
<a href="@ViewBag.ReturnURL" class="btn btn-danger">Cancel</a>
Davon abgesehen funktioniert das Update von Jason Enochs hervorragend!
quelle
Hier ist nur eine weitere Option, die Sie für ASP NET MVC anwenden können.
Normalerweise sollten Sie
BaseController
für jedeController
Klasse eine Klasse verwenden.Gehen Sie also innerhalb der Konstruktormethode wie folgt vor.
public class BaseController : Controller { public BaseController() { // get the previous url and store it with view model ViewBag.PreviousUrl = System.Web.HttpContext.Current.Request.UrlReferrer; } }
Und jetzt in jeder Ansicht, die Sie mögen können
<button class="btn btn-success mr-auto" onclick=" window.location.href = '@ViewBag.PreviousUrl'; " style="width:2.5em;"><i class="fa fa-angle-left"></i></button>
Genießen!
quelle