ASP.NET MVC ActionLink dan metode posting

97

Adakah yang bisa memberitahu saya bagaimana saya bisa mengirimkan nilai ke Controller menggunakan metode ActionLink dan POST?
Saya tidak ingin menggunakan tombol.
Saya rasa ada sesuatu dengan jquery.

šljaker
sumber
1
Saya telah menulis metode yang mirip dengan Html.ActionLink, hanya saja ia membangun Formulir POST dengan tombol Kirim. Saya akan melihat apakah saya dapat memberikan opsi untuk mengganti tombol dengan tautan yang mengirimkan formulir. Lihat di sini: stackoverflow.com/questions/3449807/…
nikib3ro

Jawaban:

58

Anda tidak dapat menggunakan ActionLinkkarena itu hanya membuat <a>tag jangkar .
Anda dapat menggunakan file posting jQuery AJAX .
Atau cukup panggil metode pengiriman formulir dengan atau tanpa jQuery (yang akan menjadi non-AJAX), mungkin dalam onclickhal kontrol apa pun yang Anda sukai.

AUSteve
sumber
70

Jika Anda menggunakan ASP MVC3, Anda dapat menggunakan Ajax.ActionLink (), yang memungkinkan Anda menentukan Metode HTTP yang dapat Anda setel ke "POST".

Aidos
sumber
45
Perhatikan bahwa untuk membuat ini berfungsi, Anda harus menyertakan salah satu file javascript ajax, misalnya " jquery.unobtrusive-ajax.min.js". Jika tidak, itu akan terus melakukan GET daripada POST ketika diklik. Sintaks untuk membuat link akan seperti ini:@Ajax.ActionLink("Delete", "Delete", new { id = item.Id }, new AjaxOptions {HttpMethod = "POST"})
CodingWithSpike
1
ajax yang tidak mengganggu berfungsi dengan baik TAPI saya harus menggunakan tautan tindakan sedikit berbeda, meneruskan Kamus sebagai parameter alih-alih objek AjaxOptions ini: stackoverflow.com/a/10657891/429521 Juga, saya harus meneruskan atribut ajax dengan tangan sehingga JS dapat menangkap dan menimpa peristiwa klik "data-ajax"="true, "data-ajax-url"=<your link> and "data-ajax-method"="Post". Btw, saya menggunakan ASP.NET MVC 3
Felipe Sabino
1
@CokoBWare ini stackoverflow.com/questions/10507737/… ? Betulkah? Tampaknya tidak rusak bagi saya ...
Felipe Sabino
20

Anda dapat menggunakan jQuery untuk melakukan POST untuk semua tombol Anda. Beri mereka nama CssClass yang sama.

Gunakan "return false;" di akhir acara javascript onclick Anda jika Anda ingin melakukan RedirectToAction sisi server setelah posting jika tidak, cukup kembalikan tampilan.

Kode Razor

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

Kode 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);
}
Idris
sumber
@ goodies4uall Memang, dan jawaban ini tidak hanya itu. :) Kelas CSS dinamai "saveButton" (mungkin nama yang menyesatkan), tetapi tag anchor digunakan untuk memulai tindakan
Savantes
17

@Aidos punya jawaban yang benar hanya ingin memperjelas karena tersembunyi di dalam komentar di postingannya yang dibuat oleh @CodingWithSpike.

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

Berikut adalah jawaban yang dimasukkan ke dalam proyek ASP.NET MVC 5 default yang saya percayai yang menyelesaikan tujuan gaya saya dengan baik di UI. Pengiriman formulir menggunakan javascript murni ke beberapa formulir yang mengandung.

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

Kasus penggunaan yang ditampilkan sepenuhnya adalah tarik-turun logout di bilah navigasi aplikasi 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>
}
daniel.caspers
sumber
3

ActionLink tidak akan pernah mengaktifkan postingan. Itu selalu memicu permintaan GET.

Navish Rampal
sumber
2

Gunakan link Call the Action berikut:

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

