2011-11-12 6 views
5

ASP.NET MVC 2 representa un enlace (es decir, <a>) para eliminar registros.Creación de la extensión de botón MVC Delete - ¿Cómo extender el helper Html de MVC?

Puede ser perjudicial permitir acciones de eliminación a través de acciones GET, por lo que quiero hacer la eliminación mediante la publicación de una POST.

He creado el siguiente fragmento de código:

<% using (Html.BeginForm("Delete", "Boodschap", new { id = item.BoodschapID })) 
    { %> 
    <button>Delete</button> 
<% } %> 

Ahora me gustaría añadir este código a la asistente de HTML como un método de extensión:

public static MvcForm DeleteButton(this HtmlHelper helper, string name, 
    string actionName, string controllerName, string routeValues) 
{ 
    MvcForm form = helper.BeginForm(actionName, controllerName, routeValues); 
    return form; 
} 

Ahora aquí es donde me quedó atascado. ¿Cómo consigo que este botón de eliminación funcione?

Respuesta

4

Si desea generar el código completo, lo va a hacer incorrectamente para que devuelva un MvcForm. Desea que devuelva un MvcHtmlString y construya el HTML dentro del método. De esa manera usted puede utilizarlo como:

@Html.DeleteButton("Delete", "Boodschap", new { id = item.BoodschapID }); 

Generar el código HTML directamente (nota: no probado, puede ser necesario cheques nulos adecuados, etc.)

public static MvcHtmlString DeleteButton(this HtmlHelper helper, string name, 
    string actionName, object htmlAttributes) 
{ 
    return DeleteButton(helper, name, actionName, null, null, htmlAttributes); 
} 

public static MvcHtmlString DeleteButton(this HtmlHelper helper, string name, 
    string actionName, string controllerName, object routeValues, 
    object htmlAttributes) 
{ 
    var buttonBuilder = new TagBuilder("button"); 
    buttonBuilder.SetInnerText(name); 

    var formBuilder = new TagBuilder("form"); 
    var urlHelper = new UrlHelper(helper.ViewContext.RequestContext); 
    formBuilder.Attributes.Add("action", urlHelper.Action( 
     actionName, controllerName, routeValues)) 
    formBuilder.Attributes.Add("method", FormMethod.Post); 
    formBuilder.MergeAttributes(new RouteValueDictionary(htmlAttributes)); 
    formBuilder.InnerHtml = buttonBuilder.ToString(); 

    return new MvcHtmlString(formBuilder.ToString()); 
} 

Una alternativa sería la de volver a utilizar los helpers de formularios y Response.Write, pero tienen el método devolverá una cadena (vacío), tal vez algo como:

public static MvcHtmlString DeleteButton(this HtmlHelper helper, string name, string actionName, object routeValues) 
{ 
    return DeleteButton(helper, name, actionName, null, routeValues, null); 
} 

public static MvcHtmlString DeleteButton(this HtmlHelper helper, string name, string actionName, string controllerName, object routeValues, object htmlAttributes) 
{ 
    using (helper.BeginForm(actionName, controllerName, routeValues, FormMethod.Post, htmlAttributes)) 
    { 
     var response = helper.ViewContext.HttpContext.Response; 
     var builder = new TagBuilder("button"); 
     builder.SetInnerText(name); 
     response.Write(builder.ToString(TagRenderMode.Normal)); 
    } 
    return MvcHtmlString.Create(""); 
} 
+0

He editado la última respuesta que, después de algunos cambios, parece funcionar correctamente. –

+0

Muy buena idea de cómo hacer una 'response.Write' en el HtmlHelper. ¡¡Gracias!! Ojalá pudiera votarlo de nuevo. –

1

aunque creo que un elemento <form> hará el truco, no es muy AJAX-y.

Más bien, ¿por qué no usar jQuery, wire up to the click event para los enlaces apropiados <a>, y luego issue an HTTP POST to the server yourself?

$document.ready(function() { 
    // "deleteLink is a class that identifies links that 
    // are used for deleting, you might have some other mechanism 
    $("a .deleteLink").click(function() { 
     $.post('post url', function(data) { 
      // Do something with the data returned 
     });  
    }); 
}); 

La ventaja de esto es que mantienen su HTML mucho más limpio que si ha insertado una <form> para cada artículo que quería eliminar y semánticamente relevantes, marcado limpia siempre es un punto a favor de un desarrollo, SEO y otras perspectivas

+0

Me gusta la idea de usar algún tipo de publicación de Ajax. El argumento del HTML más limpio se queda en mi cabeza. No sé si ese es el objetivo de una aplicación comercial. Desde que leí http://www.hanselman.com/blog/JavaScriptIsAssemblyLanguageForTheWebSematicMarkupIsDeadCleanVsMachinecodedHTML.aspx, me he estado preguntando si las aplicaciones comerciales deberían incluso asistir para escribir html limpio. –

+0

@ KeesC.Bakker: No diría que es un objetivo, pero HTML más limpio es un objetivo de buenas prácticas de desarrollo IMO; cuando te enfrentas a una pared de HTML, va a ser una pesadilla pasar por todo para ver dónde algo salió mal; con jQuery (o algo similar) tienes una mejor separación de preocupaciones; Además, estás usando un código probado en batalla. Finalmente, tendrás más personas en libertad que pueden ayudar cuando todos sigan el mismo paradigma en lugar de tratar de resolver el caso del nicho por ti mismo. – casperOne

+0

Estoy a favor de manejarlo a través de AJAX, pero esto se romperá si hay un error de javascript en la página o javascript está desactivado. Puede interceptar el formulario enviado con el controlador y hacerlo a través de AJAX, o incluso desenvolver los formularios, dejando solo los botones con un controlador adecuado si es necesario. – tvanfosson

Cuestiones relacionadas