web-dev-qa-db-fra.com

Envoi de formulaire à différentes actions de post-MVC en fonction du bouton de soumission cliqué

J'utilise ASP.Net MVC 4. J'ai plusieurs boutons sur une vue .. À l'heure actuelle, j'appelle la même méthode d'action. et je distingue le bouton cliqué en utilisant un attribut name.

@using (Html.BeginForm("Submit", "SearchDisplay", new { id = Model == null ? Guid.NewGuid().ToString() : Model.SavedSearch }, FormMethod.Post))
{
    <div class="leftSideDiv">
        <input type="submit" id="btnExport" class="exporttoexcelButton" 
        name="Command" value="Export to Excel" />
    </div>

    <div class="pageWrapperForSearchSubmit">
        <input type="submit" class="submitButton" 
         value="Submit" id="btnSubmitChange" />
    </div>
}

//ACTION

    [HttpPost]
    public ActionResult Submit(SearchCostPage searchModel, string Command)
    {
        SessionHelper.ProjectCase = searchModel.ProjectCaseNumber;

        if (string.Equals(Command, Constants.SearchPage.ExportToExcel))
        {

        }
   }

[~ # ~] questions [~ # ~]

  1. Existe-t-il un moyen de diriger différentes méthodes d’action POST) sur différents clics de bouton (sans routage personnalisé)?
  2. S'il n'y a pas de chemin sans routage personnalisé, comment pouvons-nous le faire avec un routage personnalisé?

Références:

  1. Jimmy Bogard - Nettoyage des POST dans ASP.NET MVC
55
Lijo

MEILLEURE RÉPONSE 1:

ActionNameSelectorAttribute mentionné dans

  1. Comment gérez-vous plusieurs boutons de soumission dans ASP.NET MVC Framework?

  2. Formulaire ASP.Net MVC 4 avec 2 boutons/actions de soumission

http://weblogs.asp.net/scottgu/archive/2007/12/09/asp-net-mvc-framework-part-4-handling-form-edit-edit-and-post-scenarios.aspx

RÉPONSE 2

Référence: dotnet-tricks - Gestion de plusieurs boutons d'envoi sur le même formulaire - MVC Razor

Deuxième approche

Ajouter un nouveau formulaire pour gérer le bouton Annuler cliquez. Maintenant, en cliquant sur le bouton Annuler, nous publierons le deuxième formulaire et le redirigerons vers la page d’accueil.

Troisième approche: script client

<button name="ClientCancel" type="button" 
    onclick=" document.location.href = $('#cancelUrl').attr('href');">Cancel (Client Side)
</button>
<a id="cancelUrl" href="@Html.AttributeEncode(Url.Action("Index", "Home"))" 
style="display:none;"></a>
21
Lijo

Vous pouvez choisir l'URL où le formulaire doit être envoyé (et donc l'action invoquée) de différentes manières, en fonction de la prise en charge du navigateur:

De cette façon, vous n'avez rien à faire de spécial côté serveur.

Bien sûr, vous pouvez utiliser les méthodes Url extensions dans votre Razor pour spécifier l'action de formulaire.

Pour les navigateurs supportant HMTL5: définissez simplement vos boutons d'envoi de la manière suivante:

<input type='submit' value='...' formaction='@Url.Action(...)' />

Pour les anciens navigateurs , je vous recommande d'utiliser un script non intrusif comme celui-ci (incluez-le dans votre "maquette maître"):

$(document).on('click', '[type="submit"][data-form-action]', function (event) {
  var $this = $(this);
  var formAction = $this.attr('data-form-action');
  $this.closest('form').attr('action', formAction);
});

REMARQUE: ce script gérera le clic de tout élément de la page comportant type=submit et data-form-action les attributs. Lorsque cela se produit, la valeur de data-form-action attribuez et définissez l'action du formulaire contenant la valeur de cet attribut. Comme il s'agit d'un événement délégué, cela fonctionnera même pour le code HTML chargé avec AJAX, sans aucune étape supplémentaire.

Ensuite, vous devez simplement ajouter un data-form-action attribut avec l'URL d'action souhaitée pour votre bouton, comme ceci:

<input type='submit' data-form-action='@Url.Action(...)' value='...'/>

Notez que cliquer sur le bouton modifie l'action du formulaire et que, juste après, le navigateur enregistre le formulaire dans l'action souhaitée.

Comme vous pouvez le constater, cela ne nécessite aucun routage personnalisé, vous pouvez utiliser les méthodes d'extension standard Url et vous n'avez rien de spécial à faire dans les navigateurs modernes.

80
JotaBe

Cela me semble que ce que vous avez est une commande avec 2 sorties, je choisirais de faire le changement dans les deux client et serveur pour cela.

Sur le client, utilisez JS pour créer l’URL que vous souhaitez publier (utilisez JQuery pour plus de simplicité), c.-à-d.

<script type="text/javascript">
    $(function() {
        // this code detects a button click and sets an `option` attribute
        // in the form to be the `name` attribute of whichever button was clicked
        $('form input[type=submit]').click(function() {
            var $form = $('form');
            form.removeAttr('option');
            form.attr('option', $(this).attr('name'));
        });
        // this code updates the URL before the form is submitted
        $("form").submit(function(e) { 
            var option = $(this).attr("option");
            if (option) {
                e.preventDefault();
                var currentUrl = $(this).attr("action");
                $(this).attr('action', currentUrl + "/" + option).submit();     
            }
        });
    });
</script>
...
<input type="submit" ... />
<input type="submit" name="Excel" ... />

Maintenant, côté serveur, nous pouvons ajouter une nouvelle route pour traiter la demande Excel

routes.MapRoute(
    name: "ExcelExport",
    url: "SearchDisplay/Submit/Excel",
    defaults: new
    {
        controller = "SearchDisplay",
        action = "SubmitExcel",
    });

Vous pouvez configurer 2 actions distinctes

public ActionResult SubmitExcel(SearchCostPage model)
{
   ...
}

public ActionResult Submit(SearchCostPage model)
{
   ...
}

Ou vous pouvez utiliser l'attribut ActionName comme alias

public ActionResult Submit(SearchCostPage model)
{
   ...
}

[ActionName("SubmitExcel")]
public ActionResult Submit(SearchCostPage model)
{
   ...
}
5
James

vous pouvez utiliser des appels ajax pour appeler différentes méthodes sans publication

$.ajax({
    type: "POST",
     url: "@(Url.Action("Action", "Controller"))",
     data: {id: 'id', id1: 'id1' },
     contentType: "application/json; charset=utf-8",
     cache: false,
     async: true,
     success: function (result) {
        //do something
     }
});
3
Matt Bodily