Переписать Html.BeginForm () в MVC 3.0 и оставить ненавязчивый JavaScript - PullRequest
6 голосов
/ 23 февраля 2011

Это будет немного глупо, но, тем не менее, я хочу научиться этому.

Прямо сейчас, в ASP.NET MVC 3.0 вам нужно использовать синтаксис @using (Html.BeginForm()) {, а затем, }, чтобы закрыть блок формы, чтобы получить новый причудливый «ненавязчивый JavaScript», чтобы вы нехочу написать все это от руки (это нормально).

По какой-то причине (Read: *OCD*) мне это не нравится.Я действительно предпочел бы сделать это ..

@Html.BeginForm()
<div class="happy-css">
</div>
@Html.EndForm()

Кажется глупым еще?Ага, ну каждому свое.Я хочу понять, почему он работает так, как есть, и сформировать его по своему вкусу.Поэтому я подумал, что первым делом я начну копать, это сам источник MVC 3.0.Поэтому я запрыгнул в кодовый комплекс, чтобы найти метод расширения BeginForm.

(http://aspnet.codeplex.com/SourceControl/changeset/view/63452#288009)

Так что теперь я немного озадачен тем, как начать достигать своей цели.Прочитав код, я обнаружил, что все они переходят к корневому методу (что неудивительно, поскольку большинство методов расширения представляются иерархическими методами, которые сводятся к одному, чтобы избежать избыточности).

private static MvcForm FormHelper(this HtmlHelper htmlHelper, string formAction, FormMethod method, IDictionary<string, object> htmlAttributes) {
            TagBuilder tagBuilder = new TagBuilder("form");
            tagBuilder.MergeAttributes(htmlAttributes);
            // action is implicitly generated, so htmlAttributes take precedence.
            tagBuilder.MergeAttribute("action", formAction);
            // method is an explicit parameter, so it takes precedence over the htmlAttributes.
            tagBuilder.MergeAttribute("method", HtmlHelper.GetFormMethodString(method), true);

            HttpResponseBase httpResponse = htmlHelper.ViewContext.HttpContext.Response;
            httpResponse.Write(tagBuilder.ToString(TagRenderMode.StartTag));
            return new MvcForm(htmlHelper.ViewContext.HttpContext.Response);
        }

Чего я здесь не вижу, так это того, как этот метод относится к ненавязчивому javascript.Если я просто наберу ..

<form action="/Controller/Action" method="post">

, а затем добавлю свою проверку следующим образом ...

@Html.ValidationSummary(false)

Я делаюне получить ненавязчивый JavaScript.Но если я использую

@using (Html.BeginForm()) {, тогда я использую.Я даже изучил сгенерированную разметку, и я действительно не могу найти разницу.

Теперь тогда это становится странным.Если я просто наберу ...

@Html.BeginForm(), а затем вставлю весь код формы, форма будет работать , и я получу ненавязчивый JavaScript, но мне придется ввести * вручную1041 * в конце.@Html.EndForm() не работает.Но помимо этого, теперь я получаю текст System.Web.Mvc.Html.MvcForm, записанный в выходной поток прямо под <form action="/Controller/Action" method="post"> html.

Может ли кто-нибудь просветить и / или помочь мне?

Ответы [ 2 ]

8 голосов
/ 23 февраля 2011

Ответ на основной вопрос (т. Е. Как использовать синтаксис BeginForm / EndForm) состоит в том, чтобы сделать это следующим образом:

@{ Html.BeginForm(...); }
<div> content</div>
@{ Html.EndForm(); }

К сожалению, синтаксис Razor сейчас немного более многословен при вызовехелперы, которые пишут в вывод (в отличие от большинства хелперов, которые просто возвращают HTML-фрагмент).Возможно, вы могли бы упростить это, написав свои собственные методы расширения, например:

public static IHtmlString FormBegin(this HtmlHelper helper, ...) {
    helper.BeginForm(...);
    return new HtmlString("");
}

public static IHtmlString FormEnd(this HtmlHelper helper) {
    helper.EndForm();
    return new HtmlString("");
}
0 голосов
/ 16 мая 2011

Причина, по которой это работает, я считаю, что метод BeginForm возвращает объект MvcForm, а не html, он записывает html непосредственно на страницу.Когда блок using заканчивается, он удаляется и записывает закрывающий тег end.Вот почему вы видите, что текст System.Web.Mvc.Html.MvcForm появляется в вашем выводе.Вы должны поместить туда закрывающий тег вручную, потому что объект MvcForm не расположен.

Синтаксис использования похож на это:

@{ MvcForm mf = Html.BeginForm(); /* writes directly to html stream */ }
<div class="happy-css">
</div>
@{ mf.Dispose(); /* like calling mf.EndForm() */ }
...