2011-11-12 53 views
5

ASP.NET MVC 2呈现链接(即<a>)删除记录。创建MVC删除按钮扩展 - 如何扩展MVC的Html助手?

通过GET操作允许删除操作可能有害,所以我想通过发布POST来删除操作。

我创建了下面的一段代码:

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

现在,我想这个代码添加到HTML辅助作为扩展方法:

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

现在,这里是我卡着了。我如何获得这个删除按钮的工作?

回答

4

如果你想生成完整的代码,你会错误地返回一个MvcForm。你想让它返回一个MvcHtmlString并在方法中构造HTML。这样,你可以使用它作为:

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

直接生成HTML(注:未经测试,可能需要适当的空检查等)

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

另一种方法是重复使用的形式助手和的Response.Write,但该方法返回一个(空)字符串,也许是这样的:

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

我编辑了最后一个答案 - 经过一些更改 - 似乎正常工作。 –

+0

如何在HtmlHelper中做一个'response.Write'非常好的见解。谢谢!!希望我可以再次投票。 –

1

虽然我认为一个<form>元素就可以了,是不是很AJAX-Y。

相反,为什么不使用jQuerywire up to the click event为适当<a>链接,然后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 
     });  
    }); 
}); 

到这样做的好处是你保持你的HTML 清洁比,如果你的每个项目插入一个<form>你想删除和语义相关的,干净的标记始终是从发展的,SEO加和其他观点。

+0

我喜欢使用某种AJAX帖子的想法。清洁HTML的论点在我的脑海中。我不知道这是否是商业应用程序的目标。自从我阅读http://www.hanselman.com/blog/JavaScriptIsAssemblyLanguageForTheWebSematicMarkupIsDeadCleanVsMachinecodedHTML.aspx后,我一直在想,商业应用程序甚至应该参与编写干净的html。 –

+0

@ KeesC.Bakker:我不会说这是一个目标,但更干净的HTML是良好开发实践的目标IMO;当面对一堵HTML的墙时,这将是一个噩梦,通过这一切来看看哪里出了问题;与jQuery(或类似的东西)你有更好的问题分离;另外,你正在使用经过测试的代码。最后,当你们都遵循相同的范式时,你会有更多的人出现在野外,而不是因为你离题而试图找出自己的利基案例。 – casperOne

+0

我赞成通过AJAX处理它,但是如果页面上出现javascript错误或javascript被关闭,这将会中断。你可以拦截表单提交处理程序,并通过AJAX做到这一点 - 甚至可以打开表单,如果需要的话,只用合适的处理程序只留下按钮。 – tvanfosson