719 votos

¿Cómo se manejan los botones de envío múltiples en ASP.NET MVC Framework?

¿Hay alguna manera fácil de manejar múltiples botones de envío desde el mismo formulario? Ejemplo:

<% Html.BeginForm("MyAction", "MyController", FormMethod.Post); %>
<input type="submit" value="Send" />
<input type="submit" value="Cancel" />
<% Html.EndForm(); %>

¿Alguna idea de cómo hacer esto en ASP.NET Framework Beta? Todos los ejemplos que he buscado en Google tienen botones simples.

614voto

mkozicki Puntos 1668

Aquí hay una solución basada en atributos para el problema de los botones de envío múltiples, basada en gran medida en el post y los comentarios de Maartin Balliauw .

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

    public override bool IsValidName(ControllerContext controllerContext, string actionName, MethodInfo methodInfo)
    {
        var isValidName = false;
        var keyValue = string.Format("{0}:{1}", Name, Argument);
        var value = controllerContext.Controller.ValueProvider.GetValue(keyValue);

        if (value != null)
        {
            controllerContext.Controller.ControllerContext.RouteData.Values[Name] = Argument;
            isValidName = true;
        }

        return isValidName;
    }
}

navaja de afeitar:

<form action="" method="post">
 <input type="submit" value="Save" name="action:Save" />
 <input type="submit" value="Cancel" name="action:Cancel" />
</form>

y el controlador:

[HttpPost]
[MultipleButton(Name = "action", Argument = "Save")]
public ActionResult Save(MessageModel mm) { ... }

[HttpPost]
[MultipleButton(Name = "action", Argument = "Cancel")]
public ActionResult Cancel(MessageModel mm) { ... }

464voto

Dylan Beattie Puntos 23222

Dale un nombre a tus botones de envío, y luego inspecciona el valor enviado en tu método del controlador:

<% Html.BeginForm("MyAction", "MyController", FormMethod.Post); %>
<input type="submit" name="submitButton" value="Send" />
<input type="submit" name="submitButton" value="Cancel" />
<% Html.EndForm(); %>

Contabilización en

public class MyController : Controller {
    public ActionResult MyAction(string submitButton) {
        switch(submitButton) {
            case "Send":
                // delegate sending to another controller action
                return(Send());
            case "Cancel":
                // call another action to perform the cancellation
                return(Cancel());
            default:
                // If they've submitted the form without a submitButton, 
                // just return the view again.
                return(View());
        }
    }

    private ActionResult Cancel() {
        // process the cancellation request here.
        return(View("Cancelled"));
    }

    private ActionResult Send() {
        // perform the actual send operation here.
        return(View("SendConfirmed"));
    }

}

EDITAR:

Para ampliar este enfoque para trabajar con sitios localizados, aísle sus mensajes en otro lugar (por ejemplo, compilando un archivo de recursos a una clase de recursos fuertemente tipada)

Entonces modifica el código para que funcione como:

<% Html.BeginForm("MyAction", "MyController", FormMethod.Post); %>
<input type="submit" name="submitButton" value="<%= Html.Encode(Resources.Messages.Send)%>" />
<input type="submit" name="submitButton" value="<%=Html.Encode(Resources.Messages.Cancel)%>" />
<% Html.EndForm(); %>

y tu controlador debería tener este aspecto:

// Note that the localized resources aren't constants, so 
// we can't use a switch statement.

if (submitButton == Resources.Messages.Send) { 
    // delegate sending to another controller action
    return(Send());

} else if (submitButton == Resources.Messages.Cancel) {
     // call another action to perform the cancellation
     return(Cancel());
}

121voto

Trevor de Koekkoek Puntos 2029

Puede comprobar el nombre en la acción como se ha mencionado, pero podría considerar si esto es o no un buen diseño. Es una buena idea considerar la responsabilidad de la acción y no acoplar este diseño demasiado a aspectos de UI como los nombres de los botones. Así que considere el uso de 2 formularios y 2 acciones:

<% Html.BeginForm("Send", "MyController", FormMethod.Post); %>
<input type="submit" name="button" value="Send" />
<% Html.EndForm(); %>

<% Html.BeginForm("Cancel", "MyController", FormMethod.Post); %>
<input type="submit" name="button" value="Cancel" />
<% Html.EndForm(); %>

Además, en el caso de "Cancelar", lo normal es que no se procese el formulario y se vaya a una nueva URL. En este caso no es necesario enviar el formulario en absoluto y sólo necesita un enlace:

<%=Html.ActionLink("Cancel", "List", "MyController") %>

98voto

PabloBlamirez Puntos 969

Eilon sugiere que puedes hacerlo así:

Si tiene más de un botón puede puede distinguir entre ellos dando a un nombre a cada botón:

<input type="submit" name="SaveButton" value="Save data" />
<input type="submit" name="CancelButton" value="Cancel and go back to main page" />

En el método de acción de tu controlador puedes puede añadir parámetros con el nombre de nombres de etiquetas de entrada HTML:

public ActionResult DoSomeStuff(string saveButton, string
cancelButton, ... other parameters ...)
{ ... }

Si se contabiliza algún valor en uno de esos parámetros, significa que ese fue el que se pulsó. El navegador web sólo publicará un valor para el un que se ha pulsado. Todos los demás valores serán nulos.

if (saveButton != null) { /* do save logic */ }
if (cancelButton != null) { /* do cancel logic */ }

Me gusta este método, ya que no depende de la propiedad de valor de los botones de envío, que es más probable que cambie que los nombres asignados, y no requiere que javascript esté habilitado

Ver: http://forums.asp.net/p/1369617/2865166.aspx#2865166

35voto

Izmoto Puntos 1134

Sugiero a los interesados que echen un vistazo a una solución que creo que es muy elegante aquí >> http://blog.maartenballiauw.be/post/2009/11/26/Supporting-multiple-submit-buttons-on-an-ASPNET-MVC-view.aspx

En caso de que el enlace desaparezca, se utiliza el atributo MultiButton aplicado a una acción del controlador para indicar con qué botón debe relacionarse esa acción.

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X