1

流暢な検証を使用してビューモデルを検証しようとしています。ビューモデル オブジェクトを投稿すると、modelstate.isvalid は常に false を返します。投稿されたオブジェクトの値を確認すると、ドロップダウンに表示されるデータを取得するために使用されたプロパティも検証されています。これを解決する方法。私は間違った方法でそれをやっていますか、plsは助けてください。私は 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);
}
4

1 に答える 1

0

Fluent Validation についてはお手伝いできませんが、これを fluent-nhibernate としてタグ付けしたので、NHibernate の使用についてコメントする必要があると思いました。

ビュー モデルのコンストラクターで NHibernate を使用しないでください。実際、ビュー モデルは、外部サービスによって取り込まれる単なるデータ構造であるべきです。同様に、コントローラーで同じことをしたいかもしれません。コントローラーを分離するために、データ アクセスをリポジトリに抽出することはよくあることです (そして、テストを簡単にするために、テストをしているのですよね?)。

リポジトリを使用している場合は、エンティティからビュー モデルを投影できます。これは、 NHibernate プロジェクションとトランスフォーマーを使用するか、 AutoMapperなどのツールを使用して行うことができます。

于 2010-12-17T10:10:05.180 に答える