6

这看起来有点愚蠢,但这是我想学习的东西。

现在,在 ASP.NET MVC 3.0 中,您需要使用语法@using (Html.BeginForm()) {,然后,}关闭表单块以获得花哨的新“不显眼的 javascript”,以免您想手动编写所有内容(这很好)。

出于某种原因 ( Read: *OCD*) 我不喜欢那样。我真的宁愿这样做..

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

看起来还傻吗?是的,各有各的。我想了解它为什么会这样工作,并按照我的喜好塑造它。所以我认为我要开始挖掘的第一个地方是 MVC 3.0 源代码本身。所以我跳进了codeplex来寻找BeginFormExtension方法。

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,但我必须在</form>最后手动输入。@Html.EndForm()不起作用。但最重要的是,我现在将文本System.Web.Mvc.Html.MvcForm写入<form action="/Controller/Action" method="post">html 正下方的输出流。

有人可以启发和/或帮助我吗?

4

2 回答 2

8

您的基本问题(即如何使用 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("");
}
于 2011-02-23T16:34:24.530 回答
0

我相信它起作用的原因是 BeginForm 方法返回一个 MvcForm 对象而不是 html,它将 html 直接写入页面。当 using 块结束时,它被释放并写入结束结束标记。这就是您看到文本System.Web.Mvc.Html.MvcForm出现在输出中的原因。您必须手动将结束标记放在那里,因为没有释放 MvcForm 对象。

using 语法是这样的:

@{ MvcForm mf = Html.BeginForm(); /* writes directly to html stream */ }
<div class="happy-css">
</div>
@{ mf.Dispose(); /* like calling mf.EndForm() */ }
于 2011-05-16T09:13:38.657 回答