web-dev-qa-db-fra.com

ASP.NET MVC ActionLink et méthode post

Quelqu'un peut-il me dire comment puis-je soumettre des valeurs au contrôleur à l'aide de ActionLink et de la méthode POST?
Je ne veux pas utiliser de boutons.
Je suppose qu’il a quelque chose de mal à répondre.

96
šljaker

Vous ne pouvez pas utiliser un ActionLink car cela ne fait que restituer une balise d'ancrage <a>.
Vous pouvez utiliser un jQuery AJAX post .
Ou appelez simplement la méthode submit du formulaire avec ou sans jQuery (ce qui ne serait pas AJAX), peut-être dans l'événement onclick du contrôle que vous voudrez.

55
AUSteve

Si vous utilisez ASP MVC3, vous pouvez utiliser Ajax.ActionLink (), ce qui vous permet de spécifier une méthode HTTP que vous pouvez définir sur "POST".

71
Aidos

Vous pouvez utiliser jQuery pour effectuer un POST pour tous vos boutons. Donnez-leur simplement le même nom CssClass.

Utilisez "return false"; à la fin de votre événement javascript onclick si vous souhaitez effectuer une redirection côté serveur après la publication, sinon, il vous suffit de renvoyer la vue.

Code de rasoir

@using (Html.BeginForm())
{
    @Html.HiddenFor(model => model.ID) 
    @Html.ActionLink("Save", "SaveAction", "MainController", null, new { @class = "saveButton", onclick = "return false;" })
}

Code JQuery

$(document).ready(function () {
        $('.saveButton').click(function () {
            $(this).closest('form')[0].submit();
        });
    });

C #

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult SaveAction(SaveViewModel model)
{
    // Save code here...

    return RedirectToAction("Index");
    //return View(model);
}
20
Idris

@Aidos avait la bonne réponse, je voulais juste que ce soit clair, car elle est cachée dans un commentaire sur son message de @CodingWithSpike.

@Ajax.ActionLink("Delete", "Delete", new { id = item.ApkModelId }, new AjaxOptions { HttpMethod = "POST" })
15
goodies4uall

Voici une réponse cuite dans le projet ASP.NET MVC 5 par défaut, qui, à mon avis, permet de réaliser parfaitement mes objectifs en matière de style dans l'interface utilisateur. Soumettre le formulaire en utilisant du javascript pur à un formulaire contenant.

@using (Html.BeginForm("Logout", "Account", FormMethod.Post, new { id = "logoutForm", @class = "navbar-right" }))
{
   <a href="javascript:document.getElementById('logoutForm').submit()">
      <span>Sign out</span>
   </a>
}

Le cas d'utilisation complet est une liste déroulante de déconnexion dans la barre de navigation d'une application Web.

@using (Html.BeginForm("Logout", "Account", FormMethod.Post, new { id = "logoutForm", @class = "navbar-right" }))
{
    @Html.AntiForgeryToken()

    <div class="dropdown">
        <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
            <span class="ma-nav-text ma-account-name">@User.Identity.Name</span>
            <i class="material-icons md-36 text-inverse">person</i>
        </button>

        <ul class="dropdown-menu dropdown-menu-right ma-dropdown-tray">
            <li>
                <a href="javascript:document.getElementById('logoutForm').submit()">
                    <i class="material-icons">system_update_alt</i>
                    <span>Sign out</span>
                </a>
            </li>
        </ul>
    </div>
}
5
daniel.caspers

ActionLink ne tirera jamais après. Il déclenche toujours une requête GET.

3
Navish Rampal

Utilisez le lien Call the Action suivant:

<%= Html.ActionLink("Click Here" , "ActionName","ContorllerName" )%>

Pour soumettre les valeurs du formulaire, utilisez:

 <% using (Html.BeginForm("CustomerSearchResults", "Customer"))
   { %>
      <input type="text" id="Name" />
      <input type="submit" class="dASButton" value="Submit" />
   <% } %>

Il soumettra les données au contrôleur client et à l'action CustomerSearchResults.

2
Navish Rampal

Cela a été un problème difficile à résoudre pour moi. Comment puis-je créer un lien dynamique dans razor et html pouvant appeler une méthode d'action et transmettre une ou des valeurs à une méthode d'action spécifique? J'ai envisagé plusieurs options, y compris un assistant HTML personnalisé. Je viens de proposer une solution simple et élégante.

La vue

@model IEnumerable<MyMvcApp.Models.Product>

@using (Html.BeginForm()) {

     <table>
         <thead>
             <tr>
                 <td>Name</td>
                 <td>Price</td>
                 <td>Quantity</td>
            </tr>
        </thead>
        @foreach (Product p in Model.Products)
        {
            <tr>
                <td><a href="@Url.Action("Edit", "Product", p)">@p.Name</a></td>
                <td>@p.Price.ToString()</td>
                <td>@p.Quantity.ToString()</td>
            </tr>
         }
    </table>
}

