2011-02-14 82 views
7

我剛剛意識到當我在我的佈局頁面上放置一個表單標記時,圍繞着RenderBody部分,不會產生不顯眼的驗證。類似這樣的:ASP.NET MVC 3:當BeginForm在佈局上時生成不顯眼的驗證

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

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

正如你可能已經猜到我想要生成我的內容上的按鈕。這是否是正確的不引人注目的行爲?

順便說一句,如果我把表單放在一個特定的頁面中,一切就像一個魅力:data-val *屬性很好地生成。

我會感謝您的寶貴幫助。

問候

羅德里戈

回答

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引擎是使用一個位於頁面佈局上,所以數據-VAL *屬性是否被正確渲染和在這裏我想這樣任何提交的佈局按鈕可以提交我的特定頁面呈現

的驗證它工作得很好形式剛放置

非常感謝

問候, 羅德里戈

+0

如果這會在頁面中添加額外的`

`標記(如@AidanBoyle所述),則可能會破壞頁面功能。 [表單不應該按照HTML標準嵌套](http://www.w3.org/TR/2011/WD-html5-20110525/forms.html#the-form-element)。 – 2012-04-11 19:27:01

12

你可以申請一個怪誕破解您的視圖中:

@{ 
    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; 
} 
+2

這救了我相當多的工作中,這是非常愚蠢的框架不能處理這個開始。我的意思是從ajax構建動態表單元素是一種非常常見的做法,如果您可以通過「模擬」新的表單上下文來獲取編輯器模板,那麼他們沒有理由不能在頂部執行此操作處理編輯器模板的函數。 – 2011-08-19 15:55:25

+0

我在生成模板標籤內的輸入時遇到了類似的問題。必須應用相同的hack才能使不顯眼的驗證屬性生成。 – 2015-12-14 17:55:43

1

我剛剛遇到同樣的問題,但可能更好的解決方案基於Darin Dimitrov's答案。

訣竅是基於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; 
    } 
} 

然後在~/Views/文件夾下的Web.config文件,改變下pages元素,它可以在system.web.webPages.razor部分中找到的pageBaseType屬性:

<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> 
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; 
     } 
    } 
} 
1

就在子視圖文件的頂部添加下面的代碼...

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

它爲我工作的罰款。

我希望這將幫助你....

相關問題