Untuk mengirimkan nilai formulir gunakan:

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

Ini akan mengirimkan Data ke Pengontrol Pelanggan dan Tindakan CustomerSearchResults.

Navish Rampal
sumber
1

Gunakan tautan ini di dalam 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
sumber
1

Solusi saya untuk masalah ini cukup sederhana. Saya memiliki halaman yang melakukan pencarian pelanggan satu per satu seluruh email dan yang lainnya sebagian, sebagian menarik dan menampilkan daftar daftar tersebut memiliki tautan tindakan yang mengarah ke hasil tindakan yang disebut GetByID dan meneruskan di id

GetByID menarik data untuk pelanggan yang dipilih lalu mengembalikannya

return View("Index", model); 

yang merupakan metode posting

DJ_PLaying
sumber
1

Ini adalah masalah yang sulit saya pecahkan. Bagaimana cara membuat tautan dinamis di pisau cukur dan html yang dapat memanggil metode tindakan dan meneruskan nilai atau nilai ke metode tindakan tertentu? Saya mempertimbangkan beberapa opsi termasuk pembantu html khusus. Saya baru saja menemukan solusi yang sederhana dan elegan.

Pandangan

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

Metode tindakan

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

Intinya di sini adalah bahwa Url.Action tidak peduli apakah metode tindakan adalah GET atau POST. Ini akan mengakses salah satu jenis metode. Anda dapat meneruskan data Anda ke metode tindakan menggunakan

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

objek routeValues. Saya telah mencoba ini dan berhasil. Tidak, Anda tidak secara teknis melakukan posting atau mengirimkan formulir tetapi jika objek routeValues ​​berisi data Anda, tidak masalah apakah itu posting atau get. Anda dapat menggunakan tanda tangan metode tindakan tertentu untuk memilih metode yang tepat.

wayne.blackmon
sumber
1
Saya mencoba sampel Anda dan browser mengirimkan GET ke server, bahkan formulir memiliki tipe Post. Jika actionMethod dalam controller memiliki atribut [HttpPost], permintaan gagal karena rute tidak ditemukan.
Vitaliy Markitanov
1

Saya telah melakukan masalah yang sama menggunakan kode berikut:

@using (Html.BeginForm("Delete", "Admin"))
{
       @Html.Hidden("ProductID", item.ProductID)
       <input type="submit" value="Delete" />
}
pembuat isxaker
sumber
Jika Anda memiliki banyak item di halaman, Anda harus membungkusnya menjadi formulir, dan sebagai hasilnya, banyak formulir akan dibuat. Juga <input type = submit> tombol render, bukan link.
Vitaliy Markitanov
@VitaliyMarkitanov Anda menyarankan untuk menggunakan jQuery ajax?
isxaker
Lihat posting saya di bawah ini di utas ini, saya menjelaskan solusi saya di sana.
Vitaliy Markitanov
Dalam proyek sampel MVC, ini persis seperti yang mereka lakukan juga
Maya
1

Ini adalah solusi saya untuk masalah tersebut. Ini adalah pengontrol dengan 2 metode tindakan

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

Dalam View saya membuat konstruksi struktur berikut.

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

