ASP.NET MVC ActionLink và phương thức đăng


97

Bất cứ ai có thể cho tôi biết làm thế nào tôi có thể gửi các giá trị đến Bộ điều khiển bằng cách sử dụng ActionLink và phương thức POST?
Tôi không muốn sử dụng các nút.
Tôi đoán nó có một cái gì đó với jquery.


1
Tôi đã viết một phương thức tương tự như Html.ActionLink, chỉ khác là nó xây dựng POST Form với nút Gửi. Tôi sẽ xem liệu tôi có thể cung cấp tùy chọn thay thế nút bằng liên kết gửi biểu mẫu hay không. Xem tại đây: stackoverflow.com/questions/3449807/…
nikib3ro

Câu trả lời:


58

Bạn không thể sử dụng một ActionLinkvì điều đó chỉ hiển thị một <a>thẻ liên kết.
Bạn có thể sử dụng một bài đăng jQuery AJAX .
Hoặc chỉ cần gọi phương thức gửi của biểu mẫu có hoặc không có jQuery (sẽ không phải là AJAX), có thể trong trường onclickhợp bất kỳ điều khiển nào bạn muốn.


70

Nếu bạn đang sử dụng ASP MVC3, bạn có thể sử dụng Ajax.ActionLink (), cho phép bạn chỉ định Phương thức HTTP mà bạn có thể đặt thành "POST".


45
Lưu ý rằng để làm cho việc này hoạt động, bạn sẽ phải bao gồm một trong các tệp javascript ajax, ví dụ: " jquery.unobtrusive-ajax.min.js". Nếu không, nó sẽ tiếp tục thực hiện GET thay vì POST khi được nhấp. Cú pháp để làm cho liên kết sẽ như thế nào:@Ajax.ActionLink("Delete", "Delete", new { id = item.Id }, new AjaxOptions {HttpMethod = "POST"})
CodingWithSpike

1
ajax không phô trương hoạt động tốt NHƯNG tôi phải sử dụng liên kết hành động hơi khác một chút, truyền Từ điển làm tham số thay vì đối tượng AjaxOptions này: stackoverflow.com/a/10657891/429521 Ngoài ra, tôi phải chuyển các thuộc tính ajax bằng tay để JS có thể bắt và ghi đè các sự kiện nhấp chuột "data-ajax"="true, "data-ajax-url"=<your link> and "data-ajax-method"="Post". Btw, tôi đang sử dụng ASP.NET MVC 3
Felipe Sabino,

1
@CokoB Đây có phải là một stackoverflow.com/questions/10507737/… ? có thật không? Nó dường như không thể bị phá vỡ cho tôi ...
Felipe Sabino

20

Bạn có thể sử dụng jQuery để thực hiện ĐĂNG cho tất cả các nút của mình. Chỉ cần cung cấp cho chúng cùng một tên CssClass.

Sử dụng "return false;" ở cuối sự kiện javascript onclick của bạn nếu bạn muốn thực hiện RedirectToAction phía máy chủ sau bài đăng, nếu không thì chỉ cần trả lại chế độ xem.

Mã dao cạo

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

Mã 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);
}

@ goodies4uall Thật vậy, và câu trả lời này chỉ làm được điều đó. :) Lớp CSS được đặt tên là "saveButton" (có lẽ là một tên gây hiểu lầm), nhưng một thẻ liên kết được sử dụng để bắt đầu hành động
Savantes

17

@Aidos đã có câu trả lời đúng chỉ muốn làm rõ vì nó được ẩn bên trong một nhận xét về bài đăng của anh ấy được thực hiện bởi @CodingWithSpike.

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

6

Đây là một câu trả lời được đưa vào dự án ASP.NET MVC 5 mặc định, tôi tin rằng điều đó sẽ hoàn thành mục tiêu tạo kiểu của tôi một cách độc đáo trong giao diện người dùng. Gửi biểu mẫu bằng javascript thuần túy đến một số biểu mẫu có chứa.

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

Trường hợp sử dụng được hiển thị đầy đủ là danh sách đăng xuất thả xuống trong thanh điều hướng của ứng dụng 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>
}

3

ActionLink sẽ không bao giờ kích hoạt bài đăng. Nó luôn kích hoạt yêu cầu GET.


