2010-12-17 104 views
1

我想驗證使用流暢驗證的視圖模型。當我發佈viewmodel對象時,modelstate.isvalid總是返回false。當我檢查了發佈對象上的值時,用於獲取要在下拉菜單中顯示的數據的屬性也正在驗證中。如何解決這個問題。我是否以錯誤的方式做,請幫助。 我是ASP.net MVC的新手,只是嘗試在這個項目中使用流暢的驗證和流暢的NHibernate映射。使用流暢驗證驗證視圖模型的問題

更多細節如下:

我有如下域模型對象:

[Validator(typeof(TestRequirementValidator))] 
public class TestRequirement 
{ 
    public virtual int Id { get; private set; } 
    public virtual int SampleId { get; set; } 
    public virtual int TestId { get; set; } 
    public virtual int StandardId { get; set; }  
    public virtual string Description { get; set; } 
    public virtual Sample Sample { get; set; } 
    public virtual Test Test { get; set; } 
    public virtual Standard Standard { get; set; } 
} 

我已經創建如下面的圖模型:

[Validator(typeof(TestRequirementViewModelValidator))] 
public class TestRequirementViewModel 
{ 
    public TestRequirement TestRequirement; 
    public SelectList Samples; 
    public SelectList Tests; 
    public SelectList Standards; 

    public TestRequirementViewModel() 
    { 
    ISession _session = FNHsessionFactory.GetSessionFactory(); 
    this.TestRequirement = new TestRequirement(); 
    this.Samples = new SelectList(from S in _session.Linq<Sample>() select S, "Id", "Name"); 
    this.Tests = new SelectList(from T in _session.Linq<Test>() select T, "Id", "Name"); 
    this.Standards = new SelectList(from St in _session.Linq<Standard>() select St, "Id", "Name"); 
    } 
} 

模型驗證器是如下:

public class TestRequirementValidator : AbstractValidator<TestRequirement> 
{ 
    public TestRequirementValidator() 
    {  
    RuleFor(x => x.SampleId) 
    .NotEmpty() 
    .WithMessage("This field is required") 
    .DisplayName("Sample Name"); 

    RuleFor(x => x.TestId) 
     .DisplayName("Test Name"); 

    RuleFor(x => x.StandardId) 
     .NotEmpty() 
     .WithMessage("This field is required") 
     .DisplayName("Standard Name"); 

    RuleFor(x => x.Description) 
     .NotEmpty() 
     .WithMessage("This field is required")     
     .Length(0, 10) 
     .WithMessage("Length of this field cannot be more than 10 characters"); 
    } 
} 

視圖模型驗證程序如下:

public class TestRequirementViewModelValidator:AbstractValidator-TestRequirementViewModel- 
{ 
    public TestRequirementViewModelValidator() 
    {    
    RuleFor(x => x.TestRequirement) 
     .SetValidator(new TestRequirementValidator()); 
    } 
} 

示意圖如下:

<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<foo.Models.ViewModels.TestRequirementViewModel>" MasterPageFile="~/Views/shared/site.master" %> 
<asp:Content ContentPlaceHolderID="MainContent" ID="MainContentContent" runat="server"> 
    <h3><%= Html.Encode(ViewData["Message"]) %></h3> 

    <% using (Html.BeginForm()) {%> 
    <%= Html.ValidationSummary(true) %> 
    <fieldset> 
     <legend>Create Test Requirement</legend> 

     <div class="editor-label"> 
     <%= Html.LabelFor(model => model.TestRequirement.SampleId) %> 
     </div> 

     <div class="editor-field"> 
     <%= Html.DropDownListFor(model => model.TestRequirement.SampleId, new SelectList(Model.Samples.Items, Model.Samples.DataValueField, Model.Samples.DataTextField), "Select Sample") %> 
     <%= Html.ValidationMessageFor(model => model.TestRequirement.SampleId) %> 
     </div> 

     <div class="editor-label"> 
     <%= Html.LabelFor(model => model.TestRequirement.TestId) %> 
     </div> 

     <div class="editor-field"> 
     <%= Html.DropDownListFor(model => model.TestRequirement.TestId, new SelectList(Model.Tests.Items, Model.Tests.DataValueField, Model.Tests.DataTextField), "Select Test") %> 
     <%= Html.ValidationMessageFor(model => model.TestRequirement.TestId) %> 
     </div> 

     <div class="editor-label"> 
     <%= Html.LabelFor(model => model.TestRequirement.StandardId) %> 
     </div> 

     <div class="editor-field"> 
     <%= Html.DropDownListFor(model => model.TestRequirement.StandardId, new SelectList(Model.Standards.Items, Model.Standards.DataValueField, Model.Standards.DataTextField), "Select Standard") %> 
     <%= Html.ValidationMessageFor(model => model.TestRequirement.StandardId) %> 
     </div> 

     <div class="editor-label"> 
     <%= Html.LabelFor(model => model.TestRequirement.Description) %> 
     </div> 

     <div class="editor-field"> 
     <%= Html.TextBoxFor(model => model.TestRequirement.Description) %> 
     <%= Html.ValidationMessageFor(model => model.TestRequirement.Description) %> 
     </div> 

     <p> 
     <input type="submit" value="Create" /> 
     </p> 
    </fieldset> 
    <% } %> 

    <%= Html.ClientSideValidation<TestRequirement>("TestRequirement") %> 
</asp:Content> 

控制器是如下:

public ActionResult TestRequirement() 
{ 
    TestRequirementViewModel NewTestRequirement = new TestRequirementViewModel(); 
    return View(NewTestRequirement); 
} 

[HttpPost] 
public ActionResult TestRequirement(TestRequirementViewModel NewTestRequirement) 
{ 
    if(ModelState.IsValid) 
    { 
    ISession _session = FNHsessionFactory.GetSessionFactory();  
    _session.SaveOrUpdate(NewTestRequirement.TestRequirement);  

    ViewData["Message"] = "New Test Requirement has been created successfully"; 

    return View(); 
    } 

    return View(NewTestRequirement); 
} 

回答

0

我不能流利驗證幫助,但作爲你已經標記爲流利nhibernate我想我應該評論你的NHibernate的用法。

您的視圖模型不應該在其構造函數中使用NHibernate;實際上,您的視圖模型應該只是一個由外部服務填充的數據結構。同樣,你可能想對你的控制器做同樣的事情;人們通常會將數據訪問提取到一個repository以隔離其控制器(並且使測試更容易,您正在測試的不是您?)。

如果您使用存儲庫,則可以從您的實體投影您的視圖模型;您可以通過使用NHibernate projections and transformers或使用類似AutoMapper的工具來完成此操作。