La méthode d'action

public ViewResult Edit(Product prod)
{
    ContextDB contextDB = new ContextDB();

    Product product = contextDB.Products.Single(p => p.ProductID == prod.ProductId);

    product = prod;

    contextDB.SaveChanges();

    return View("Edit");
}

Le point ici est que Url.Action ne se soucie pas de savoir si la méthode d'action est un GET ou un POST. Il aura accès à l'un ou l'autre type de méthode. Vous pouvez transmettre vos données à la méthode d'action à l'aide de

@Url.Action(string actionName, string controllerName, object routeValues)

l'objet routeValues. J'ai essayé cela et ça marche. Non, techniquement, vous ne faites pas de publication ou ne soumettez pas le formulaire, mais si l'objet routeValues ​​contient vos données, peu importe qu'il s'agisse d'un post ou d'un get. Vous pouvez utiliser une signature de méthode d'action particulière pour sélectionner la bonne méthode.

1
wayne.blackmon

Utilisez ce lien dans Ajax.BeginForm

@Html.ActionLink(
    "Save", 
    "SaveAction", 
    null, 
    null, 
    onclick = "$(this).parents('form').attr('action', $(this).attr('href'));$(this).parents('form').submit();return false;" })

;)

1
Alexey Smolyakov

J'ai fait le même problème en utilisant le code suivant:

@using (Html.BeginForm("Delete", "Admin"))
{
       @Html.Hidden("ProductID", item.ProductID)
       <input type="submit" value="Delete" />
}
1
isxaker

Ma solution à ce problème est assez simple. J'ai une page qui fait une recherche de client un par l'email entier et l'autre par un partiel, les tirages partiels et affiche une liste la liste a un lien d'action qui pointe vers un résultat d'action appelé GetByID et passe dans l'id

getByID extrait les données du client sélectionné, puis revient

return View("Index", model); 

quelle est la méthode post

1
DJ_PLaying

Ceci est ma solution pour le problème. C'est contrôleur avec 2 méthodes d'action

public class FeedbackController : Controller
{
public ActionResult Index()
{
   var feedbacks =dataFromSomeSource.getData;
   return View(feedbacks);
}

[System.Web.Mvc.HttpDelete]
[System.Web.Mvc.Authorize(Roles = "admin")]
public ActionResult Delete([FromBody]int id)
{
   return RedirectToAction("Index");
}
}

Dans View, la structure suivante est générée.

<html>
..
<script src="~/Scripts/bootbox.min.js"></script>
<script>
function confirmDelete(id) {
  bootbox.confirm('@Resources.Resource.AreYouSure', function(result) {
    if (result) {
      document.getElementById('idField').value = id;
      document.getElementById('myForm').submit();
    }
  }.bind(this));
}
</script>

