2009-11-11 17 views
108

Ho due pulsanti sulla mia forma MVC:MVC cui pulsante di invio è stato premuto

<input name="submit" type="submit" id="submit" value="Save" /> 
<input name="process" type="submit" id="process" value="Process" /> 

Dalla mia azione di controllo come faccio a sapere quale sono stati premuti?

+0

Perché non basta aggiungere eventi onclick a questi pulsanti che vanno alla propria chiamata AJAX, che andranno ai loro metodi appropriati? es .: ''? – ragerory

risposta

141

Nome entrambi i tuoi presentare pulsanti lo stesso

<input name="submit" type="submit" id="submit" value="Save" /> 
<input name="submit" type="submit" id="process" value="Process" /> 

Poi nel controller ottenere il valore di presentare. Solo il pulsante cliccato passerà il suo valore.

public ActionResult Index(string submit) 
{ 
    Response.Write(submit); 
    return View(); 
} 

È ovviamente possibile valutare tale valore per eseguire diverse operazioni con un blocco di interruttori.

public ActionResult Index(string submit) 
{ 
    switch (submit) 
    { 
     case "Save": 
      // Do something 
      break; 
     case "Process": 
      // Do something 
      break; 
     default: 
      throw new Exception(); 
      break; 
    } 

    return View(); 
} 
+12

Attenzione ai problemi che la localizzazione potrebbe portare a questa soluzione, alla quale la soluzione di Darin non è accettabile. –

+0

Due ingressi con lo stesso nome generano una matrice che viene pubblicata con un elemento per ogni valore, non un singolo valore come implicito. Quindi vorrei poter dire altrimenti poiché speravo/cercando di usarlo, ma questo non funziona. –

43
<input name="submit" type="submit" id="submit" value="Save" /> 
<input name="process" type="submit" id="process" value="Process" /> 

E nella vostra azione di controllo:

public ActionResult SomeAction(string submit) 
{ 
    if (!string.IsNullOrEmpty(submit)) 
    { 
     // Save was pressed 
    } 
    else 
    { 
     // Process was pressed 
    } 
} 
+1

Immagino che più pulsanti possano essere aggiunti semplicemente aggiungendolo all'elenco dei parametri e nominandolo correttamente. Bella soluzione! – GONeale

0

Non è possibile trovare utilizzando Request.Form Collection? Se il processo viene cliccato il Request.Form [ "processo"] non sarà vuoto

26

questa è una risposta migliore, in modo che possiamo avere sia il testo e il valore per un pulsante:

http://weblogs.asp.net/dfindley/archive/2009/05/31/asp-net-mvc-multiple-buttons-in-the-same-form.aspx

</p> 
<button name="button" value="register">Register</button> 
<button name="button" value="cancel">Cancel</button> 
</p> 

e il controller:

public ActionResult Register(string button, string userName, string email, string password, string confirmPassword) 
{ 
if (button == "cancel") 
    return RedirectToAction("Index", "Home"); 
... 

in breve è un pulsante INVIA ma si sceglie il nome usando l'attributo nome, è ancora più potente perché il tuo non è obbligato al nome submit o button nei parametri del metodo controller, puoi chiamarlo come preferisci ...

+0

Grazie Signore, questo è esattamente ciò di cui ho bisogno – oHoodie

5

Ecco un modo veramente bello e semplice di farlo con istruzioni davvero facili da seguire usando un MultiButtonAttribute personalizzato:

http://blog.maartenballiauw.be/post/2009/11/26/Supporting-multiple-submit-buttons-on-an-ASPNET-MVC-view.aspx

In sintesi, rendere il vostro presentare pulsanti come questo:

<input type="submit" value="Cancel" name="action" /> 
<input type="submit" value="Create" name="action" /> 

Le vostre azioni come questa:

0.123.
[HttpPost] 
[MultiButton(MatchFormKey="action", MatchFormValue="Cancel")] 
public ActionResult Cancel() 
{ 
    return Content("Cancel clicked"); 
} 

[HttpPost] 
[MultiButton(MatchFormKey = "action", MatchFormValue = "Create")] 
public ActionResult Create(Person person) 
{ 
    return Content("Create clicked"); 
} 

E creare questa classe:

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)] 
public class MultiButtonAttribute : ActionNameSelectorAttribute 
{ 
    public string MatchFormKey { get; set; } 
    public string MatchFormValue { get; set; } 

    public override bool IsValidName(ControllerContext controllerContext, string actionName, MethodInfo methodInfo) 
    { 
     return controllerContext.HttpContext.Request[MatchFormKey] != null && 
      controllerContext.HttpContext.Request[MatchFormKey] == MatchFormValue; 
    } 
} 
+1

