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);
}
4

1 回答 1

0

我对 Fluent Validation 无能为力,但是当您将其标记为 fluent-nhibernate 时,我想我应该评论您的 NHibernate 用法。

您的视图模型不应在其构造函数中使用 NHibernate;实际上,您的视图模型应该只是由外部服务填充的数据结构。同样,您可能希望对控制器执行相同的操作;人们将数据访问提取到存储库中以隔离他们的控制器是很常见的(并使测试更容易,您正在测试不是吗?)。

如果您使用的是存储库,则可以从您的实体中投影您的视图模型;您可以通过使用NHibernate 投影和转换器或使用AutoMapper之类的工具来做到这一点。

于 2010-12-17T10:10:05.180 回答