ASP.NET MVC ActionLink und Post-Methode

97

Kann mir jemand sagen, wie ich mithilfe der ActionLink- und POST-Methode Werte an Controller senden kann?
Ich möchte keine Tasten verwenden.
Ich denke, es hat etwas mit jquery.

šljaker
quelle
1
Ich habe eine Methode geschrieben, die Html.ActionLink ähnelt, nur dass das POST-Formular mit der Schaltfläche "Senden" erstellt wird. Ich werde sehen, ob ich die Option geben kann, die Schaltfläche durch einen Link zu ersetzen, der das Formular sendet. Siehe hier: stackoverflow.com/questions/3449807/…
nikib3ro

Antworten:

58

Sie können ein nicht verwenden, ActionLinkda dadurch nur ein Ankertag <a>gerendert wird.
Sie können einen jQuery AJAX-Beitrag verwenden .
Oder rufen Sie einfach die Submit-Methode des Formulars mit oder ohne jQuery auf (was nicht AJAX wäre), möglicherweise für den onclickFall, dass Sie die Kontrolle haben.

AUSteve
quelle
70

Wenn Sie ASP MVC3 verwenden, können Sie einen Ajax.ActionLink () verwenden, mit dem Sie eine HTTP-Methode angeben können, die Sie auf "POST" setzen können.

Aidos
quelle
45
Beachten Sie, dass Sie eine der Ajax-Javascript-Dateien einfügen müssen, z. B. " jquery.unobtrusive-ajax.min.js". Andernfalls wird beim Klicken weiterhin ein GET anstelle eines POST ausgeführt. Die Syntax zum Herstellen des Links @Ajax.ActionLink("Delete", "Delete", new { id = item.Id }, new AjaxOptions {HttpMethod = "POST"})
lautet
1
unauffälliger Ajax funktionierte einwandfrei, ABER ich musste den Aktionslink etwas anders verwenden und anstelle dieses AjaxOptions-Objekts ein Dictionary als Parameter übergeben: stackoverflow.com/a/10657891/429521 Außerdem musste ich die Ajax- Attribute von Hand übergeben, damit der JS konnte die Klickereignisse abfangen und überschreiben "data-ajax"="true, "data-ajax-url"=<your link> and "data-ajax-method"="Post". Übrigens benutze ich ASP.NET MVC 3
Felipe Sabino
1
@CokoBWare this one stackoverflow.com/questions/10507737/… ? Ja wirklich? Es scheint für mich nicht kaputt zu sein ...
Felipe Sabino
20

Sie können jQuery verwenden, um einen POST für alle Ihre Schaltflächen durchzuführen. Geben Sie ihnen einfach den gleichen CssClass-Namen.

Verwenden Sie "return false;" Wenn Sie am Ende Ihres Onclick-Javascript-Ereignisses nach dem Beitrag eine serverseitige RedirectToAction ausführen möchten, geben Sie ansonsten einfach die Ansicht zurück.

Rasiermesser Code

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

JQuery-Code

$(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);
}
Idris
quelle
@ goodies4uall In der Tat, und diese Antwort macht genau das. :) Die CSS-Klasse heißt "saveButton" (möglicherweise ein irreführender Name), aber ein Ankertag wird verwendet, um die Aktion zu
starten
17

@Aidos hatte die richtige Antwort, wollte es nur klarstellen, da sie in einem Kommentar zu seinem Beitrag von @CodingWithSpike versteckt ist.

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

Hier ist eine Antwort, die in das Standard-ASP.NET MVC 5-Projekt eingebrannt wurde. Ich glaube, dass meine Styling-Ziele in der Benutzeroberfläche gut erreicht werden. Formular mit reinem Javascript an ein Formular senden.

@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>
}

Der vollständig angezeigte Anwendungsfall ist ein Dropdown-Menü zum Abmelden in der Navigationsleiste einer Web-App.

@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>
}
daniel.caspers
quelle
3

ActionLink wird niemals Post feuern. Es wird immer eine GET-Anfrage ausgelöst.

Navish Rampal
quelle
2

Verwenden Sie den folgenden Link Call the Action:

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

Verwenden Sie zum Senden der Formularwerte:

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