Tempat menarik di Razor View :

  1. Fungsi JavaScript confirmDelete(id)yang dipanggil saat link yang dihasilkan @Html.ActionLinkdiklik;

  2. confirmDelete()fungsi diperlukan id dari item yang diklik. Item ini diteruskan dari onClickhandler. confirmDelete("+feedback.Id+");return false;Perhatikan handler mengembalikan false untuk mencegah aksi default - yaitu mendapatkan permintaan ke target. OnClickacara untuk tombol dapat dilampirkan dengan jQuery untuk semua tombol dalam daftar sebagai alternatif (mungkin akan lebih baik lagi, karena akan lebih sedikit teks di halaman HTML dan data dapat diteruskan melalui data-atribut).

  3. Formulir memiliki id=myForm, untuk menemukannya confirmDelete().

  4. Bentuk termasuk @Html.HttpMethodOverride(HttpVerbs.Delete)untuk menggunakan HttpDeletekata kerja, sebagai tindakan yang ditandai dengan HttpDeleteAttribute.

  5. Dalam fungsi JS saya menggunakan konfirmasi tindakan (dengan bantuan plugin eksternal, tetapi konfirmasi standar juga berfungsi dengan baik. Jangan lupa untuk menggunakan bind()panggilan balik atau var that=this(apa pun yang Anda inginkan).

  6. Formulir memiliki elemen tersembunyi dengan id='idField'dan name='id'. Jadi sebelum formulir dikirimkan setelah konfirmasi ( result==true), nilai elemen tersembunyi diatur ke nilai yang melewati argumen dan browser akan mengirimkan data ke pengontrol seperti ini:

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

Metode Permintaan : Kode Status POST: 302 Ditemukan

Header Respons

Lokasi: / Umpan balik Host: localhost: 38874 Formulir Data X-HTTP-Metode-Override: DELETE id: 5

Seperti yang Anda lihat, ini adalah permintaan POST dengan X-HTTP-Method-Override: DELETE dan data dalam isi diatur ke "id: 5". Respon memiliki kode 302 yang mengarahkan ke tindakan Indeks, dengan ini Anda menyegarkan layar Anda setelah menghapus.

Vitaliy Markitanov
sumber
0

Saya akan merekomendasikan tetap murni untuk prinsip REST dan menggunakan HTTP delete untuk menghapus Anda. Sayangnya Spesifikasi HTML hanya memiliki HTTP Get & Post. Sebuah tag hanya bisa mendapatkan HTTP. Tag formulir dapat melakukan HTTP Get atau Post. Untungnya jika Anda menggunakan ajax Anda dapat melakukan HTTP Delete dan inilah yang saya rekomendasikan. Lihat posting berikut untuk detailnya: Http Deletes

coding4fun
sumber
0

Memanggil $ .post () tidak akan berfungsi karena berbasis Ajax. Jadi metode hybrid perlu digunakan untuk tujuan ini.

Berikut adalah solusi yang berhasil untuk saya.

Langkah-langkah: 1. Buat URL untuk href yang memanggil metode dengan url dan parameter 2. Panggil POST normal menggunakan metode JavaScript

Larutan:

Dalam .cshtml:

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

Catatan: metode anonim harus dibungkus dengan (....) () yaitu

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

postGo didefinisikan seperti di bawah ini dalam JavaScript. Istirahat itu sederhana ..

@ Url.Ation ("Tampilan") membuat url untuk panggilan tersebut

{'id': @ accept.ReceiptId} membuat parameter sebagai objek yang kemudian diubah menjadi bidang POST dalam metode postGo. Ini dapat berupa parameter apa pun yang Anda butuhkan

Dalam 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 referensi yang telah saya gunakan untuk postGo

GET / POST non-ajax menggunakan jQuery (plugin?)

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

Tejasvi Hegde
sumber
0

jQuery.post()akan berfungsi jika Anda memiliki data khusus. Jika Anda ingin memposting formulir yang sudah ada, lebih mudah digunakan ajaxSubmit().

Dan Anda tidak perlu menyiapkan kode ini ActionLinksendiri, karena Anda dapat melampirkan penangan tautan dalam document.ready()acara (yang merupakan metode yang lebih disukai), misalnya menggunakan $(function(){ ... })trik jQuery.

ratu3
sumber
0

Menemukan ini perlu POST dari halaman Pencarian (Indeks) ke halaman Hasil. Saya tidak membutuhkan sebanyak yang @Vitaliy nyatakan tetapi itu mengarahkan saya ke arah yang benar. Yang harus saya lakukan hanyalah ini:

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

Pengontrol saya memiliki metode tanda tangan berikut:

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

Ini diambil dari proyek sampel 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>
            }
        }
Maya
sumber