Проблема с проверкой модели представления с помощью плавной проверки

Я пытаюсь проверить модель просмотра, используя плавную проверку. Когда я публикую объект 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);
}

person Srinivasa    schedule 17.12.2010    source источник


Ответы (1)


Я не могу помочь с Fluent Validation, но, поскольку вы отметили это как fluent-nhibernate, я подумал, что должен прокомментировать ваше использование NHibernate.

Ваша модель представления не должна использовать NHibernate в своем конструкторе; Фактически, ваша модель представления должна быть просто структурой данных, которая заполняется внешней службой. Точно так же вы можете сделать то же самое со своим контроллером; люди обычно извлекают доступ к данным в репозиторий, чтобы изолировать свои контроллеры (и упростить тестирование, вы ведь тестируете?).

Если вы используете репозиторий, вы можете спроецировать свою модель представления из своей сущности; это можно сделать либо с помощью проекций и преобразователей NHibernate, либо с помощью с помощью такого инструмента, как AutoMapper.

person James Gregory    schedule 17.12.2010