@using (Html.BeginForm("Delete", "Feedback", FormMethod.Post, new { id = "myForm" }))
{
  @Html.HttpMethodOverride(HttpVerbs.Delete)
  @Html.Hidden("id",null,new{id="idField"})
  foreach (var feedback in @Model)
  {
   if (User.Identity.IsAuthenticated && User.IsInRole("admin"))
   {
    @Html.ActionLink("Delete Item", "", new { id = @feedback.Id }, new { onClick = "confirmDelete("+feedback.Id+");return false;" })
   }
  }
...
</html>

Point d'intérêt à Razor View:

  1. Fonction JavaScript confirmDelete(id) qui est appelée lorsque l'utilisateur clique sur le lien généré avec @Html.ActionLink.

  2. confirmDelete() fonction requise id de l'élément sur lequel l'utilisateur a cliqué. Cet élément est transmis de onClick gestionnaire confirmDelete("+feedback.Id+");return false; Le gestionnaire d'attention est renvoyé par false pour empêcher l'action par défaut, c'est-à-dire une requête get cible. L'événement OnClick pour les boutons peut également être associé à jQuery pour tous les boutons de la liste (ce sera probablement encore mieux car il y aura moins de texte dans la page HTML et les données pourraient être transmises via data- attribut).

  3. Le formulaire a id=myForm, afin de le trouver dans confirmDelete().

  4. La forme inclut @Html.HttpMethodOverride(HttpVerbs.Delete) afin d'utiliser le verbe HttpDelete comme action marquée avec le HttpDeleteAttribute.

  5. Dans la fonction JS, j'utilise la confirmation d'action (à l'aide d'un plugin externe, mais la confirmation standard fonctionne également. N'oubliez pas d'utiliser bind() dans call back ou var that=this (comme vous préférez).

  6. La forme a un élément caché avec id='idField' et name='id'. Ainsi, avant que le formulaire ne soit soumis après confirmation (result==true), la valeur de l'élément masqué est définie sur argument passé et le navigateur soumettra les données au contrôleur de la manière suivante:

URL de la demande : http://localhost:38874/Feedback/Delete

Méthode de requête : Code d'état POST: 302 trouvés

En-têtes de réponse

Emplacement:/Commentaires Hôte: localhost: 38874 Données du formulaire X-HTTP-Method-Override: DELETE id: 5

Comme vous pouvez le voir, il s’agit de la demande POST avec X-HTTP-Method-Override: DELETE et les données dans le corps sont définies sur "id: 5". Response a un code 302 qui redirige vers l’action Index, ce qui vous permet d’actualiser votre écran après sa suppression.

1
Vitaliy Markitanov

L'appel de $ .post () ne fonctionnera pas car il est basé sur Ajax. Une méthode hybride doit donc être utilisée à cette fin.

Voici la solution qui fonctionne pour moi.

Étapes: 1. Créez une URL pour href qui appelle la méthode a avec l'URL et le paramètre 2. Appelez la méthode normale POST à l'aide de la méthode JavaScript.

Solution:

En cshtml:

<a href="javascript:(function(){$.postGo( '@Url.Action("View")', { 'id': @receipt.ReceiptId  } );})()">View</a>

Remarque: la méthode anonyme doit être encapsulée dans (....) () i.e.

(function() {
    //code...
})();

postGo est défini comme ci-dessous en JavaScript. Le repos est simple ..

@ Url.Action ("View") crée l'URL de l'appel.

{'id': @ reception.ReceiptId} crée des paramètres sous la forme d'un objet qui est ensuite converti en champs POST dans la méthode postGo. . Cela peut être n'importe quel paramètre selon vos besoins

En JavaScript:

(function ($) {
    $.extend({
        getGo: function (url, params) {
            document.location = url + '?' + $.param(params);
        },
        postGo: function (url, params) {
            var $form = $("<form>")
                .attr("method", "post")
                .attr("action", url);
            $.each(params, function (name, value) {
                $("<input type='hidden'>")
                    .attr("name", name)
                    .attr("value", value)
                    .appendTo($form);
            });
            $form.appendTo("body");
            $form.submit();
        }
    });
})(jQuery);

URL de référence que j'ai utilisées pour postGo

Non-ajax GET/POST utilisant jQuery (plugin?)

http://nuonical.com/jquery-postgo-plugin/

0
Tejasvi Hegde

Je vous recommande de rester pur selon les principes REST et d'utiliser une suppression HTTP pour vos suppressions. Malheureusement, HTML Specs n’a que HTTP Get & Post. Un tag seulement peut recevoir un HTTP. Une balise de formulaire peut faire une requête HTTP Get ou Post. Heureusement si vous utilisez ajax, vous pouvez faire une suppression HTTP et c'est ce que je recommande. Voir le post suivant pour plus de détails: Http Deletes

0
coding4fun

Nous sommes tombés sur ce besoin de POST d'une page de recherche (index) à la page de résultats. Je n’avais pas besoin autant que @Vitaliy, mais cela m’a orienté dans la bonne direction. Tout ce que je devais faire était ceci:

@using (Html.BeginForm("Result", "Search", FormMethod.Post)) {
  <div class="row">
    <div class="col-md-4">
      <div class="field">Search Term:</div>
      <input id="k" name="k" type="text" placeholder="Search" />
    </div>
  </div>
  <br />
  <div class="row">
    <div class="col-md-12">
      <button type="submit" class="btn btn-default">Search</button>
    </div>
  </div>
}

Mon contrôleur avait la méthode de signature suivante:

[HttpPost]
public async Task<ActionResult> Result(string k)
0
Grandizer

jQuery.post() fonctionnera si vous avez des données personnalisées. Si vous souhaitez publier un formulaire existant, il est plus facile d'utiliser ajaxSubmit() .

Et vous ne devez pas configurer ce code dans la ActionLink elle-même, car vous pouvez attacher un gestionnaire de lien dans l'événement document.ready() (qui est de toute façon une méthode préférée), par exemple en utilisant $(function(){ ... }) jQuery astuce.

0
queen3

Ceci est extrait de l'exemple de projet MVC

@if (ViewBag.ShowRemoveButton)
      {
         using (Html.BeginForm("RemoveLogin", "Manage"))
           {
              @Html.AntiForgeryToken()
                  <div>
                     @Html.Hidden("company_name", account)
                     @Html.Hidden("returnUrl", Model.returnUrl)
                     <input type="submit" class="btn btn-default" value="Remove" title="Remove your email address from @account" />
                  </div>
            }
        }
0
Maya