2010-12-17 75 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的工具来完成此操作。