2012-03-19 39 views
54

Tengo un método de edición básico en mi controlador que redirige a una lista de nivel superior ("Índice") cuando la edición tiene éxito. Comportamiento estándar después del andamiaje MVC.C# ASP.NET MVC Volver a la página anterior

Estoy tratando de cambiar este método de edición para redirigir a la página anterior (no índice). Como mi método de edición no usaba el parámetro de entrada mapeado predeterminado "id", primero intenté usarlo para pasar la URL anterior.

En mi método Edit “obtener”, que utiliza esta línea para agarrar la URL anterior y funcionó bien:

ViewBag.ReturnUrl = Request.UrlReferrer; 

luego envié este URL retorno al método de edición “post” mediante el uso de mi formulario etiqueta de esta manera:

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

Ahora aquí es donde las ruedas se cayeron. No pude analizar correctamente la URL del parámetro id.

*** ACTUALIZACIÓN: RESUELTO ** *

Usando el ejemplo de Garry como guía, he cambiado el parámetro de "id" a "ReturnURL" y se utiliza un oculto campo para pasar mi parámetro (en lugar de la etiqueta del formulario). Lección aprendida: solo use el parámetro "id" como estaba destinado a ser utilizado y manténgalo simple. Ahora funciona. Aquí está mi código actualizado con notas:

Primero, tomo la URL anterior usando Request.UrlReferrer como lo hice la primera vez.

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

y ahora pasa el parámetro ReturnURL del modelo para el método [HttpPost] utilizando un campo oculto en la forma:

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

En el método [HttpPost] tiramos del parámetro de la campo oculto y redirigir a ella ....

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

Incluso si no está usando 'id', no lo usaría para pasar una URL. Eso parece un truco, y estoy seguro de que hay una mejor manera de hacerlo. –

+0

Sí, Eirc estás en lo cierto. Estaba usando un hack feo. Esta es mi primera aplicación MVC. Probé muchas cosas y leí muchas publicaciones, y el truco fue mi mejor intento. Lo arreglé basándome en el ejemplo de Gary. Gracias, –

Respuesta

44

estoy asumiendo (por favor, corríjanme si me equivoco) que desea volver a visualizar la página de edición si la edición falla y para ello está utilizando una redirección

Puede tener más suerte simplemente devolviendo la vista de nuevo en lugar de tratar de redirigir al usuario, de esta manera podrá usar el modelo de estado para producir también cualquier error.

Editar:

actualizan con base en la retroalimentación. Puede colocar la URL anterior en viewModel, agregarla a un campo oculto y luego usarla de nuevo en la acción que guarda las ediciones.

Por ejemplo:

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

El método BeginForm para la vista no necesita usar esta URL de retorno o bien, usted debería ser capaz de salirse con la suya:

@model ViewModel 

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

Volviendo a su publicación de acción de formulario en una URL incorrecta, esto se debe a que está pasando una URL como el parámetro 'id', por lo que la ruta automáticamente formatea su URL con la ruta de retorno.

Esto no funcionará porque su formulario se publicará en una acción del controlador que no sabrá cómo guardar las ediciones. Primero debe publicar su acción de guardado, luego manejar la redirección dentro de ella.

+2

+1. + Más si pudiera. – Fenton

+0

Sí, pero necesito que lo redirija a la página anterior si la edición tiene éxito. Creo que no funcionaba porque estaba usando "id". Cambié el parámetro a "url" como se muestra a continuación y parece haber funcionado en mi primer intento, pero necesito probarlo más ... espere y publicaré lo que tengo. Soy nuevo en publicar en este sitio y tomar un tic para acostumbrarme. –

+0

En ese caso, puede colocar la URL anterior en el ViewBag al cargar inicialmente la página Editar, y luego colocarla en un campo oculto. Luego puede acceder a él como parte de su ViewModel en la acción posterior y redirigir a él. Preferiría algo como esto que enviarlo vía querystring. Si quieres un ejemplo, házmelo saber. –

Cuestiones relacionadas