0

我想通過數據註釋添加自定義數據驗證。我現在只關心服務器端驗證。我在這裏和其他地方看到的一切都引用了客戶端驗證。我已經剝離了我的所有代碼,運行了一些測試用例,並且我可以在常規視圖中正常工作,但只要表單處於部分視圖中,代碼就不會在用於覆蓋IsValid的方法中斷開。MVC3自定義服務器端數據註釋驗證不能在局部視圖中工作

無論哪種情況,我都可以看到正在初始化的自定義屬性。當表單處於常規視圖時,我可以看到提交表單時正在執行的覆蓋方法,但是在部分視圖中,代碼永遠不會被執行,而是直接轉到HttpPost操作。

我花了兩天的好時間試圖弄清楚這一點,並且無所適從。任何幫助將不勝感激。

注意: 下面的代碼在進入HttpPost操作時會返回相同的視圖。我有這樣的測試目的。我知道我的重寫永遠不會從部分視圖中調用,因此IsValid始終爲真。

查看顯示形式,其中驗證工作

@model eRecruitBoard.ViewModels.HomeIndexViewModel 
@{ 
    ViewBag.Title = "eRecruitBoard"; 
} 
@*<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script> 
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>*@ 

<h2>Login/homepage</h2> 

<br /><br /> 
<div class="errorMessage"> 
@Html.DisplayFor(m => m.LoginErrorMsg) 
</div> 
<br /> 

@using (Html.BeginForm("Index", "Home")) { 
    <div id="loginControlBox"> 
     <fieldset> 
      <legend>Welcome to eRecruitBoard</legend> 

      <div class="editor-label"> 
       @Html.LabelFor(m => m.UserName) 
      </div> 
      <div class="editor-field"> 
       @Html.TextBoxFor(m => m.UserName) 
       @Html.ValidationMessageFor(m => m.UserName) 
      </div> 

      <div class="editor-label"> 
       @Html.LabelFor(m => m.Password) 
      </div> 
      <div class="editor-field"> 
       @Html.PasswordFor(m => m.Password) 
       @Html.ValidationMessageFor(m => m.Password) 
      </div> 

      <div class="editor-label"> 
       @Html.CheckBoxFor(m => m.RememberMe) 
       @Html.LabelFor(m => m.RememberMe) 
      </div> 
      <div class="editor-label"> 
       @Html.EditorFor(m => m.Date) 
       @Html.ValidationMessageFor(m => m.Date) 
      </div> 
      <p> 
       <input type="submit" value="Log In" /> 
      </p> 
     </fieldset> 
    </div> 
} 
    <div> 
     @Html.Action("BlankForm", "TestForm") 
    </div> 

局部視圖(這些腳本調用也通過_layout進來,但我有他們在這裏進行測試以及)

@model eRecruitBoard.ViewModels.TestFormViewModel 

    <script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script> 
    <script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script> 
    <script src="@Url.Content("~/Scripts/MicrosoftAjax.js")" type="text/javascript"></script>  
    <script src="@Url.Content("~/Scripts/MicrosoftMvcAjax.js")" type="text/javascript"></script> 
    <script src="@Url.Content("~/Scripts/MicrosoftMvcValidation.js")" type="text/javascript"></script> 

@using (Html.BeginForm("NewActivity2", "TestForm", FormMethod.Post)) 
{ 
<fieldset> 
    <legend>Test Form</legend> 
    <br /> 
    @Html.LabelFor(m => m.Date) 
    @Html.EditorFor(m => m.Date) 
    @Html.ValidationMessageFor(m => m.Date) 
    <input id="activityTimelineSubmit" type="submit" value="Submit" /> 
</fieldset> 
} 

視圖模型(對局部視圖)

namespace eRecruitBoard.ViewModels 
{ 
    public class TestFormViewModel 
    { 
     [Required] 
     [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:MM/dd/yyyy}")] 
     [NonFutureDate()] 
     [Display(Name = "Date")] 
     public DateTime Date { get; set; } 
    } 
} 

控制器(局部視圖)

namespace eRecruitBoard.Controllers 
{ 
    public class TestFormController :BaseController 
    { 
     public ActionResult BlankForm() 
     { 
      var viewModel = new TestFormViewModel 
      { 
       Date = DateTime.Today 
      }; 

      return PartialView("_TestForm", viewModel); 
     } 

     [HttpPost] 
     public ActionResult NewActivity2(DateTime Date) 
     { 
      if (!ModelState.IsValid) 
       return RedirectToAction("Index", "Home"); 
      else 
       return RedirectToAction("Index", "Home"); 
     } 
    } 
} 

輸入驗證碼

using System; 
using System.ComponentModel.DataAnnotations; 

namespace eRecruitBoard.WebLibrary.Validation 
{ 
    [AttributeUsageAttribute(AttributeTargets.Class | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false, Inherited = true)] 
    public class NonFutureDateAttribute : ValidationAttribute //public sealed class 
    { 
     public NonFutureDateAttribute(): base("Activity can only be saved for today or dates in the past.") 
     { 
     } 
     public override bool IsValid(object value) 
     { 
      DateTime dateToCheck = (DateTime)value; 
      return (dateToCheck <= DateTime.Today); 
     } 
    } 
} 

回答

2

如果RedirectToAction你失去所有的驗證。您的POST操作中必須有return PartialView(model)。這需要將參數類型NewActivity2更改爲TestFormViewModel而不是DateTime

更新您的代碼,舉例說明如何顯示部分視圖(@Html.Partial()或JavaScript),如果它仍然不起作用。

+0

感謝您的留言。這工作完美。 –

相關問題