Die Daten werden an Customer Controller und CustomerSearchResults Action gesendet.

Navish Rampal
quelle
1

Verwenden Sie diesen Link in Ajax.BeginForm

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

;)

Alexey Smolyakov
quelle
1

Meine Lösung für dieses Problem ist ziemlich einfach. Ich habe eine Seite, die eine Kundensuche nach der gesamten E-Mail und nach einem Teil durchführt. Der Teil zieht eine Liste und zeigt sie an. Die Liste enthält einen Aktionslink, der auf ein Aktionsergebnis namens GetByID verweist und die ID übergibt

Die GetByID ruft die Daten für den ausgewählten Kunden ab und kehrt dann zurück

return View("Index", model); 

Welches ist die Post-Methode

DJ_PLaying
quelle
1

Das war für mich ein schwieriges Problem. Wie kann ich eine dynamische Verknüpfung in Rasiermesser und HTML erstellen, die eine Aktionsmethode aufrufen und einen oder mehrere Werte an eine bestimmte Aktionsmethode übergeben kann? Ich habe verschiedene Optionen in Betracht gezogen, darunter einen benutzerdefinierten HTML-Helfer. Ich habe gerade eine einfache und elegante Lösung gefunden.

Die Aussicht

@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>
}

Die Aktionsmethode

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");
}

Der Punkt hier ist, dass es Url.Action egal ist, ob die Aktionsmethode ein GET oder ein POST ist. Es wird auf beide Arten von Methoden zugegriffen. Sie können Ihre Daten mit an die Aktionsmethode übergeben

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

das routeValues-Objekt. Ich habe es versucht und es funktioniert. Nein, Sie machen technisch gesehen keinen Beitrag oder senden das Formular nicht, aber wenn das routeValues-Objekt Ihre Daten enthält, spielt es keine Rolle, ob es sich um einen Beitrag oder einen Abruf handelt. Sie können eine bestimmte Signatur der Aktionsmethode verwenden, um die richtige Methode auszuwählen.

wayne.blackmon
quelle
1
Ich habe Ihr Beispiel ausprobiert und der Browser sendet GET an den Server, sogar das Formular hat den Post-Typ. Wenn actionMethod im Controller das Attribut [HttpPost] hat, schlägt die Anforderung fehl, da die Route nicht gefunden wurde.
Vitaliy Markitanov
1

Ich habe das gleiche Problem mit folgendem Code gelöst:

@using (Html.BeginForm("Delete", "Admin"))
{
       @Html.Hidden("ProductID", item.ProductID)
       <input type="submit" value="Delete" />
}
isxaker
quelle
Wenn Sie viele Elemente auf der Seite haben, müssen Sie jedes in ein Formular einschließen. Infolgedessen werden viele Formulare generiert. Auch <input type = submit> rendert die Schaltfläche, nicht die Verknüpfung.
Vitaliy Markitanov
@VitaliyMarkitanov Sie schlagen vor, jQuery Ajax zu verwenden?
Isxaker
Schauen Sie sich meinen Beitrag unten in diesem Thread an, ich habe dort meine Lösung erklärt.
Vitaliy Markitanov
Im MVC-Beispielprojekt ist dies ziemlich genau das, was sie auch tun
Maya
1

Dies ist meine Lösung für das Problem. Dies ist ein Controller mit 2 Aktionsmethoden

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");
}
}

In View rendere ich das Konstrukt folgender Struktur.

<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>