2

Sử dụng liên kết Gọi hành động sau:

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

Để gửi các giá trị biểu mẫu, hãy sử dụng:

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

Nó sẽ gửi Dữ liệu cho Người kiểm soát khách hàng và Hành động CustomerSearchResults.


1

Sử dụng liên kết này bên trong Ajax.BeginForm

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

;)


1

Giải pháp của tôi cho vấn đề này là một giải pháp khá đơn giản. Tôi có một trang mà khách hàng tìm kiếm lần lượt toàn bộ email và trang kia tìm kiếm từng phần, một phần kéo và hiển thị danh sách, danh sách có liên kết hành động trỏ đến kết quả hành động được gọi là GetByID và chuyển vào id

GetByID kéo dữ liệu cho khách hàng đã chọn sau đó trả về

return View("Index", model); 

phương pháp đăng bài là gì


1

Đây là một vấn đề khó giải quyết đối với tôi. Làm cách nào để tạo liên kết động trong dao cạo và html có thể gọi một phương thức hành động và chuyển một giá trị hoặc các giá trị cho một phương thức hành động cụ thể? Tôi đã xem xét một số tùy chọn bao gồm một trình trợ giúp html tùy chỉnh. Tôi chỉ nghĩ ra một giải pháp đơn giản và thanh lịch.

Quang cảnh

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

Phương pháp hành động

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

Vấn đề ở đây là Url.Action không quan tâm đến việc phương thức hành động là GET hay POST. Nó sẽ truy cập một trong hai loại phương thức. Bạn có thể chuyển dữ liệu của mình sang phương thức hành động bằng cách sử dụng

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

đối tượng routeValues. Tôi đã thử điều này và nó hoạt động. Không, về mặt kỹ thuật bạn không thực hiện một bài đăng hoặc gửi biểu mẫu nhưng nếu đối tượng routeValues ​​chứa dữ liệu của bạn, thì nó là bài đăng hay nhận được. Bạn có thể sử dụng một chữ ký của phương thức hành động cụ thể để chọn phương pháp phù hợp.


1
Tôi đã thử mẫu của bạn và trình duyệt gửi GET đến máy chủ, ngay cả biểu mẫu có loại Đăng. Nếu actionMethod trong bộ điều khiển có thuộc tính [HttpPost] yêu cầu không thành công vì không tìm thấy tuyến.
Vitaliy Markitanov,

1

Tôi đã thực hiện cùng một vấn đề bằng cách sử dụng mã sau:

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

Nếu bạn có nhiều mục trên trang, bạn sẽ cần phải kết hợp từng mục đó thành biểu mẫu, và kết quả là nhiều biểu mẫu sẽ được tạo. Ngoài ra <input type = submit> nút kết xuất, không phải liên kết.
Vitaliy Markitanov,

@VitaliyMarkitanov bạn đề xuất sử dụng jQuery ajax?
isxaker,

Nhìn vào bài viết của tôi bên dưới trong chủ đề này, tôi đã giải thích giải pháp của mình ở đó.
Vitaliy Markitanov,

Trong dự án mẫu MVC, đây cũng chính là những gì họ làm
Maya

1

Đây là giải pháp của tôi cho vấn đề. Đây là bộ điều khiển với 2 phương thức hành động

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

Trong View, tôi kết xuất cấu trúc sau.

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

