Czy ktoś może mi powiedzieć, jak mogę przesłać wartości do kontrolera za pomocą metody ActionLink i POST?
Nie chcę używać przycisków.
Myślę, że ma coś z jQuery.
Czy ktoś może mi powiedzieć, jak mogę przesłać wartości do kontrolera za pomocą metody ActionLink i POST?
Nie chcę używać przycisków.
Myślę, że ma coś z jQuery.
Odpowiedzi:
Nie możesz użyć, ActionLink
ponieważ po prostu renderuje <a>
tag kotwicy .
Możesz użyć posta jQuery AJAX .
Lub po prostu wywołaj metodę przesyłania formularza z lub bez jQuery (który byłby inny niż AJAX), być może w onclick
przypadku dowolnej kontroli.
Jeśli używasz ASP MVC3, możesz użyć Ajax.ActionLink (), która pozwala określić metodę HTTP, którą możesz ustawić na „POST”.
jquery.unobtrusive-ajax.min.js
”. W przeciwnym razie po kliknięciu będzie nadal wykonywał GET zamiast POST. Składnia do utworzenia linku byłaby następująca:@Ajax.ActionLink("Delete", "Delete", new { id = item.Id }, new AjaxOptions {HttpMethod = "POST"})
"data-ajax"="true, "data-ajax-url"=<your link> and "data-ajax-method"="Post"
. Przy okazji, używam ASP.NET MVC 3
Możesz użyć jQuery, aby wykonać POST dla wszystkich swoich przycisków. Po prostu nadaj im tę samą nazwę CssClass.
Użyj "return false;" na końcu zdarzenia javascript onclick, jeśli chcesz wykonać po stronie serwera RedirectToAction po poście, w przeciwnym razie po prostu zwróć widok.
Razor Code
@using (Html.BeginForm())
{
@Html.HiddenFor(model => model.ID)
@Html.ActionLink("Save", "SaveAction", "MainController", null, new { @class = "saveButton", onclick = "return false;" })
}
Kod JQuery
$(document).ready(function () {
$('.saveButton').click(function () {
$(this).closest('form')[0].submit();
});
});
DO#
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult SaveAction(SaveViewModel model)
{
// Save code here...
return RedirectToAction("Index");
//return View(model);
}
@Aidos miał właściwą odpowiedź, po prostu chciał ją wyjaśnić, ponieważ jest ona ukryta w komentarzu do jego postu opublikowanego przez @CodingWithSpike.
@Ajax.ActionLink("Delete", "Delete", new { id = item.ApkModelId }, new AjaxOptions { HttpMethod = "POST" })
Oto odpowiedź wypieczona w domyślnym projekcie ASP.NET MVC 5, który, jak sądzę, ładnie realizuje moje cele dotyczące stylizacji w interfejsie użytkownika. Formularz prześlij za pomocą czystego javascript do jakiegoś formularza zawierającego.
@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>
}
W pełni pokazany przypadek użycia to menu wylogowania na pasku nawigacyjnym aplikacji internetowej.
@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>
}
ActionLink nigdy nie odpali postów. Zawsze wyzwala żądanie GET.
Użyj następującego linku Call the Action:
<%= Html.ActionLink("Click Here" , "ActionName","ContorllerName" )%>
Aby przesłać wartości formularza, użyj:
<% using (Html.BeginForm("CustomerSearchResults", "Customer"))
{ %>
<input type="text" id="Name" />
<input type="submit" class="dASButton" value="Submit" />
<% } %>
Przekaże dane do Kontrolera klienta i CustomerSearchResults Action.
Użyj tego linku wewnątrz Ajax.BeginForm
@Html.ActionLink(
"Save",
"SaveAction",
null,
null,
onclick = "$(this).parents('form').attr('action', $(this).attr('href'));$(this).parents('form').submit();return false;" })
;)
Moje rozwiązanie tego problemu jest dość proste. Mam stronę, na której klient wyszukuje jeden po całym e-mailu, a drugi po części, częściowo pobiera i wyświetla listę lista ma link do akcji, który wskazuje na wynik działania o nazwie GetByID i przekazuje identyfikator
GetByID pobiera dane dla wybranego klienta, a następnie zwraca
return View("Index", model);
która jest metodą postu
Był to dla mnie trudny problem do rozwiązania. Jak mogę zbudować łącze dynamiczne w maszynce do golenia i html, które może wywołać metodę akcji i przekazać wartość lub wartości do określonej metody akcji? Rozważyłem kilka opcji, w tym niestandardowy pomocnik HTML. Właśnie wymyśliłem proste i eleganckie rozwiązanie.
Widok
@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>
}
Metoda działania
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");
}
Chodzi o to, że Url.Action nie dba o to, czy metoda akcji to GET czy POST. Będzie mieć dostęp do dowolnego typu metody. Możesz przekazać swoje dane do metody akcji za pomocą
@Url.Action(string actionName, string controllerName, object routeValues)
obiekt routeValues. Próbowałem tego i działa. Nie, z technicznego punktu widzenia nie publikujesz postu ani nie przesyłasz formularza, ale jeśli obiekt routeValues zawiera Twoje dane, nie ma znaczenia, czy jest to post, czy get. Aby wybrać właściwą metodę, możesz użyć określonej sygnatury metody akcji.
Zrobiłem ten sam problem, używając następującego kodu:
@using (Html.BeginForm("Delete", "Admin"))
{
@Html.Hidden("ProductID", item.ProductID)
<input type="submit" value="Delete" />
}
To jest moje rozwiązanie problemu. To jest kontroler z 2 metodami akcji
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");
}
}
W widoku renderuję konstrukcję według następującej struktury.
<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>
Ciekawe miejsca w Razor View :
Funkcja JavaScript confirmDelete(id)
wywoływana po kliknięciu linku wygenerowanego za pomocą @Html.ActionLink
;
confirmDelete()
funkcja wymaga identyfikatora klikniętego elementu. Ten element jest przekazywany z onClick
modułu obsługi confirmDelete("+feedback.Id+");return false;
Zwróć uwagę, że program obsługi zwraca false, aby zapobiec domyślnej akcji - czyli żądaniu odebrania celu. OnClick
Zdarzenie dla przycisków mogłoby być dołączone z jQuery dla wszystkich przycisków na liście jako alternatywa (prawdopodobnie będzie jeszcze lepiej, ponieważ będzie mniej tekstu na stronie HTML, a dane będą mogły być przekazywane przez data-
atrybut).
Formularz ma id=myForm
, aby go znaleźć confirmDelete()
.
Form zawiera @Html.HttpMethodOverride(HttpVerbs.Delete)
, aby użyć HttpDelete
czasownika, jako czynność oznaczoną znakiem HttpDeleteAttribute
.
W funkcji JS używam potwierdzenia akcji (za pomocą zewnętrznej wtyczki, ale standardowe potwierdzenie też działa dobrze. Nie zapomnij użyć bind()
w oddzwonieniu lub var that=this
(cokolwiek wolisz).
Formularz ma ukryty element z id='idField'
i name='id'
. Więc zanim formularz zostanie przesłany po potwierdzeniu ( result==true
), wartość ukrytego elementu jest ustawiana na argument wartość przekazana, a przeglądarka prześle dane do kontrolera w następujący sposób:
URL żądania :http://localhost:38874/Feedback/Delete
Metoda żądania: Kod stanu POST: 302 znaleziony
Nagłówki odpowiedzi
Lokalizacja: / Host opinii: localhost: 38874 Dane formularza X-HTTP-Method-Override: DELETE id: 5
Jak widać, jest to żądanie POST z X-HTTP-Method-Override: DELETE i danymi w treści ustawionymi na „id: 5”. Odpowiedź zawiera kod 302, który przekierowuje do akcji Index, dzięki czemu po usunięciu odświeżasz ekran.
Poleciłbym pozostać czystym zgodnie z zasadami REST i używać usuwania HTTP do usuwania. Niestety specyfikacje HTML zawierają tylko HTTP Get & Post. Tag może tylko Get HTTP. Znacznik formularza może wykonywać polecenia HTTP Get lub Post. Na szczęście, jeśli używasz Ajax, możesz wykonać HTTP Delete i to właśnie zalecam. Szczegółowe informacje można znaleźć w następującym poście: Http Deletes
Wywołanie $ .post () nie zadziała, ponieważ jest oparte na Ajax. Dlatego do tego celu należy zastosować metodę hybrydową.
Oto rozwiązanie, które działa dla mnie.
Kroki: 1. Utwórz adres URL dla href, który wywoła metodę z adresem URL i parametrem 2. Wywołaj normalny POST za pomocą metody JavaScript
Rozwiązanie:
W .cshtml:
<a href="javascript:(function(){$.postGo( '@Url.Action("View")', { 'id': @receipt.ReceiptId } );})()">View</a>
Uwaga: metoda anonimowa powinna być opakowana w (....) () tj
(function() {
//code...
})();
postGo jest zdefiniowane jak poniżej w JavaScript. Reszta jest prosta ...
@ Url.Action ("Widok") tworzy adres URL połączenia
{'id': @ receiver.ReceiptId} tworzy parametry jako obiekt, który z kolei jest konwertowany na pola POST metodą postGo. Może to być dowolny parametr, jakiego potrzebujesz
W 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);
Referencyjne adresy URL, których użyłem do postGo
jQuery.post()
będzie działać, jeśli masz niestandardowe dane. Jeśli chcesz opublikować istniejący formularz, jest łatwiejszy w użyciu ajaxSubmit()
.
I nie musisz konfigurować tego kodu w samym ActionLink
sobie, ponieważ możesz dołączyć obsługę linku w document.ready()
zdarzeniu (co i tak jest preferowaną metodą), na przykład za pomocą $(function(){ ... })
triku jQuery.
Przeszedłem przez to wymagając POST ze strony wyszukiwania (indeksu) na stronę wyników. Nie potrzebowałem tak dużo, jak stwierdził @Vitaliy, ale wskazało mi to właściwy kierunek. Wszystko, co musiałem zrobić, to:
@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>
}
Mój kontroler miał następującą metodę podpisu:
[HttpPost]
public async Task<ActionResult> Result(string k)
Jest to pobierane z przykładowego projektu 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>
}
}