2011-11-12 69 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