ASP.NET MVC ActionLink和发布方法


97

谁能告诉我如何使用ActionLink和POST方法将值提交到Controller?
我不想使用按钮。
我猜它与jQuery有关。


1
我写了一个类似于Html.ActionLink的方法,只是它使用Submit按钮构建POST Form。我将看看是否可以选择用提交表单的链接替换按钮。看到这里:stackoverflow.com/questions/3449807/…–
nikib3ro

Answers:


58

您不能使用,ActionLink因为这只会呈现锚<a>标记。
您可以使用jQuery AJAX帖子
或仅在带有或不带有jQuery(这将是非AJAX)的情况下调用表单的Submit方法,也许是在onclick任何控件需要的情况下。


70

如果您使用的是ASP MVC3,则可以使用Ajax.ActionLink(),它允许您指定可以设置为“ POST”的HTTP方法。


45
请注意,要使此工作有效,您将必须包含一个ajax javascript文件,例如“ jquery.unobtrusive-ajax.min.js”。否则,单击后它将继续执行GET而不是POST。进行链接的语法如下:@Ajax.ActionLink("Delete", "Delete", new { id = item.Id }, new AjaxOptions {HttpMethod = "POST"})
CodingWithSpike

1
不显眼的ajax可以正常工作,但是我不得不使用动作链接,将字典作为参数而不是此AjaxOptions对象传递:stackoverflow.com/a/10657891/429521另外,我必须手动传递ajax属性,以便JS可以捕获并覆盖click事件,它们是"data-ajax"="true, "data-ajax-url"=<your link> and "data-ajax-method"="Post"。顺便说一句,我正在使用ASP.NET MVC 3
Felipe Sabino 2012年

1
@CokoBWare这个stackoverflow.com/questions/10507737/…?真?它对我来说似乎并不
Felipe Sabino

20

您可以使用jQuery对所有按钮进行POST。只需给他们相同的CssClass名称即可。

使用“返回假”;如果要在发布后执行服务器端RedirectToAction,请在onclick javascript事件结束时进行操作,否则只需返回视图即可。

剃刀代码

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

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确实,这个答案就是这样。:) CSS类的名称为“ saveButton”(可能是一个令人误解的名称),但是使用锚标记来启动操作
Savantes 17-4-25

17

@Aidos的答案是正确的,只是想弄清楚,因为它隐藏在@CodingWithSpike发表的评论中。

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

6

这是默认ASP.NET MVC 5项目中的一个答案,我相信它可以在UI中很好地实现我的样式目标。使用纯JavaScript将表单提交到某些包含表单的表单。

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

完整显示的用例是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>
}


2

使用以下“调用操作”链接:

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

要提交表单值,请使用:

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

它将数据提交给Customer Controller和CustomerSearchResults Action。



1

我对这个问题的解决方法很简单。我有一个页面,客户可以通过该页面搜索整个电子邮件,另一部分则通过部分搜索,部分拉出并显示一个列表,列表中有一个操作链接,该操作链接指向一个称为GetByID的操作结果并传递ID

GetByID为选定客户提取数据,然后返回

return View("Index", model); 

这是发布方法


1

这对我来说是一个很难解决的问题。如何在razor和html中建立一个动态链接,该链接可以调用操作方法并将一个或多个值传递给特定的操作方法?我考虑了几个选项,包括自定义html助手。我只是想出了一个简单而优雅的解决方案。

风景

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

动作方法

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

这里的重点是Url.Action不在乎该操作方法是GET还是POST。它将访问任何一种方法。您可以使用以下方法将数据传递给操作方法

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

routeValues对象。我已经尝试过了,并且有效。不,从技术上讲,您不是在张贴或提交表单,但是,如果routeValues对象包含您的数据,则无论张贴还是获取都没有关系。您可以使用特定的操作方法签名来选择正确的方法。


1
我尝试了您的示例,浏览器将GET发送到服务器,即使表单具有Post类型。如果控制器中的actionMethod具有属性[HttpPost],则请求失败,因为找不到路由。
Vitaliy Markitanov,2015年

