2009-03-18 9 views
24

Tengo un código que guarda un ticket en nuestro sistema. Si hay un error, hace un RedirectToAction. El problema es que no parece tener mis errores en la nueva acción. ¿Cómo puedo arreglar esto?¿Cómo mantengo los errores de ModelState cuando uso RedirectToAction?

ModelState.AddModelError("_FORM", "Unable to save ticket"); 
ModelState.AddModelError("_FORM", "Phone number was invalid."); 
ModelState.AddModelError("_FORM", "Lane number is required."); 
return RedirectToAction("CreateStep", "Ticket"); 

Sé que algunos han sugerido el uso de TempData, pero ¿cómo puedo obtener cada error del ModelState?

Gracias.

Respuesta

-3

Creo que pierdes el estado de tu modelo cuando realizas una redirección. Tal vez usted podría reescribir su lógica a algo como:

public ActionResult Save() 
{ 
    // your code... 
    if(saveSucceeded) 
    { 
    return View("Saved"); 
    } 
    else 
    { 
    return View("Create"); 
    } 
} 

Y la manera habitual para transmitir su mensaje de error:

<%= Html.ValidationMessage("property_name") %> 
+1

La única cosa que me irrita más en los foros, es cuando pido una cosa, la gente responde algo diferente. ¡Y aquí hice lo mismo! –

3

Utilice los botones [] Colección TempData

El TempData se almacena de una solicitud al siguiente, luego se ha ido.

40

El patrón PRG está bien, pero me hizo esto:

controlador Base:

protected override void OnActionExecuted(ActionExecutedContext filterContext) 
{ 
    if (TempData["ModelState"] != null && !ModelState.Equals(TempData["ModelState"])) 
     ModelState.Merge((ModelStateDictionary)TempData["ModelState"]); 

    base.OnActionExecuted(filterContext); 
} 

Acción (Estoy usando xVal):

try 
{ 
    user.Login(); 
    AuthenticationManager.SignIn(user); 
} 
catch (RulesException rex) 
{ 
    // on bad login 
    rex.AddModelStateErrors(ModelState, "user"); 
    TempData["ModelState"] = ModelState; 
    return Redirect(Request.UrlReferrer.ToString()); 
} 

La acción arroja una excepción, agrega ModelState a TempData y redirige a la referencia. Como la acción está capturada, OnActionExecuted se sigue ejecutando, pero la primera vez que se usa el ModelState es la misma que TempData ["ModelState"], por lo que no desea fusionarse consigo mismo. Cuando se ejecuta la acción de redireccionamiento, OnActionExecuted vuelve a activarse. Esta vez, si hay algo en TempData ["ModelState"], se fusiona con el ModelState de esta acción.

Puede expandirlo a varios modelos utilizando TempData ["ModelState.user"] = ModelState y luego fusionando cada objeto TempData que comienza con ModelState.

+0

Me gusta ... Parece una forma práctica de hacer que esto funcione. ¡Gracias! –

+2

@Bill. Lo amo. He extendido tu código para mi uso. En lugar de RulesException.AddModelStateErrors(), lo hice de la otra manera, extendí ModelState para tener dos métodos de extensión; UpdateModel y RestoreModel. +1 para ti. – Syd

28

Sé que este hilo es viejo, pero this blog about ASP.NET Best Practices tiene algunas sugerencias excelentes.
# 13 en la página trata con el uso de 2 filtros de acción para guardar y restaurar ModelState entre los redireccionamientos.

Este es el patrón que mi trabajo usa, y me encanta.

Aquí está el ejemplo simplificado:

[ImportModelStateFromTempData] 
public ActionResult Dashboard() 
{ 
    return View(); 
} 

[AcceptVerbs(HttpVerbs.Post), ExportModelStateToTempData] 
public ActionResult Dashboard(string data) 
{ 
    if (ValidateData(data)) 
    { 
     try 
     { 
      _service.Submit(data); 
     } 
     catch (Exception e) 
     { 
      ModelState.AddModelError(ModelStateException, e); 
     } 
    } 

    return RedirectToAction("Dashboard"); 
} 
+1

La edad de la pregunta o respuestas realmente no importa, incluso aquí en 2014 pueden ayudar :-) Y gracias por el enlace, ¡realmente cosas buenas! – Oliver

+0

Los atributos ** [ImportModelStateFromTempData] ** y ** [ExportModelStateToTempData] ** también se explican aquí: [Cómo guardar el ModelState en sesión siguiendo las buenas prácticas] (http://patrickdesjardins.com/blog/how-to -save-the-modelstate-into-session-following-the-good-practice) – cat5dev

+1

Su enlace (que es omnipresente con cada discusión de PRG en MVC que vi) está extrañamente muerto. Parece que todo el blog de Rashid fue eliminado del blog del equipo ASP.NET. –

0

Lo que hice para mantener mi ModelState no importa dónde voy con redirecciones es la siguiente:

  1. En su modelo, añadir:

    public ModelStateDictionary modelstate { get; set; } 
    
  2. En el constructor de su modelo, agregue:

    this.modelstate = new System.Web.Mvc.ModelStateDictionary(); 
    
  3. muestra post con mi modelo llamado Models.ContactInformation:

    [HttpPost] 
    [ValidateAntiForgeryToken] 
    public ActionResult contact(Models.ContactInformation con) 
    { 
        if (string.IsNullOrEmpty(con.SelectedAgencySelectorType)) 
        { 
        ModelState.AddModelError("", "You did not select an agency type."); 
        } 
    
        con.modelstate = ModelState; 
        TempData["contact"] = con; 
        if (!ModelState.IsValid) return RedirectToAction("contactinformation", "reports"); 
    
        //do stuff 
    
        return RedirectToAction("contactinformation", "reports"); 
    } 
    
  4. Así que ahora su TempData tiene su modelo y ModelState como es.

  5. El siguiente es mi punto de vista que es indiferente al estado de cualquier cosa, a menos que tenga algo. Aquí está el código:

    [HttpGet] 
    public ActionResult contactinformation() 
    { 
        //try cast to model 
        var m = new Models.ContactInformation(); 
        if (TempData["contact"] is Models.ContactInformation) m = (Models.ContactInformation)TempData["contact"]; 
    
        //restore modelstate if needed 
        if (!m.modelstate.IsValid) 
        { 
         foreach (ModelState item in m.modelstate.Values) 
         { 
          foreach (ModelError err in item.Errors) 
          { 
           ModelState.AddModelError("", err.ErrorMessage.ToString()); 
          } 
         } 
        } 
    
        return View(m); 
    } 
    
Cuestiones relacionadas