2010-12-17 16 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"); 
    } 
} 

モデルValidatorは以下の通りです:

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のようなツールを使用して行うことができます。

関連する問題