使用 Lightspeed 进行 MVC3 验证

Posted

技术标签:

【中文标题】使用 Lightspeed 进行 MVC3 验证【英文标题】:MVC3 Validation with Lightspeed 【发布时间】:2011-07-18 23:59:38 【问题描述】:

我的 ORM (LightSpeed) 为 Animals 表生成这个,带有 Name 和 Age。使用 MVC3 和 Razor

   [Serializable]
  [System.CodeDom.Compiler.GeneratedCode("LightSpeedModelGenerator", "1.0.0.0")]
  [System.ComponentModel.DataObject]
  [Table(IdColumnName="AnimalID", IdentityMethod=IdentityMethod.IdentityColumn)]
  public partial class Animal : Entity<int>
       
    [ValidatePresence]
    [ValidateLength(0, 50)]
    private string _name;

    [ValidateComparison(ComparisonOperator.GreaterThan, 0)]
    private int _age;

    public const string NameField = "Name";
    public const string AgeField = "Age";

    [System.Diagnostics.DebuggerNonUserCode]
    [Required] // ****I put this in manually to get Name required working
    public string Name
    
      get  return Get(ref _name, "Name"); 
      set  Set(ref _name, value, "Name"); 
    

    [System.Diagnostics.DebuggerNonUserCode]
    public int Age
    
      get  return Get(ref _age, "Age"); 
      set  Set(ref _age, value, "Age"); 
    

添加了 [必需] 属性:

没有添加 [Required] 属性:(注意 LightSpeed 奇怪的验证渲染)

填写姓名:

在上图中 - 顶部的验证是 LightSpeed(放入 ValidationSummary),侧面是 MVC3(放入 ValidationMessageFor)

目前仅使用服务器端验证。

问题:如何让 LightSpeed 验证在 MVC3 中正常工作?

我觉得是这方面的东西http://www.mindscapehq.com/staff/jeremy/index.php/2009/03/aspnet-mvc-part4/

对于服务器端验证 - 您将需要使用自定义模型绑定器,它可以更精确地从 LightSpeed 验证中发出错误,而不是利用 DefaultModelBinder 行为。看看直接使用或改编 Mvc 社区代码库中的 EntityModelBinder

http://www.mindscapehq.com/forums/Thread.aspx?PostID=12051

【问题讨论】:

【参考方案1】:

见链接http://www.mindscapehq.com/forums/Thread.aspx?ThreadID=4093

Jeremys 的回答(Mindscape 有很大的支持!)

public class EntityModelBinder2 : DefaultModelBinder
  
    public static void Register(Assembly assembly)
    
      ModelBinders.Binders.Add(typeof(Entity), new EntityModelBinder2());

      foreach (Type type in assembly.GetTypes())
      
        if (typeof(Entity).IsAssignableFrom(type))
        
          ModelBinders.Binders.Add(type, new EntityModelBinder2());
        
      
    

    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    
      object result = base.BindModel(controllerContext, bindingContext);

      if (typeof(Entity).IsAssignableFrom(bindingContext.ModelType))
      
        Entity entity = (Entity)result;

        if (!entity.IsValid)
        
          foreach (var state in bindingContext.ModelState.Where(s => s.Value.Errors.Count > 0))
          
            state.Value.Errors.Clear();
          

          foreach (var error in entity.Errors)
          
            if (error.ErrorMessage.EndsWith("is invalid")) continue;
            bindingContext.ModelState.AddModelError(error.PropertyName ?? "Custom", error.ErrorMessage);
          
        
      

      return result;
    
  

并在 Global.asax 中使用:

EntityModelBinder2.Register(typeof(MyEntity).Assembly);

Register 调用设置模型绑定器以用于模型程序集中的每个实体类型,因此请根据需要进行修改。

【讨论】:

【参考方案2】:

从 2011 年 4 月 4 日起,您可以使用 Lightspeed 夜间构建进行客户端验证。

如下创建验证器提供者:

public class LightspeedModelValidatorProvider : DataAnnotationsModelValidatorProvider

    private string GetDisplayName(string name)
    
        return name; //  go whatever processing is required, eg decamelise, replace "_" with " " etc
    

    protected override IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context, IEnumerable<Attribute> attributes)
    

        if(typeof(Entity).IsAssignableFrom(metadata.ContainerType))
        
            List<Attribute> newAttributes = new List<Attribute>(attributes);
            var attr = DataAnnotationBuilder.GetDataAnnotations(metadata.ContainerType, metadata.PropertyName, GetDisplayName(metadata.PropertyName));
            newAttributes.AddRange(attr);

            return base.GetValidators(metadata, context, newAttributes);
        

        return base.GetValidators(metadata, context, attributes);
    

然后在 Application_Start() 中添加

        ModelValidatorProviders.Providers.Clear();
        ModelValidatorProviders.Providers.Add(new LightspeedModelValidatorProvider());

【讨论】:

以上是关于使用 Lightspeed 进行 MVC3 验证的主要内容,如果未能解决你的问题,请参考以下文章

如何在没有模型的情况下验证 MVC3 中的强类型视图

MVC3 输入相关验证

MVC3 中基于 AD 角色的授权

mvc3 + jQuery 验证:如何捕获错误或正常事件

mvc3 验证输入“不等于”

MVC 3/4 Intranet 应用程序自动/使用 Chrome 的静默身份验证