ASP.NET MVC ActionLink и метод публикации


97

Может ли кто-нибудь сказать мне, как я могу отправить значения в контроллер с помощью метода ActionLink и POST?
Я не хочу использовать кнопки.
Я думаю, что в этом есть что-то с jquery.


1
Я написал метод, похожий на Html.ActionLink, только он создает форму POST с кнопкой «Отправить». Я посмотрю, смогу ли я дать возможность заменить кнопку ссылкой, которая отправляет форму. Смотрите здесь: stackoverflow.com/questions/3449807/…
nikib3ro

Ответы:


58

Вы не можете использовать, ActionLinkпотому что он просто отображает <a>тег привязки .
Вы можете использовать сообщение jQuery AJAX .
Или просто вызовите метод отправки формы с jQuery или без него (который не был бы AJAX), возможно, в onclickслучае любого элемента управления, который вам нравится.


70

Если вы используете ASP MVC3, вы можете использовать Ajax.ActionLink (), который позволяет вам указать HTTP-метод, который вы можете установить на «POST».


45
Обратите внимание, что для выполнения этой работы вам нужно будет включить один из файлов javascript ajax, например " jquery.unobtrusive-ajax.min.js". В противном случае при щелчке он продолжит выполнять GET вместо POST. Синтаксис для создания ссылки будет примерно таким:@Ajax.ActionLink("Delete", "Delete", new { id = item.Id }, new AjaxOptions {HttpMethod = "POST"})
CodingWithSpike 05

1
ненавязчивый ajax работал нормально, НО мне пришлось использовать ссылку действия немного иначе, передав словарь в качестве параметра вместо этого объекта AjaxOptions: stackoverflow.com/a/10657891/429521 Кроме того, мне пришлось передать атрибуты ajax вручную, чтобы JS мог перехватывать и переопределять события щелчка "data-ajax"="true, "data-ajax-url"=<your link> and "data-ajax-method"="Post". Кстати, я использую ASP.NET MVC 3
Фелипе Сабино

1
@CokoBWare этот stackoverflow.com/questions/10507737/… ? действительно? Мне кажется, это не сломано ...
Фелипе Сабино

20

Вы можете использовать jQuery для выполнения POST для всех ваших кнопок. Просто дайте им то же имя CssClass.

Используйте "return false;" в конце вашего события javascript onclick, если вы хотите выполнить RedirectToAction на стороне сервера после публикации, в противном случае просто верните представление.

Код бритвы

@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

18

@Aidos получил правильный ответ, просто хотел прояснить, поскольку он скрыт внутри комментария к его сообщению, сделанному @CodingWithSpike.

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

6

Это был ответ, запеченный в проект ASP.NET MVC 5 по умолчанию, который, я считаю, хорошо выполняет мои задачи по стилизации в пользовательском интерфейсе. Отправка формы с использованием чистого 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>
}

Полностью показанный вариант использования - это раскрывающийся список выхода на панели навигации веб-приложения.

@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" />
   <% } %>

Он отправит Данные в Контроллер клиентов и действие CustomerSearchResults.


1

Используйте эту ссылку внутри Ajax.BeginForm

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

;)


1

Мое решение этой проблемы довольно простое. У меня есть страница, на которой клиент выполняет поиск по всему электронному письму, а другой по частям, частичное извлекает и отображает список, в котором есть ссылка на действие, которая указывает на результат действия под названием GetByID и передает идентификатор

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 на сервер, даже если форма имеет тип сообщения. Если actionMethod в контроллере имеет атрибут [HttpPost], запрос не выполняется, так как маршрут не найден.
Виталий Маркитанов

1

Я сделал ту же проблему, используя следующий код:

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

Если у вас много элементов на странице, вам нужно будет обернуть каждый из них в форму, и в результате будет создано много форм. Также <input type = submit> отображает кнопку, а не ссылку.
Виталий Маркитанов

@VitaliyMarkitanov вы предлагаете использовать jQuery ajax?
isxaker

Посмотрите мой пост ниже в этой теме, там я объяснил свое решение.
Виталий Маркитанов

В примере проекта MVC это в значительной степени именно то, что они делают
Maya

1

Это мое решение проблемы. Это контроллер с двумя методами действий

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

Во View визуализирую конструкцию следующей структуры.

<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. Функция JavaScript, confirmDelete(id)которая вызывается при нажатии на ссылку, созданную с помощью @Html.ActionLink;

  2. confirmDelete()функция требует id элемента, по которому щелкают. Этот элемент передается из onClickобработчика. confirmDelete("+feedback.Id+");return false;Обратите внимание, что обработчик возвращает false, чтобы предотвратить действие по умолчанию - получение запроса к цели. 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) значение скрытого элемента устанавливается на значение переданного аргумента, и браузер отправляет данные контроллеру следующим образом:

URL запроса :http://localhost:38874/Feedback/Delete

Метод запроса : Код состояния POST: 302 Найдено

Заголовки ответа

Расположение: / Хост обратной связи: localhost: 38874 Данные формы X-HTTP-Method-Override: DELETE id: 5

Как видите, это POST-запрос с X-HTTP-Method-Override: DELETE и данными в теле, установленными на «id: 5». В ответе есть код 302, который перенаправляет на действие Index, таким образом вы обновляете свой экран после удаления.


0

Я бы рекомендовал придерживаться принципов REST и использовать HTTP-удаление для удаления. К сожалению, в спецификациях HTML есть только HTTP Get & Post. Тег может получить только HTTP. Тег формы может выполнять HTTP Get или Post. К счастью, если вы используете ajax, вы можете выполнить HTTP-удаление, и это то, что я рекомендую. Подробности смотрите в следующем сообщении: Http Deletes


0

Вызов $ .post () не будет работать, поскольку он основан на Ajax. Поэтому для этой цели необходимо использовать гибридный метод.

Ниже приводится решение, которое работает для меня.

Шаги: 1. Создайте URL-адрес для href, который вызывает метод с URL-адресом и параметром 2. Вызовите обычный POST с использованием метода JavaScript.

Решение:

В .cshtml:

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

Примечание: анонимный метод должен быть заключен в (....) (), т.е.

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

postGo определяется в JavaScript, как показано ниже. Остальные просты ..

@ Url.Action ("Просмотр") создает URL для звонка.

{'id': @ accept.ReceiptId} создает параметры как объект, который, в свою очередь, преобразуется в поля POST в методе postGo. Это может быть любой параметр, который вам нужен

В 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-адреса, которые я использовал для postGo

GET / POST без использования ajax с использованием jQuery (плагин?)

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>
            }
        }
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.