1

我已经使用以下代码完成了相同的问题:

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

如果页面上有很多项目,则需要将每个项目包装成表格,结果将生成许多表格。同样,<input type = submit>呈现按钮,而不是链接。
Vitaliy Markitanov,2015年

@VitaliyMarkitanov,建议您使用jQuery ajax?
isxaker

在此线程下查看我的帖子,我在那里解释了我的解决方案。
Vitaliy Markitanov,2015年

在MVC示例项目中,这几乎就是他们所做的工作
Maya 19'5

1

这是我解决这个问题的方法。这是具有2种动作方法的控制器

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

在视图中,我渲染构造以下结构。

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

Razor View的景点

  1. 单击confirmDelete(id)生成的链接时调用的JavaScript函数@Html.ActionLink

  2. confirmDelete()功能必填项被点击的ID。此项从onClick处理程序传递。confirmDelete("+feedback.Id+");return false;注意处理程序返回false以防止执行默认操作-这是对目标的get请求。OnClick按钮的事件可以与jQuery一起附加在列表中的所有按钮上(可能会更好,因为HTML页面中的文本会更少,并且可以通过data-属性传递数据)。

  3. 表格有id=myForm,以便在中找到它confirmDelete()

  4. 形式包括@Html.HttpMethodOverride(HttpVerbs.Delete)为了使用HttpDelete动词,用标记为动作HttpDeleteAttribute

  5. 在JS函数中,我确实使用动作确认(借助外部插件,但标准确认也可以正常工作。请不要忘记bind()在回叫或var that=this(无论您喜欢什么)中使用)。

  6. 形式有一个隐藏的元素id='idField'name='id'。因此,在确认(result==true)后提交表单之前,隐藏元素的值设置为值传递的参数,浏览器将向控制器提交数据,如下所示:

要求网址http://localhost:38874/Feedback/Delete

请求方法:POST状态码:302

响应标题

位置:/ Feedback主机:localhost:38874 表单数据 X-HTTP-Method-Override:DELETE ID:5

如您所见,它是带有X-HTTP-Method-Override:DELETE的POST请求,主体中的数据设置为“ id:5”。响应具有302代码,可重定向到索引动作,由此您可以在删除后刷新屏幕。


0

我建议您遵循REST原则,并使用HTTP删除进行删除。不幸的是HTML规范只有HTTP Get&Post。标记只能是HTTP Get。表单标签可以执行HTTP Get或Post。幸运的是,如果您使用ajax,则可以执行HTTP Delete,这是我的建议。有关详细信息,请参见以下帖子:Http Deletes


0

调用$ .post()无效,因为它是基于Ajax的。因此,为此需要使用一种混合方法。

以下是对我有用的解决方案。

步骤:1.为href创建URL,该URL使用url和参数调用a方法。2.使用JavaScript方法调用普通的POST。

解:

在.cshtml中:

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

注意:匿名方法应该用(....)()包装,即

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

postGo在JavaScript中定义如下。休息很简单..

@ Url.Action(“ View”)为调用创建URL

{'id':@ receipt.ReceiptId}将参数创建为对象,然后将其转换为postGo方法中的POST字段。可以是您需要的任何参数

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

我用于postGo的参考URL

使用jQuery的非ajax GET / POST(插件?)

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


0

jQuery.post()如果您有自定义数据,它将起作用。如果您要发布现有表单,则使用起来会更容易ajaxSubmit()

而且您不必自己设置此代码ActionLink,因为您可以在document.ready()事件中附加链接处理程序(无论如何这是首选方法),例如使用$(function(){ ... })jQuery技巧。


0

遇到了需要从“搜索(索引)”页面POST到“结果”页面的问题。我不需要@Vitaliy所说的,但它为我指明了正确的方向。我要做的就是:

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

我的控制器具有以下签名方法:

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

0

这取自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>
            }
        }
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.