Gestire form con più di un pulsante submit in ASP.NET MVC

di Marco De Sanctis, in ASP.NET MVC,

L'utilizzo di più di un pulsante di submit associato a una singola form HTML ha dei risvolti pratici molto interessanti: proviamo a pensare, per esempio, a una pagina di ricerca, in cui possiamo specificare dei filtri, e per la quale vogliamo decidere se visualizzare sullo schermo il risultato o esportarlo su un foglio Excel.

<form method="post">
    <input id="product" type="text" placeholder="Codice prodotto" />
    
    <!-- ... altri filtri -->

    <input type="submit" value="Visualizza" name="Browser" />
    <input type="submit" value="Esporta" name="Excel" />
</form>

Casi come questo pongono il problema, una volta che la richiesta perviene al server, di discriminare da quale pulsante è avvenuto effettivamente il post, così da comportarsi di conseguenza. Dal punto di vista dell'HTML, ciò è possibile analizzando il contenuto della richiesta e verificando la presenza di una chiave Browser o Excel al suo interno.

In ASP.NET MVC abbiamo a disposizione uno strumento che consente di gestire questa problematica in maniera davvero semplice e intuitiva, denominato action name selector.

Si tratta di un attribute, che eredita dalla classe ActionNameSelectorAttribute, che possiamo utilizzare per decorare una action; esso possiede un metodo IsValidName tramite cui indicare se la action corrente è idonea a gestire la richiesta o meno.

Un esempio di implementazione può essere la seguente:

public class HandlesButtonAttribute : ActionNameSelectorAttribute
{
  public string ButtonName { get; set; }

  public override bool IsValidName(ControllerContext controllerContext, 
    string actionName, MethodInfo methodInfo)
  {
    return controllerContext.Controller
      .ValueProvider.GetValue(this.ButtonName) != null;
  }
}

Il codice in alto non fa altro che verificare se, all'interno della richiesta, sia presente la chiave contenuta all'interno di ButtonName; l'effetto, nel caso il valore restituito sia false, è che ASP.NET MVC non considererà il metodo selezionato come valido e passerà a valutare eventuali ulteriori alternative.

Proviamo ora a riconsiderare l'esempio originale e vediamo come sfruttare questo attributo per gestire in maniera elegante le due tipologie di submit:

[HttpGet]
public ActionResult Search()
{
    return View();
}

[HttpPost]
[ActionName("Search")]
[HandlesButton(ButtonName = "Excel")]
public ActionResult ExportToExcel()
{
   ...
}

[HttpPost]
[ActionName("Search")]
[HandlesButton(ButtonName = "Browser")]
public ActionResult DisplayInBrowser()
{
   ...
}

I due metodi ExportToExcel e DisplayInBrowser sono entrambi associati alla action Search se richiamata in POST. Grazie al nostro attribute, però, siamo in grado di associarne uno al button denominato Browser e uno a quello denominato Excel, mantenendo quindi separati, all'interno del controller, i due diversi comportamenti che abbiamo voluto implementare.

Commenti

Visualizza/aggiungi commenti

| Condividi su: Twitter, Facebook, LinkedIn

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.

Approfondimenti

I più letti di oggi