7

我刚刚意识到,当我在布局页面上放置一个表单标签时,围绕 RenderBody 部分,不会生成不显眼的验证。像这样的东西:

@using (Html.BeginForm())
{
    <input type="submit" value="save" />

    <div>
        @RenderBody()
    </div>
}

正如您可能已经猜到的那样,我想在我的内容上生成按钮。这是正确的不引人注目的行为吗?

顺便说一句,如果我将表单放在特定页面中,一切都会像魅力一样工作: data-val* 属性生成良好。

我会感谢你的宝贵帮助。

最好的祝福

罗德里戈

4

5 回答 5

12

你可以在你的视图中应用一个怪诞的 hack:

@{
    var originalContext = ViewContext.FormContext;
    ViewContext.FormContext = new FormContext();
}

<!-- This will generate proper HTML5 data-* validation attributes -->
@Html.TextBoxFor(x => x.Prop1)
@Html.ValidationMessageFor(x => x.Prop1)

@Html.TextBoxFor(x => x.Prop2)
@Html.ValidationMessageFor(x => x.Prop2)

@{
    ViewContext.FormContext = originalContext;
}
于 2011-02-14T22:17:04.337 回答
4

虽然放入@using (Html.BeginForm())内容页面可以解决验证问题,但它还会将一组额外的<form>标签放入输出中。我创建了一个小扩展来解决问题,而无需向输出写入任何内容。

用它作为@using (Html.BeginSubForm())

public static class FormExtensions
{
    public static MvcSubForm BeginSubForm(this HtmlHelper html)
    {
        return new MvcSubForm(html.ViewContext);
    }
}


public sealed class MvcSubForm : IDisposable
{
    private readonly ViewContext _viewContext;
    private readonly FormContext _originalFormContext;

    public MvcSubForm(ViewContext viewContext)
    {
        _viewContext = viewContext;
        _originalFormContext = viewContext.FormContext;

        viewContext.FormContext = new FormContext();
    }


    public void Dispose()
    {
        if (_viewContext != null)
        {
            _viewContext.FormContext = _originalFormContext;
        }
    }
}
于 2012-01-05T21:36:26.927 回答
1

感谢您的帮助,我试过了,但我找到了一个不像您建议的那样“怪诞”(如您所说)的解决方案:D

我只是在我的页面中放置了一个 BeginForm 方法,并在布局上放置了一个 BeginForm 方法:

@* On the layout page *@
@using (Html.BeginForm())
{
    <input type="submit" value="save" />

    <div>
        @RenderBody()
    </div>
}


@* On the content page *@
@using(Html.BeginForm())
{
  @* Content *@
}

所以,最后我有两个 BeginForm 方法: ASP.NET MVC 引擎正在使用位于布局页面上的一个,因此 data-val* 属性被正确呈现,并且表单被放置在我想要的位置,因此任何提交按钮在布局上可以提交我的特定页面并呈现验证

它工作得很好

非常感谢

问候, 罗德里戈

于 2011-02-15T14:17:35.497 回答
1

我刚刚遇到了同样的问题,但可能是基于Darin Dimitrov 的回答的更好的解决方案。

诀窍是创建一个页面基类型,基于WebViewPage<T>类,视图的默认基类并在FormContext那里进行交换。

abstract public class FormFixWebViewPage : FormFixWebViewPage<object>
{
}

abstract public class FormFixWebViewPage<T> : WebViewPage<T>
{
    override public void Write(System.Web.WebPages.HelperResult result)
    {
        var originalFormContext = ViewContext.FormContext;
        ViewContext.FormContext = new FormContext();

        base.Write(result);

        ViewContext.FormContext = originalFormContext;
    }
}

然后在Web.config文件夹下的~/Views/文件中,修改elementpageBaseType下的属性pages,可以在以下system.web.webPages.razor部分找到:

<system.web.webPages.razor>
    <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
    <pages pageBaseType="<YOUR-NAMESPACE>.FormFixWebViewPage">
    <!--pages pageBaseType="System.Web.Mvc.WebViewPage"-->
        <namespaces>
            <add namespace="System.Web.Mvc" />
            <add namespace="System.Web.Mvc.Ajax" />
            <add namespace="System.Web.Mvc.Html" />
            <add namespace="System.Web.Helpers" />
            <add namespace="System.Web.Routing" />
        </namespaces>
    </pages>
</system.web.webPages.razor>
于 2011-05-11T08:28:17.323 回答
1

只需在子视图文件顶部添加以下代码...

@{
   Layout = "~/Views/Shared/_Layout.cshtml";
   this.ViewContext.FormContext = new FormContext();
}

它对我来说很好。

我希望这能帮到您....

于 2012-05-24T06:37:45.553 回答