2012-06-26 23 views
40

En el RedirectToAction a continuación, me gustaría pasar un viewmodel. ¿Cómo paso el modelo a la redirección?¿Cómo incluyo un modelo con RedirectToAction?

Establecí un punto de interrupción para verificar los valores del modelo y verificar que el modelo se haya creado correctamente. Es correcto, pero la vista resultante no contiene los valores encontrados en las propiedades del modelo.

// 
// model created up here... 
// 
return RedirectToAction("actionName", "controllerName", model); 

ASP.NET MVC 4 RC

+2

Me tomó un enfoque simple como esto => Regresar ver ("actionName ", modelo); – xameeramir

Respuesta

66

RedirectToAction devuelve una respuesta 302 al navegador del cliente y por lo tanto el navegador hará una nueva solicitud GET a la URL en el valor de encabezado localización de la respuesta llegó a la navegador.

Si está intentando pasar un modelo simple de vista plana al segundo método de acción, puede usar this overload del método RedirectToAction.

protected internal RedirectToRouteResult RedirectToAction(
    string actionName, 
    string controllerName, 
    object routeValues 
) 

El RedirectToAction convertirá el objeto pasado (routeValues) a una cadena de consulta y añadir que a la URL (generado a partir de los 2 primeros parámetros que pasamos) y Will incrustar el URL resultante en la cabecera location de la respuesta .

Supongamos que su modelo de vista es como esto

public class StoreVm 
{ 
    public int StoreId { get; set; } 
    public string Name { get; set; } 
    public string Code { set; get; } 
} 

Y en su primer método de acción, se puede pasar un objeto de esta con el método RedirectToAction como esto

var m = new Store { StoreId =101, Name = "Kroger", Code = "KRO"}; 
return RedirectToAction("Details","Store", m); 

Este código envíe una respuesta 302 al navegador con el valor del encabezado de ubicación como

Store/Details?StoreId=101&Name=Kroger&Code=KRO 

Suponiendo que el parámetro del método de acción Details es del tipo StoreVm, los valores del parámetro de cadena de consulta se correlacionarán correctamente con las propiedades del parámetro.

public ActionResult Details(StoreVm model) 
{ 
    // model.Name & model.Id will have values mapped from the request querystring 
    // to do : Return something. 
} 

Lo anterior funcionará para aprobar el modelo de vista plana pequeña. Pero si quiere pasar un objeto complejo, debe intentar seguir el patrón PRG.

Patrón PRG

PRG significa POSTAL - REDIRECT - GET. Con este enfoque, emitirá una respuesta de redireccionamiento con una identificación única en la cadena de consulta, con la cual el segundo método de acción GET puede consultar nuevamente el recurso y devolver algo a la vista.

int newStoreId=101; 
return RedirectToAction("Details", "Store", new { storeId=newStoreId}); 

Esto creará la url Store/Details?storeId=101 y en su acción Detalles GET, utilizando el StoreID aprobada en, obtendrá/construcción del objeto StoreVm de algún lugar (de un servicio o la consulta de la base de datos, etc.)

public ActionResult Details(string storeId) 
{ 
    // from the storeId value, get the entity/object/resource 
    var store = yourRepo.GetStore(storeId); 
    if(store!=null) 
    { 
     // Map the the view model 
     var storeVm = new StoreVm { Id=storeId, Name=store.Name,Code=store.Code}; 
     return View(storeVm); 
    } 
    return View("StoreNotFound"); // view to render when we get invalid store id 
} 

TempData

Tras la PRG pattern es una mejor solución para manejar este caso de uso. Pero si usted no quiere hacer eso y quiere pasar algunos datos complejos a través de sin estado HTTP solicitudes de verdad, es posible utilizar algún mecanismo de almacenamiento temporal, como TempData

TempData["NewCustomer"] = model; 
return RedirectToAction("Index", "Users"); 

y leerlo en su método de acción GET nuevo .

public ActionResult Index() 
{  
    var model=TempData["NewCustomer"] as Customer 
    return View(model); 
} 

TempData utiliza Session objeto detrás de la escena para almacenar los datos. Pero una vez que se leen los datos, los datos se terminan.

Rachel ha escrito un buen blog post explicando cuándo usar TempData/ViewData. Vale la pena leer.

Usando TempData para pasar los datos del modelo a una solicitud de redirección en Asp.Net Core

En Asp.Net núcleo, no se puede pasar tipos complejos en TempData. Puede pasar tipos simples como string, int, Guid etc.

Si desea pasar absolutamente un objeto de tipo complejo a través de TempData, tiene 2 opciones.

1) Serialice su objeto a una cadena y páselo.

Aquí es una muestra usando Json.NET para serializar el objeto a una cadena

var s = Newtonsoft.Json.JsonConvert.SerializeObject(createUserVm); 
TempData["newuser"] = s; 
return RedirectToAction("Index", "Users"); 

En su método de acción Index, leer este valor de la TempData y deserializar a su objeto CreateUserViewModel clase.

public IActionResult Index() 
{ 
    if (TempData["newuser"] is string s) 
    { 
     var newUser = JsonConvert.DeserializeObject<CreateUserViewModel>(s); 
     // use newUser object now as needed 
    } 
    // to do : return something 
} 

2) Establecer un diccionario de tipos simples para TempData

var d = new Dictionary<string, string> 
{ 
    ["FullName"] = rvm.FullName, 
    ["Email"] = rvm.Email; 
}; 
TempData["MyModelDict"] = d; 
return RedirectToAction("Index", "Users"); 

y leerlo después

public IActionResult Index() 
{ 
    if (TempData["MyModelDict"] is Dictionary<string,string> dict) 
    { 
     var name = dict["Name"]; 
     var email = dict["Email"]; 
    } 
    // to do : return something 
} 
Cuestiones relacionadas