asp.net-mvc - page - html.actionlink image
ASP.NET MVC ActionLink y método de publicación (17)
¿Alguien puede decirme cómo puedo enviar valores al controlador usando el método ActionLink y POST?
No quiero usar botones
Supongo que tiene algo con jquery.
@Aidos tenía la respuesta correcta, solo quería dejarlo en claro, ya que está oculto dentro de un comentario en su publicación hecha por @CodingWithSpike.
@Ajax.ActionLink("Delete", "Delete", new { id = item.ApkModelId }, new AjaxOptions { HttpMethod = "POST" })
ActionLink nunca disparará la publicación. Siempre activa la solicitud GET.
Aquí hay una respuesta cocida en el proyecto predeterminado de ASP.NET MVC 5, creo que cumple mis objetivos de diseño muy bien en la interfaz de usuario. Formulario enviar utilizando javascript puro a algún formulario que contenga.
@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>
}
El caso de uso completamente mostrado es un menú desplegable de cierre de sesión en la barra de navegación de una aplicación 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>
}
Encontré esta necesidad de POSTAR desde una página de búsqueda (índice) a la página de resultados. No necesitaba tanto como @Vitaliy declaró, pero me indicó la dirección correcta. Todo lo que tenía que hacer era esto:
@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>
}
Mi controlador tenía el siguiente método de firma:
[HttpPost]
public async Task<ActionResult> Result(string k)
Esta es mi solución para el problema. Este es un controlador con 2 métodos de acción
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");
}
}
En Vista, renderizo constructo siguiente estructura.
<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>
Punto de interés en Razor View :
La función de JavaScript
confirmDelete(id)
que se llama cuando se hace clic en el enlace generado con@Html.ActionLink
;confirmDelete()
funciónconfirmDelete()
requiere la identificación del elemento al que se hace clic. Este elemento se pasa desde el controladoronClick
confirmDelete("+feedback.Id+");return false;
El controlador de atención de pago devuelve falso para evitar acciones predeterminadas, que es la solicitud de obtención de destino.OnClick
eventoOnClick
para botones podría adjuntarse con jQuery para todos los botones de la lista como alternativa (probablemente sea aún mejor, ya que habrá menos texto en la página HTML y los datos podrían pasarse a través dedata-
atributos).El formulario tiene
id=myForm
, para encontrarlo enconfirmDelete()
.El formulario incluye
@Html.HttpMethodOverride(HttpVerbs.Delete)
para usar el verboHttpDelete
, como acción marcada conHttpDeleteAttribute
.En la función JS utilizo la confirmación de acción (con la ayuda de un complemento externo, pero la confirmación estándar también funciona bien. No olvide utilizar
bind()
en callback ovar that=this
(lo que prefiera).La forma tiene un elemento oculto con
id=''idField''
yname=''id''
. Entonces, antes de enviar el formulario después de la confirmación (result==true
), el valor del elemento oculto se establece en el argumento valor pasado y el navegador enviará los datos al controlador de la siguiente manera:
URL de solicitud : http://localhost:38874/Feedback/Delete
Método de solicitud : Código de estado POST: 302 Encontrado
Encabezados de respuesta
Ubicación: / Feedback Host: localhost: 38874 Datos del formulario X-HTTP-Method-Override: DELETE id: 5
Como puede ver, es una solicitud POST con X-HTTP-Method-Override: DELETE y los datos en el cuerpo están configurados en "id: 5". Response tiene un código 302 que redirige a la acción Index, con esto refrescas tu pantalla después de eliminarla.
Este ha sido un problema difícil de resolver. ¿Cómo puedo crear un enlace dinámico en razor y html que pueda llamar a un método de acción y pasar un valor o valores a un método de acción específico? Consideré varias opciones, incluido un helper html personalizado. Solo se me ocurrió una solución simple y elegante.
La vista
@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>
}
El método de acción
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");
}
El punto aquí es que a Url.Action no le importa si el método de acción es un GET o un POST. Accederá a cualquier tipo de método. Puede pasar sus datos al método de acción usando
@Url.Action(string actionName, string controllerName, object routeValues)
el objeto routeValues. Lo intenté y funciona. No, técnicamente no está haciendo una publicación o enviando el formulario, pero si el objeto routeValues contiene sus datos, no importa si es una publicación o un get. Puede usar una firma de método de acción particular para seleccionar el método correcto.
He hecho el mismo problema usando el siguiente código:
@using (Html.BeginForm("Delete", "Admin"))
{
@Html.Hidden("ProductID", item.ProductID)
<input type="submit" value="Delete" />
}
Llamar $ .post () no funcionará ya que está basado en Ajax. Entonces un método híbrido necesita ser usado para este propósito.
A continuación está la solución que funciona para mí.
Pasos: 1. Crea una URL para href que llama al método a con url y el parámetro 2. Llama al POST normal usando el método de JavaScript
Solución:
En .cshtml:
<a href="javascript:(function(){$.postGo( ''@Url.Action("View")'', { ''id'': @receipt.ReceiptId } );})()">View</a>
Nota: el método anónimo debe estar envuelto en (....) () es decir,
(function() {
//code...
})();
postGo se define a continuación en JavaScript. El descanso es simple ...
@ Url.Action ("Ver") crea url para la llamada
{''id'': @ receipt.ReceiptId} crea parámetros como un objeto que a su vez se convierte en campos POST en el método postGo. Este puede ser cualquier parámetro que requiera
En 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 de referencia que he usado para publicar
Mi solución a este problema es bastante simple. Tengo una página que realiza una búsqueda de clientes una por todo el correo electrónico y la otra por parcial, las tiradas parciales y muestra una lista; la lista tiene un enlace de acción que apunta a un resultado de acción llamado GetByID y pasa en la identificación
el GetByID extrae los datos para el cliente seleccionado y luego regresa
return View("Index", model);
cual es el metodo de publicacion
Para realizar una POST, debe enviar los datos del formulario. No creo que sea posible hacerlo con un ActionLink. Mira este enlace .
Puede usar jQuery para hacer una POST para todos sus botones. Solo dales el mismo nombre de CssClass.
Use "return false;" al final de su evento onclick javascript si desea hacer un lado del servidor RedirectToAction después de la publicación; de lo contrario, simplemente devuelva la vista.
Código Razor
@using (Html.BeginForm())
{
@Html.HiddenFor(model => model.ID)
@Html.ActionLink("Save", "SaveAction", "MainController", null, new { @class = "saveButton", onclick = "return false;" })
}
Código 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);
}
Si está utilizando ASP MVC3, podría usar un Ajax.ActionLink (), que le permite especificar un Método HTTP que podría establecer en "POST".
Use este enlace dentro de Ajax.BeginForm
@Html.ActionLink(
"Save",
"SaveAction",
null,
null,
onclick = "$(this).parents(''form'').attr(''action'', $(this).attr(''href''));$(this).parents(''form'').submit();return false;" })
;)
Use lo siguiente el enlace Llamar a la acción:
<%= Html.ActionLink("Click Here" , "ActionName","ContorllerName" )%>
Para enviar los valores del formulario, use:
<% using (Html.BeginForm("CustomerSearchResults", "Customer"))
{ %>
<input type="text" id="Name" />
<input type="submit" class="dASButton" value="Submit" />
<% } %>
Enviará los datos al controlador del cliente y a la acción de resultados de investigación del cliente.
Yo recomendaría mantenerme puro con los principios REST y usar una eliminación HTTP para sus eliminaciones. Lamentablemente, HTML Specs solo tiene HTTP Get & Post. Una etiqueta solo puede obtener HTTP. Una etiqueta de formulario puede hacer un HTTP Get o Post. Afortunadamente, si usas ajax puedes hacer una eliminación HTTP y esto es lo que recomiendo. Consulte la siguiente publicación para más detalles: Http Deletes
jQuery.post()
funcionará si tiene datos personalizados. Si desea publicar un formulario existente, es más fácil usar ajaxSubmit()
.
Y no tiene que configurar este código en ActionLink
, ya que puede adjuntar el controlador de enlace en el evento document.ready()
(que de todos modos es un método preferido), por ejemplo, usando $(function(){ ... })
truco de jQuery.
No puede usar un ActionLink
porque eso simplemente genera una etiqueta de anclaje <a>
.
Puedes usar una publicación jQuery AJAX .
O simplemente llame al método de envío del formulario con o sin jQuery (que no sería AJAX), quizás en el evento onclick
de cualquier control que le apetezca.