在 MVC 3.0 中重写 Html.BeginForm() 并保持不显眼的 javascript
这看起来有点愚蠢,但它仍然是我想学习的东西。
现在,在 ASP.NET MVC 3.0 中,您需要使用语法 @using (Html.BeginForm()) {
,然后使用 }
来关闭表单阻止获得新奇的“不引人注目的 javascript”,以免您想手动编写所有内容(这很好)。
由于某种原因(阅读:*OCD*
)我不喜欢这样。我真的宁愿这样做......
@Html.BeginForm()
<div class="happy-css">
</div>
@Html.EndForm()
看起来很愚蠢吗?是啊,各有各的好。我想了解它为什么会这样工作,并按照我的喜好塑造它。所以我认为我要开始挖掘的第一个地方是 MVC 3.0 源代码本身。所以我跳进 codeplex 来寻找 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 之间的关系。如果我只是输入 ..
然后像这样输入我的验证...
@Html.ValidationSummary (false)
我没有得到不引人注目的 JavaScript。但如果我使用
@using (Html.BeginForm()) {
那么我就会这样做。我什至检查了生成的标记,但我真的找不到区别。
现在事情就变得奇怪了。如果我只是输入...
@Html.BeginForm()
然后输入我的所有表单代码,表单工作并且我得到了不显眼的javascript,但是我有在末尾手动输入 。
@Html.EndForm()
不起作用。但最重要的是,我现在将文本 System.Web.Mvc.Html.MvcForm
写入
有人可以启发和/或帮助我吗?
This is going to seem like a bit of a silly endeavor, but it's something I want to learn nonetheless.
Right now, in ASP.NET MVC 3.0, you need to use the syntax @using (Html.BeginForm()) {
and then later, the }
to close a form block to get the fancy new 'unobtrusive javascript', lest you want to write all of it by hand (which is fine).
For some reason (Read: *OCD*
) I don't like that. I'd really rather do this..
@Html.BeginForm()
<div class="happy-css">
</div>
@Html.EndForm()
Seem stupid yet? Yeah, well to each their own. I want to understand why it is working how it is and mold it to my liking. So I thought the first place I would start digging is the MVC 3.0 source itself. So I jumped into codeplex to find the BeginForm
Extension method.
( http://aspnet.codeplex.com/SourceControl/changeset/view/63452#288009 )
So now I am a little confused as to how to begin achieving my goal. Reading through the code, I discovered that they all go down to a root method (not surprising, as most extension methods seem to be hierarchical methods all reaching down into a single one to avoid redundancy).
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);
}
What I am not seeing here is how this method relates to the unobtrusive javascript. If I simply type out ..
<form action="/Controller/Action" method="post">
and then put in my validation like so...
@Html.ValidationSummary(false)
I do not get the unobtrusive javascript. But if I use
@using (Html.BeginForm()) {
then I do. I've even examined the generated markup and I really can't find the difference.
Now then it gets strange. If I just type in ...
@Html.BeginForm()
and then put all of my form code, the form works and I get the unobtrusive javascript, but I have to manually type in </form>
at the end. @Html.EndForm()
doesn't work. But ontop of that, I now get the text System.Web.Mvc.Html.MvcForm
written to the output stream right beneath the <form action="/Controller/Action" method="post">
html.
Can someone enlighten and/or help me?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您的根本问题(即如何使用 BeginForm/EndForm 语法)的答案是按以下方式执行:
不幸的是,在调用写入输出的帮助程序时,现在的 Razor 语法有点冗长(与大多数情况相反)只返回 html 片段的助手)。您可以通过编写自己的扩展方法来使这变得更容易,如下所示:
The answer to your underlying question (i.e. how to use BeginForm/EndForm syntax) is to do it in the following manner:
Unfortunately the Razor syntax right now is a bit more verbose when invoking helpers that write to the output (as opposed to the majority of helpers which just return an html snippet). You could probably make this easier by writing your own extension methods like so:
我认为它起作用的原因是 BeginForm 方法返回一个 MvcForm 对象而不是 html,它将 html 直接写入页面。当 using 块结束时,它会被释放并写入结束结束标记。这就是您在输出中看到文本
System.Web.Mvc.Html.MvcForm
的原因。您必须手动将结束标记放在那里,因为 MvcForm 对象没有被释放。使用语法就像这样做:
The reason it works I believe is that the BeginForm method returns an MvcForm object and not html, it writes the html directly to the page. When the using block ends it is disposed and it writes the closing end tag. That's the reason you see the text
System.Web.Mvc.Html.MvcForm
appear in your output. You have to put the closing tag in there manually because the MvcForm object isn't disposed.The using syntax is like doing this: