首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >用Fluent验证低调地验证复杂视图模型- MVC3

用Fluent验证低调地验证复杂视图模型- MVC3
EN

Stack Overflow用户
提问于 2014-02-03 16:33:21
回答 2查看 2.7K关注 0票数 1

我正在试图弄清楚为什么我的FluentValidation不是不引人注目地验证我的一些视图模型属性。

我通过NuGet安装了MVC3的FluentValidation包:

代码语言:javascript
复制
  Install-Package FluentValidation.MVC3

结果:

代码语言:javascript
复制
<package id="FluentValidation" version="5.0.0.1" targetFramework="net45" />
<package id="FluentValidation.MVC3" version="5.0.0.1" targetFramework="net45" />

未被验证的属性是Guitar类对象的一些成员,它们在model模型中声明。Guitar.ProductionYear属性得到的是不引人注目的验证代码,而Guitar对象的其他2个属性则不是。

代码语言:javascript
复制
public Guitar Guitar1 { get; set; }
public Guitar Guitar2 { get; set; }
public Guitar Guitar3 { get; set; }

我读过FluentValidation文档,尤其是关于流验证的客户端列表验证的限制的文档,但这不是一个列表,所以我希望有人能够看到问题所在和/或提供一些建议。

我也尝试使用自定义的Guitar对象验证器,但仍然得到了相同的结果。

观测

  • 正在生成客户端验证并触发属性FirstName、LasteName、电话和电子邮件。

  • 我确实注意到,当用户没有填写这些对象时,ModelState对这些对象无效,但我不知道为什么客户端验证没有生成并随后触发。

  • 为Guitar对象生成的表单HTML缺少未突出的验证属性。其他属性如FirstName、LastName、电子邮件和电话都很好。

示例

代码语言:javascript
复制
    <!-- Unobtrusive JS generated-->
        <input type="text" value="" name="FirstName" id="FirstName" data-val-required="'First Name' must not be empty." data-val="true" class="input-validation-error">
        <div class="messageBottom"> 
                <span data-valmsg-replace="true" data-valmsg-for="FirstName" class="field-validation-error"><span for="FirstName" generated="true" class="">'First Name' must not be empty.</span>
   </span>
 </div>

    <!-- Unobtrusive JS Partially generated for Guitar object-->
   <input type="text" value="" name="Guitar.Make" id="Guitar_Make" placeholder="Make">
        <div class="messageBottom">
        <span data-valmsg-replace="true" data-valmsg-for="Guitar1.Make" class="field-validation-valid"></span>
        </div>

        <input type="text" value="" name="Guitar1.Model" id="Guitar1_Model" placeholder="Model">
        <div class="messageBottom">
            <span data-valmsg-replace="true" data-valmsg-for="Guitar1.Model" class="field-validation-valid"></span>
        </div>

        <input type="text" value="" name="Guitar1.ProductionYear" id="Guitar1_ProductionYear" data-val-number="The field ProductionYear must be a number." data-val="true" placeholder="Production Year" class="valid">
        <div class="messageBottom">
        <span data-valmsg-replace="true" data-valmsg-for="Guitar1.ProductionYear" class="field-validation-valid">
        </span>
        </div>

谢谢

Global.asax.cs

代码语言:javascript
复制
FluentValidationModelValidatorProvider.Configure();

视图模型

代码语言:javascript
复制
[FluentValidation.Attributes.Validator(typeof(CustomerViewModelValidator))]
public class CustomerViewModel
{
    [Display(Name = "First Name")]
    public string FirstName { get; set; }

    [Display(Name = "Last Name")]
    public string LastName { get; set; }

    [Display(Name = "Phone")]
    public string Phone { get; set; }

    [Display(Name = "Email")]
    public string EmailAddress { get; set; }

    [Display(Name = "Guitar 1")]
    public Guitar Guitar1 { get; set; }

    [Display(Name = "Guitar 2")]
    public Guitar Guitar2 { get; set; }

    [Display(Name = "Guitar 3")]
    public Guitar Guitar3 { get; set; }
}

自定义Guitar对象

代码语言:javascript
复制
public class GuitarValidator : AbstractValidator<Guitar>
{
    public GuitarValidator()
    {
        RuleFor(x => x.Make).NotEmpty();
        RuleFor(x => x.Model).NotEmpty();
        RuleFor(x => x.ProductionYear).NotEmpty();
    }
}

视图模型验证器

代码语言:javascript
复制
public class CustomerViewModelValidator : AbstractValidator<CustomerViewModel>
{
    public CustomerViewModelValidator()
    {
        RuleFor(x => x.FirstName).NotNull();
        RuleFor(x => x.LastName).NotNull();
        RuleFor(x => x.Phone).NotNull();
        RuleFor(x => x.EmailAddress).NotNull();

        //1st Guitar Object is Required
        RuleFor(x => x.Guitar).SetValidator(new GuitarValidator());



    }
}

视图