Điểm quan tâm trong Razor View :

  1. Hàm JavaScript confirmDelete(id)được gọi khi liên kết được tạo bằng @Html.ActionLinkđược nhấp vào;

  2. confirmDelete()id yêu cầu chức năng của mục được nhấp. Mục này được chuyển từ onClicktrình xử lý confirmDelete("+feedback.Id+");return false;Chú ý xử lý trả về false để ngăn hành động mặc định - là nhận yêu cầu để nhắm mục tiêu. OnClickSự kiện cho các nút có thể được đính kèm với jQuery cho tất cả các nút trong danh sách để thay thế (có lẽ nó sẽ tốt hơn, vì nó sẽ ít văn bản hơn trong trang HTML và dữ liệu có thể được chuyển qua data-thuộc tính).

  3. Biểu mẫu có id=myForm, để tìm thấy nó trong confirmDelete().

  4. Hình thức bao gồm @Html.HttpMethodOverride(HttpVerbs.Delete)để sử dụng HttpDeleteđộng từ, như hành động được đánh dấu với HttpDeleteAttribute.

  5. Trong hàm JS, tôi sử dụng xác nhận hành động (với sự trợ giúp của plugin bên ngoài, nhưng xác nhận tiêu chuẩn cũng hoạt động tốt. Đừng quên sử dụng bind()trong cuộc gọi lại hoặc var that=this(bất cứ điều gì bạn thích).

  6. Biểu mẫu có một phần tử ẩn với id='idField'name='id'. Vì vậy, trước khi biểu mẫu được gửi sau khi xác nhận ( result==true), giá trị của phần tử ẩn được đặt thành giá trị được truyền đối số và trình duyệt sẽ gửi dữ liệu đến bộ điều khiển như sau:

URL yêu cầu :http://localhost:38874/Feedback/Delete

Phương thức yêu cầu : ĐĂNG Mã trạng thái: Đã tìm thấy 302

Tiêu đề phản hồi

Vị trí: / Máy chủ phản hồi: localhost: 38874 Dữ liệu biểu mẫu X-HTTP-Phương thức-Ghi đè: DELETE id: 5

Như bạn thấy, đó là yêu cầu ĐĂNG với X-HTTP-Method-Override: DELETE và dữ liệu trong nội dung được đặt thành "id: 5". Phản hồi có mã 302 chuyển hướng đến hành động Lập chỉ mục, bằng cách này bạn làm mới màn hình của mình sau khi xóa.


0

Tôi khuyên bạn nên tuân thủ các nguyên tắc REST và sử dụng HTTP delete cho các lần xóa của bạn. Rất tiếc HTML Specs chỉ có HTTP Get & Post. Chỉ một thẻ mới có thể nhận HTTP. Thẻ biểu mẫu có thể thực hiện HTTP Get hoặc Post. May mắn thay nếu bạn sử dụng ajax, bạn có thể thực hiện Xóa HTTP và đây là những gì tôi khuyên bạn nên. Xem bài đăng sau để biết chi tiết: Http Deletes


0

Gọi $ .post () sẽ không hoạt động vì nó dựa trên Ajax. Vì vậy một phương pháp lai cần được sử dụng cho mục đích này.

Sau đây là giải pháp phù hợp với tôi.

Các bước: 1. Tạo URL cho href gọi một phương thức với url và tham số 2. Gọi POST bình thường bằng phương thức JavaScript

Giải pháp:

Trong .cshtml:

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

Lưu ý: phương thức ẩn danh nên được gói trong (....) () tức là

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

postGo được định nghĩa như bên dưới trong JavaScript. Phần còn lại rất đơn giản ..

@ Url.Action ("View") tạo url cho cuộc gọi

{'id': @ accept.ReceiptId} tạo các tham số dưới dạng đối tượng được chuyển đổi lần lượt thành các trường POST trong phương thức postGo. Đây có thể là bất kỳ tham số nào bạn yêu cầu

Trong 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 tham chiếu mà tôi đã sử dụng cho postGo

GET / POST không phải ajax bằng jQuery (plugin?)

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


0

jQuery.post()sẽ hoạt động nếu bạn có dữ liệu tùy chỉnh. Nếu bạn muốn đăng biểu mẫu hiện có, nó sẽ dễ sử dụng hơn ajaxSubmit().

Và bạn không phải thiết lập mã này trong ActionLinkchính nó, vì bạn có thể đính kèm trình xử lý liên kết trong document.ready()sự kiện (dù sao thì đó cũng là một phương pháp ưu tiên), ví dụ như sử dụng $(function(){ ... })thủ thuật jQuery.


0

Bắt gặp điều này cần ĐĂNG từ trang Tìm kiếm (Chỉ mục) đến trang Kết quả. Tôi không cần nhiều như @Vitaliy đã nêu nhưng nó đã chỉ cho tôi đi đúng hướng. Tất cả những gì tôi phải làm là:

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

Bộ điều khiển của tôi có phương pháp chữ ký sau:

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

0

Điều này được lấy từ dự án mẫu 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>
            }
        }
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.