Sempre meglio riassumere un link di riferimento (per il giorno in cui il blog sparisce). In sintesi, il blog sostiene di avere un attributo personalizzato 'MultiButtonAttribute' per consentire la differenziazione tra i pulsanti di invio. In realtà una bella idea. –

+1

E se Arnis L avesse seguito lo stesso consiglio, potresti aver notato che ha fornito lo stesso link 4 anni prima:> –

+0

Ottimo punto @TrueBlueAussie, ho aggiunto un riepilogo del codice – Owen

3

Questo post non ha intenzione di rispondere alle Coppermill, perché sono stato risposto molto tempo fa. Il mio post sarà utile per chi cercherà una soluzione come questa. Prima di tutto, devo dire che "la soluzione di WDuffy è totalmente corretta" e funziona bene, ma la mia soluzione (non in realtà la mia) verrà utilizzata in altri elementi e rende il livello di presentazione più indipendente dal controller (perché il controller dipende da "valore" che viene utilizzato per mostrare l'etichetta del pulsante, questa funzione è importante per altre lingue.).
Ecco la mia soluzione, dare loro nomi diversi, come:
</p> <input type="submit" name="buttonSave" value="Save"/> <input type="submit" name="buttonProcess" value="Process"/> <input type="submit" name="buttonCancel" value="Process"/> </p>
E è necessario specificare i nomi dei pulsanti come argomenti nell'azione come di seguito:

public ActionResult Register(string buttonSave, string buttonProcess, string buttonCancel){if (buttonSave!= null) 
{//save is pressed 
} 
if (buttonProcess!= null) 
{//Process is pressed 
} 
if (buttonCancel!= null) 
{//Cancel is pressed 
} 


quando l'utente invia la pagina utilizzando uno dei pulsanti, solo uno degli argomenti avrà valore. Immagino che questo sarà utile per gli altri.

2

Per facilitare dirò è possibile modificare i pulsanti al seguente:

<input name="btnSubmit" type="submit" value="Save" /> 
<input name="btnProcess" type="submit" value="Process" /> 

Il controller:

public ActionResult Create(string btnSubmit, string btnProcess) 
{ 
    if(btnSubmit != null) 
     // do something for the Button btnSubmit 
    else 
     // do something for the Button btnProcess 
} 
2
// Buttons 
<input name="submit" type="submit" id="submit" value="Save" /> 
<input name="process" type="submit" id="process" value="Process" /> 

// Controller 
[HttpPost] 
public ActionResult index(FormCollection collection) 
{ 
    string submitType = "unknown"; 

    if(collection["submit"] != null) 
    { 
     submitType = "submit"; 
    } 
    else if (collection["process"] != null) 
    { 
     submitType = "process"; 
    } 

} // End of the index method 
+0

Questa è una soluzione superiore a tutto il resto pubblicato in quanto consente di trasmettere in modo coerente dati di forma molto complessi senza set di parametri personalizzati in ogni azione, consentendo alla logica del controller di essere altamente personalizzabile per moduli complessi. Kudos Fredrik :) Presumo che questo FormCollection passerebbe in più forme? – Stokely

+0

Grazie Stokely. È possibile chiamare questo metodo da più moduli, se si esegue una chiamata Ajax, è possibile includere più moduli nello stesso FormCollection. –

15

è possibile identificare il pulsante da lì tag name come sotto, Devi controllare come questo nel tuo controller

if (Request.Form["submit"] != null) 
{ 
//Write your code here 
} 
else if (Request.Form["process"] != null) 
{ 
//Write your code here 
} 
+0

questo trucco è stato davvero utile per me, grazie –

+0

questo è molto utile in situazioni in cui non si vuole passare il nome del pulsante al post action result. – yogihosting

+0

in questo scenario può essere più complicato prendere in giro la classe Request in unit test. – Muflix

1

Dare il nome a entrambi i pulsanti e ottenere il controllo del valore dal modulo.

<div> 
    <input name="submitButton" type="submit" value="Register" /> 
</div> 

<div> 
    <input name="cancelButton" type="submit" value="Cancel" /> 
</div> 

su lato controllore:

public ActionResult Save(FormCollection form) 
{ 
if (this.httpContext.Request.Form["cancelButton"] !=null) 
{ 
    // return to the action; 
} 

if (this.httpContext.Request.Form["submitButton"] !=null) 
{ 
    // save the oprtation and retrun to the action; 
} 
} 
Problemi correlati