Создание расширения кнопки удаления MVC - Как расширить Hcml помощник MVC? - PullRequest
5 голосов
/ 12 ноября 2011

ASP.NET MVC 2 отображает ссылку (например, <a>) для удаления записей.

Может быть вредно разрешать удалять действия через действия 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;
}

Теперь вот где я застрял.Как заставить эту кнопку удаления работать?

Ответы [ 2 ]

4 голосов
/ 12 ноября 2011

Если вы хотите сгенерировать полный код, вы ошибаетесь, если он возвращает 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("");
}
1 голос
/ 12 ноября 2011

Хотя я думаю, что элемент <form> сработает, он не очень AJAX-y.

Скорее, почему бы не использовать jQuery , подключиться к событию клика для соответствующих <a> ссылок, а затем самостоятельно выдать HTTP POST серверу

$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 и другие перспективы.

...