代码语言:javascript
复制
<!-- Guitar Object #1 -->
     <div id="cosponsorsTemplate_1">
            <div class="formColumn1">@Html.LabelFor(x=>x.Guitar1)</div>
            <div class="formColumn2">@Html.TextBoxFor(x => x.Guitar1.Make, new { Placeholder = "Make" })
                <div class="messageBottom">@Html.ValidationMessageFor(x => x.Guitar1.Make)</div>
            </div>
            <div class="formColumn3">@Html.TextBoxFor(x => x.Guitar1.Model, new { Placeholder = "Model" })
                <div class="messageBottom">@Html.ValidationMessageFor(x => x.Guitar1.Model)</div>
            </div>
            <div class="formColumn4">@Html.TextBoxFor(x =>x.Guitar1.ProductionYear, new { Placeholder = "Production Year" })
                <div class="messageBottom">@Html.ValidationMessageFor(x => x.Guitar1.ProductionYear)</div>
                <a class="icon delete" data-delete-id="1">Delete</a>
            </div>
        </div>

   <!-- Guitar Object #2 -->
        <div id="cosponsorsTemplate_2">
            <div class="formColumn1">@Html.LabelFor(x=>x.Guitar2)</div>
            <div class="formColumn2">@Html.TextBoxFor(x => x.Guitar2.Make, new { Placeholder = "Make" })
                <div class="messageBottom">@Html.ValidationMessageFor(x => x.Guitar2.Make)</div>
            </div>
            <div class="formColumn3">@Html.TextBoxFor(x => x.Guitar2.Model, new { Placeholder = "Model" })
                <div class="messageBottom">@Html.ValidationMessageFor(x => x.Guitar2.Model)</div>
            </div>
            <div class="formColumn4">@Html.TextBoxFor(x => x.Guitar2.ProductionYear, new { Placeholder = "Production Year" })
                <div class="messageBottom">@Html.ValidationMessageFor(x => x.Guitar2.ProductionYear)</div>
                <a class="icon delete" data-delete-id="2">Delete</a>
            </div>
        </div>

    <!-- Guitar Object #3 -->
        <div id="cosponsorsTemplate_3">
            <div class="formColumn1">@Html.LabelFor(x=>x.Guitar3)</div>
            <div class="formColumn2">@Html.TextBoxFor(x => x.Guitar3.Make, new { Placeholder = "Make" })
                <div class="messageBottom">@Html.ValidationMessageFor(x => x.Guitar3.Make)</div>
            </div>
            <div class="formColumn3">@Html.TextBoxFor(x => x.Guitar3.Model, new { Placeholder = "Model" })
                <div class="messageBottom">@Html.ValidationMessageFor(x => x.Guitar3.Model)</div>
            </div>
            <div class="formColumn4">@Html.TextBoxFor(x => x.Guitar3.ProductionYear, new { Placeholder = "Production Year" })
                <div class="messageBottom">@Html.ValidationMessageFor(x => x.Guitar3.ProductionYear)</div>
                <a class="icon delete" data-delete-id="3">Delete</a>
            </div>
        </div>
EN

回答 2

Stack Overflow用户

发布于 2014-02-03 16:42:04

文档说明复杂的图形应该使用专门的验证器。你可以这样利用它:

代码语言:javascript
复制
public class Customer {
  public string Name { get; set; }
  public Address Address { get; set; }
}

public class Address {
 public string Line1 { get; set; }
 public string Line2 { get; set; }
 public string Town { get; set; }
 public string County { get; set; }
 public string Postcode { get; set; }
}

public class AddressValidator : AbstractValidator<Address> {
  public AddressValidator() {
    RuleFor(address => address.Postcode).NotNull();
    //etc
  }
}

public class CustomerValidator : AbstractValidator<Customer> {
  public CustomerValidator() {
    RuleFor(customer => customer.Name).NotNull();
    RuleFor(customer => customer.Address).SetValidator(new AddressValidator())
  }

}

出发地:为复杂属性重新使用验证器

http://fluentvalidation.codeplex.com/wikipage?title=CreatingAValidator&referringTitle=Documentation

对于用例,您将为聚合对象创建一个Guitar和一个模型验证器。我记得有一个朋友遇到了类似的问题,因为验证器不知道如何在没有中间验证器的情况下遍历对象图。

票数 2
EN

Stack Overflow用户

发布于 2014-02-04 17:04:17

我解决了这个问题。

Guitar类

代码语言:javascript
复制
public class Guitar
{
    public string Model { get; set; }
    public int? ProductionYear { get; set; } 
    public string Make { get; set; }
}

需要一个Validator类型装饰器

代码语言:javascript
复制
 [Validator(typeof(GuitarValidator))]

校正

代码语言:javascript
复制
    [Validator(typeof(GuitarValidator))]
    public class Guitar
    {
        public string Model { get; set; }
        public int? ProductionYear { get; set; } 
        public string Make { get; set; }
    }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21532595

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档