2009-03-18 10 views

risposta

-3

Credo che si perda lo stato del modello quando si esegue un reindirizzamento. Forse si potrebbe riscrivere la logica a qualcosa di simile:

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

E il solito modo per ottenere il vostro messaggio di errore:

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

L'unica cosa che mi irrita più su forum, è quando chiedo una cosa, la gente risponde qualcosa di diverso. E qui ho fatto la stessa cosa! –

3

Utilizzare la Collezione TempData []

Il TempData è memorizzato da un richiesta per il prossimo, quindi è andato.

40

Il pattern PRG è ok, ma ho fatto questo:

Controller di base:

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

    base.OnActionExecuted(filterContext); 
} 

Azione (Sto utilizzando 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()); 
} 

L'azione genera un'eccezione, aggiunge ModelState a TempData e reindirizza nuovamente al referrer. Poiché l'azione viene intercettata, OnActionExecuted viene ancora eseguito, ma la prima volta attorno a ModelState è uguale a TempData ["ModelState"], quindi non si desidera unire con se stessi. Quando viene eseguita l'azione di reindirizzamento, OnActionExecuted viene nuovamente attivato. Questa volta, se c'è qualcosa in TempData ["ModelState"], si fonde con ModelState di questa azione.

È possibile estenderlo a più modelli utilizzando TempData ["ModelState.user"] = ModelState e quindi unendo tutti gli oggetti TempData che iniziano con ModelState.

+0

Mi piace ... Sembra un modo pratico per farlo funzionare. Grazie! –

+2

@ Bill. Lo adoro. Ho esteso il tuo codice per il mio utilizzo. Invece di RulesException.AddModelStateErrors(), l'ho fatto nell'altro modo, ho esteso ModelState per avere due metodi di estensione; UpdateModel e RestoreModel. +1 per te. – Syd

28

So che questo thread è vecchio, ma this blog about ASP.NET Best Practices ha alcuni suggerimenti eccellenti.
# 13 nella pagina si occupa di utilizzare 2 filtri di azione per salvare e ripristinare ModelState tra i reindirizzamenti.

Questo è lo schema che utilizza il mio lavoro, e lo adoro.

Ecco l'esempio semplificato:

[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

L'età della domanda o delle risposte non ha importanza - anche qui nel 2014 possono aiutare :-) E grazie per il link, roba davvero buona! – Oliver

+0

Gli attributi ** [ImportModelStateFromTempData] ** e ** [ExportModelStateToTempData] ** sono spiegati qui: [Come salvare il ModelState in sessione seguendo le buone pratiche] (http://patrickdesjardins.com/blog/how-to -salva-il-modello-in-sessione-seguendo-le-buone pratiche) – cat5dev

+1

Il tuo link (che è onnipresente con ogni discussione su PRG in MVC che ho visto) è stranamente morto. Sembra che l'intero blog di Rashid sia stato rimosso dal blog del team di ASP.NET. –

0

Quello che ho fatto per mantenere la mia ModelState non importa dove vado con i reindirizzamenti è la seguente:

  1. nel modello, aggiungere:

    public ModelStateDictionary modelstate { get; set; } 
    
  2. Nel costruttore del modello, aggiungere:

    this.modelstate = new System.Web.Mvc.ModelStateDictionary(); 
    
  3. Esempio Messaggio con il mio modello chiamato 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. Così ora la tua TempData ha il vostro modello e ModelState come è.

  5. Il seguente è il mio punto di vista che è agnostico allo stato di qualsiasi cosa, a meno che non abbia qualcosa. Ecco il codice:

    [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); 
    } 
    
Problemi correlati