Sonderziel in Razor View :

  1. JavaScript-Funktion, confirmDelete(id)die aufgerufen wird, wenn auf den mit generierten Link @Html.ActionLinkgeklickt wird.

  2. confirmDelete()Funktion erforderlich ID des angeklickten Elements. Dieses Element wird vom onClickHandler übergeben. confirmDelete("+feedback.Id+");return false;Achten Sie darauf, dass der Handler false zurückgibt, um eine Standardaktion zu verhindern, bei der die Anforderung an das Ziel gesendet wird. OnClickEreignis für Schaltflächen könnte alternativ mit jQuery für alle Schaltflächen in der Liste angehängt werden (wahrscheinlich ist es sogar noch besser, da weniger Text auf der HTML-Seite vorhanden ist und Daten über ein data-Attribut übergeben werden könnten ).

  3. Form hat id=myForm, um es zu finden confirmDelete().

  4. Formular enthält @Html.HttpMethodOverride(HttpVerbs.Delete), um das HttpDeleteVerb zu verwenden, als Aktion mit dem gekennzeichnet HttpDeleteAttribute.

  5. In der JS-Funktion verwende ich die Aktionsbestätigung (mit Hilfe eines externen Plugins, aber die Standardbestätigung funktioniert auch einwandfrei. Vergessen Sie nicht, sie bind()beim Rückruf oder var that=this(was auch immer Sie bevorzugen) zu verwenden.

  6. Form hat ein verstecktes Element mit id='idField'und name='id'. Bevor das Formular nach Bestätigung ( result==true) gesendet wird , wird der Wert des ausgeblendeten Elements auf den Wert übergeben, der übergeben wird, und der Browser sendet Daten wie folgt an den Controller:

URL anfordern :http://localhost:38874/Feedback/Delete

Anforderungsmethode : POST-Statuscode: 302 Gefunden

Antwortheader

Speicherort: / Feedback Host: localhost: 38874 Formulardaten X-HTTP-Methodenüberschreibung: DELETE id: 5

Wie Sie sehen, handelt es sich um eine POST-Anforderung mit X-HTTP-Method-Override: DELETE und Daten im Body, die auf "id: 5" gesetzt sind. Die Antwort enthält 302 Code, der zur Indexaktion umleitet. Dadurch aktualisieren Sie Ihren Bildschirm nach dem Löschen.

Vitaliy Markitanov
quelle
0

Ich würde empfehlen, die REST-Prinzipien einzuhalten und für Ihre Löschungen einen HTTP-Löschvorgang zu verwenden. Leider hat HTML Specs nur HTTP Get & Post. Ein Tag kann nur ein HTTP abrufen. Ein Formular-Tag kann entweder einen HTTP-Abruf oder einen Post ausführen. Glücklicherweise können Sie mit Ajax einen HTTP-Löschvorgang durchführen, und das empfehle ich. Weitere Informationen finden Sie im folgenden Beitrag: HTTP-Löschungen

Codierung4fun
quelle
0

Das Aufrufen von $ .post () funktioniert nicht, da es auf Ajax basiert. Zu diesem Zweck muss daher eine Hybridmethode verwendet werden.

Das Folgende ist die Lösung, die für mich funktioniert.

Schritte: 1. Erstellen Sie eine URL für href, die die a-Methode mit URL und Parameter aufruft. 2. Rufen Sie den normalen POST mit der JavaScript-Methode auf

Lösung:

In .cshtml:

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

Hinweis: Die anonyme Methode sollte in (....) () eingeschlossen sein, d. H.

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

postGo ist in JavaScript wie folgt definiert. Ruhe ist einfach ..

@ Url.Action ("View") erstellt eine URL für den Anruf

{'id': @ receive.ReceiptId} erstellt Parameter als Objekt, das wiederum in der postGo-Methode in POST-Felder konvertiert wird. Dies kann ein beliebiger Parameter sein

In 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);

Referenz-URLs, die ich für postGo verwendet habe

Nicht-Ajax-GET / POST mit jQuery (Plugin?)

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

Tejasvi Hegde
quelle
0

jQuery.post()funktioniert, wenn Sie benutzerdefinierte Daten haben. Wenn Sie ein vorhandenes Formular veröffentlichen möchten, ist es einfacher zu verwenden ajaxSubmit().

Und Sie müssen diesen Code nicht selbst einrichten ActionLink, da Sie im document.ready()Ereignis einen Link-Handler anhängen können (was ohnehin eine bevorzugte Methode ist), beispielsweise mit dem $(function(){ ... })jQuery-Trick.

Königin3
quelle
0

Kam über diese Notwendigkeit, von einer Suchseite (Index) zur Ergebnisseite zu POSTEN. Ich brauchte nicht so viel wie @Vitaliy angegeben hatte, aber es zeigte mir die richtige Richtung. Ich musste nur Folgendes tun:

@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>
}

Mein Controller hatte die folgende Signaturmethode:

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

Dies stammt aus dem MVC-Beispielprojekt

@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>
            }
        }
Maya
quelle