2011-06-25 37 views
12

Estoy estudiando para obtener un certificado de MS (70-515).
Estoy confundido con lo que encuentro en línea y lo que leo en una prueba de práctica.
Algunas preguntas sobre SO indican que el uso de un RedirectToAction está enviando al navegador un 302, lo que provoca que cambie su url en la barra de direcciones.Confusión entre Redirect y RedirectToAction

Pero esta es una pregunta de 1 de las pruebas de la práctica:

PREGUNTA:

El controlador principal MVC actualmente tiene sólo la acción Índice defecto. El código relevante se muestra en el siguiente ejemplo de código.

public ActionResult Index() 
{ 
    ViewData["Message"] = "Hello!"; 
    return View(); 
} 

Es necesario crear una acción llamada FindID que muestra el parámetro ID introducido como parte de la ruta. Si la ruta de acceso no incluye un parámetro de ID, ASP.NET debe procesar la acción de índice sin cambiar la URL en la barra de direcciones del navegador y no debe lanzar una excepción. ¿Qué segmento de código debe usar?

RESPUESTA CORRECTA:

public ActionResult FindID(int? id) 
{ 
    if (!id.HasValue) 
     return RedirectToAction("Index"); 
    ViewData["Message"] = "ID is " + id.ToString(); 
    return View(); 
} 

EXPLICACIÓN:

Usted puede utilizar el formulario de RedirectToAction ActionResult para causar MVC para procesar una acción diferente desde el interior de una acción. MVC abandona la acción actual y procesa la solicitud como si la ruta hubiera conducido directamente a la acción a la que redirecciona. Básicamente, esto es equivalente a llamar a Server.Transfer en una aplicación ASP.NET estándar.

Redirect ActionResult envía una respuesta "HTTP Error 302 - Found" al navegador, lo que hace que el navegador cargue la URL especificada. Esto cambia la dirección que aparece en la barra de direcciones.

Así:
- ¿Un RedirectToAction dejar la URL en el navegador sin tocar?
- ¿Redirect cambia la URL en el navegador?
- ¿Es correcta la explicación de la prueba de práctica? De eso entiendo que RedirectToAction NO hace un 302.

+1

bien, entonces parece que lo que está escrito en la prueba de práctica de certificación es INCORRECTO (¡horrible!). No hubo respuesta correcta disponible. Me pregunto qué debería hacer si obtengo exactamente esa pregunta en el examen. Supongo que responderé lo mismo que ahora está marcado como correcto en la prueba. – TweeZz

Respuesta

9

Puede usar la forma RedirectToAction de ActionResult para hacer que MVC procese una acción diferente desde dentro de una acción. MVC abandona la acción actual y procesa la solicitud como si la ruta hubiera conducido directamente a la acción a la que redirecciona. Básicamente, esto es equivalente a llamar a Server.Transfer en una aplicación ASP.NET estándar.

Esto es incorrecto.

Tanto el RedirectToRouteResult (RedirectToAction) como el RedirectResult realizan un redireccionamiento 302, lo que provoca que cambie la URL del navegador.

vuelta el resultado Índice sin cambiar la URL del código en realidad sería:

public ActionResult FindID(int? id) 
{ 
    if (!id.HasValue) 
     return View("index"); 
    ViewData["Message"] = "ID is " + id.ToString(); 
    return View(); 
} 

Sin embargo, no habría recomendado este enfoque. Si realizo una solicitud a mysite.com/products/some-product y some-product no existe, entonces debo informar al usuario de eso con el código de estado relevante (también importante para los motores de búsqueda).

Si el único propósito de su acción FindID es hacer algo con el parámetro id, entonces no debe ser nulo/opcional. De esta forma, la acción FindID no se invocaría si no se especificara una ID.

+1

si RedirectToAction! = Server.Transfer, ¿cómo haría un Server.Transfer en MVC? – TweeZz

+0

@TweeZz: no tiene que realizar una transferencia ya que todavía no está en la vista. Simplemente devuelve un ActionResult diferente del controlador para usar una vista diferente. – Guffa

+0

Bien, cuento largo: RedirectToAction y Redirect do a 302, RedirectToAction simplemente le permite no escribir una URL completa usted mismo, sino especificar una acción. Internamente es exactamente lo mismo. ¿Derecha? – TweeZz

9

La documentación para el método RedirectToAction nos dice que si envía una respuesta 302:

"devuelve una respuesta HTTP 302 para el navegador, lo que hace que el navegador para realizar una solicitud GET a la acción especificada. "

Examinar el código en el archivo DLL revela que lo hace devolver un objeto RedirectToRouteResult, lo que provoca una redirección, por lo que la documentación es correcta:

protected internal virtual RedirectToRouteResult RedirectToAction(string actionName, string controllerName, RouteValueDictionary routeValues) { 
    RouteValueDictionary routeValueDictionaries; 
    if (this.RouteData == null) { 
    routeValueDictionaries = RouteValuesHelpers.MergeRouteValues(actionName, controllerName, null, routeValues, true); 
    } else { 
    routeValueDictionaries = RouteValuesHelpers.MergeRouteValues(actionName, controllerName, this.RouteData.Values, routeValues, true); 
    } 
    return new RedirectToRouteResult(routeValueDictionaries); 
} 

La respuesta correcta a la pregunta de la prueba sería utilizar un punto de vista diferente:

public ActionResult FindID(int? id) { 
    if (!id.HasValue) { 
    ViewData["Message"] = "Hello!"; 
    return View("Index"); 
    } 
    ViewData["Message"] = "ID is " + id.ToString(); 
    return View(); 
} 

Esto utilizará la vista Index, en lugar de la vista FindID que es devuelto por la llamada sin parámetros View().

+1

Encuentro que todo esto es súper confuso :( – TweeZz

+1

Pitty No puedo marcar 2 respuestas como correctas .. – TweeZz