Метод ASP.NET MVC ActionLink та post


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

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

1
@CokoBWare це один stackoverflow.com/questions/10507737 / ... ? справді? Здається, це не зламане для мене ...
Феліпе Сабіно

20

Ви можете використовувати jQuery, щоб зробити POST для всіх своїх кнопок. Просто дайте їм те саме ім'я CssClass.

Використовуйте "return false;" наприкінці події onclick javascript, якщо ви хочете зробити сервер 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

17

@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

Скористайтеся наступним посиланням Call the Action:

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

Для подання значень форми використовуйте:

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

Він передасть Дані Контролеру клієнтів та Клієнту.


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

Це було важкою проблемою для мене. Як я можу побудувати динамічне посилання в бритві та 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" />
}

Якщо у вас на сторінці багато елементів, вам потрібно буде загорнути кожен з них у форму, і в результаті буде сформовано багато форм. Також <type type = submit> кнопка візуалізації, а не посилання.
Віталій Маркітанов

@VitaliyMarkitanov Ви пропонуєте використовувати jQuery ajax?
isxaker

Подивіться на мій пост нижче в цій темі, і я пояснив своє рішення там.
Віталій Маркітанов

У зразковому проекті MVC це дуже точно те, що вони теж роблять
Майя

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

У перегляді я представляю наступну структуру.

<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()потрібна функція ідентифікатора елемента, що натискається. Цей елемент передається від onClickобробника. confirmDelete("+feedback.Id+");return 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- Переопрацювання методу: DELETE id: 5

Як ви бачите, це POST-запит із методом X-HTTP-Override: DELETE та дані в тілі, встановлені на "id: 5". У відповіді є код 302, який переспрямовує на дію "Індекс", цим ви оновлюєте екран після видалення.


0

Я рекомендую дотримуватися принципів REST та використовувати видалення HTTP для своїх делетів. На жаль, у HTML Specs є лише HTTP Get & Post. Тег може отримати лише HTTP. Тег форми може робити HTTP Get або Post. На щастя, якщо ви використовуєте ajax, ви можете зробити видалення HTTP, і саме це я рекомендую. Детальніше див. У наступному дописі: Http Видаляє


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': @ квитанція.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

Non-ajax GET / POST за допомогою 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.