Проблема с проверкой модели представления с использованием беглой проверки - PullRequest
1 голос
/ 17 декабря 2010

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

1 Ответ

0 голосов
/ 17 декабря 2010

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

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

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

...