ModelValidator与ModelValidatorProvider

ModelValidator

public abstract class ModelValidator
{ public virtual bool IsRequired
{ get { return false; } } public virtual IEnumerable<ModelClientValidationRule> GetClientValidationRules()//用于客户端验证
{ return Enumerable.Empty<ModelClientValidationRule>(); } public abstract IEnumerable<ModelValidationResult> Validate(object container);//用于服务端验证 public static ModelValidator GetModelValidator(ModelMetadata metadata, ControllerContext context)
{ return new CompositeModelValidator(metadata, context); } }

ModelValidationResult集合只有在验证失败的情况下才会返回。验证通过的情况下,返回值时空集合

  • ModelValidationResult
public class ModelValidationResult
{ private string _memberName; private string _message; public string MemberName
{ get { return _memberName ?? String.Empty; } set { _memberName = value; } } public string Message
{ get { return _message ?? String.Empty; } set { _message = value; } } }

  • ModelClientValidationRule表示客户端验证规则,在HTML中辅助js进行客户端验证
public class ModelClientValidationRule
{ private readonly Dictionary<string, object> _validationParameters = new Dictionary<string, object>(); private string _validationType; public string ErrorMessage { get; set; } public IDictionary<string, object> ValidationParameters
{ get { return _validationParameters; } } public string ValidationType
{ get { return _validationType ?? String.Empty; } set { _validationType = value; } } }

  • CompositeModelValidator内部类,有ModelValidator的静态方法GetModelValidator返回.

当CompositeModelValidator 被用于验证一个容器对象的时候,会先验证其属性成员。针对容器对象自身的验证只有在所有属性值都通过验证的情况下才会进行

private class CompositeModelValidator : ModelValidator
{ public CompositeModelValidator(ModelMetadata metadata, ControllerContext controllerContext) : base(metadata, controllerContext)
{ } public override IEnumerable<ModelValidationResult> Validate(object container)
{ bool propertiesValid = true; foreach (ModelMetadata propertyMetadata in Metadata.Properties) { foreach (ModelValidator propertyValidator in propertyMetadata.GetValidators(ControllerContext)) { foreach (ModelValidationResult propertyResult in propertyValidator.Validate(Metadata.Model)) { propertiesValid = false; yield return new ModelValidationResult { MemberName = DefaultModelBinder.CreateSubPropertyName(propertyMetadata.PropertyName, propertyResult.MemberName), Message = propertyResult.Message }; } } } if (propertiesValid) { foreach (ModelValidator typeValidator in Metadata.GetValidators(ControllerContext)) { foreach (ModelValidationResult typeResult in typeValidator.Validate(container)) { yield return typeResult; } } } } }

  • DataAnnotationsModelValidator数据注解验证特性,最为常用的一种Model验证方案、

public class DataAnnotationsModelValidator : ModelValidator后边会有详细的介绍

  • ClientModelValidator 用于客户端的验证,是一个内部类.其用于服务端验证的Validate方法返回空的集合.

NurnericModelValidator和DateModelValidator是其继承者

  • DataErrorlnfoModelValidator
    1. IDataErrorInfo
    2. public interface IDataErrorInfo
      { string Error { get; }//基于自身的错误消息 string this[string columnName] { get; }//数据成员的错误消息 }

    3. DataErrorInfoClassModelValidator
    4. DataErrorInfoPropertyModelValidator
  • ValidatableObjectAdapter将自我验证的结果转换为通用的格式
    • IValidatableObject自我验证.

ModelValidatorProvider

ASPNET MVC多采用Provider的方式提供组件.

public abstract class ModelValidatorProvider
{//只有这一个方法 public abstract IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context); }

  • DataAnnotationsModelValidatorProvider
public class DataAnnotationsModelValidatorProvider : AssociatedValidatorProvider

public abstract class AssociatedValidatorProvider : ModelValidatorProvider
{ protected virtual ICustomTypeDescriptor GetTypeDescriptor(Type type)
{ return TypeDescriptorHelper.Get(type); } public sealed override IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context)
{ if (metadata == null) { throw new ArgumentNullException("metadata"); } if (context == null) { throw new ArgumentNullException("context"); } if (metadata.ContainerType != null && !String.IsNullOrEmpty(metadata.PropertyName)) { return GetValidatorsForProperty(metadata, context); } return GetValidatorsForType(metadata, context); } protected abstract IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context, IEnumerable<Attribute> attributes); private IEnumerable<ModelValidator> GetValidatorsForProperty(ModelMetadata metadata, ControllerContext context)
{//获取在父容器中的属性上的特性和数据类型上 的特性的列表. ICustomTypeDescriptor typeDescriptor = GetTypeDescriptor(metadata.ContainerType); PropertyDescriptor property = typeDescriptor.GetProperties().Find(metadata.PropertyName, true); if (property == null) { throw new ArgumentException( String.Format( CultureInfo.CurrentCulture, MvcResources.Common_PropertyNotFound, metadata.ContainerType.FullName, metadata.PropertyName), "metadata"); } return GetValidators(metadata, context, property.Attributes.OfType<Attribute>()); } private IEnumerable<ModelValidator> GetValidatorsForType(ModelMetadata metadata, ControllerContext context)
{//获取数据类型上的特性列表 return GetValidators(metadata, context, GetTypeDescriptor(metadata.ModelType).GetAttributes().Cast<Attribute>()); } }

  • ClientDataTypeModelValidatorProvider

针对数字/日期类型客户端验证的NumericModelValidator 和DateModelValidator 最终是通过具有如下定义的System.Web.Mvc.ClientDataTypeModelValidatorProvider 来提供的。在实现的GetValidators 方法中,它会根据指定ModelMetadata 判断被验证类型是否属于数字/DateTime 类型,如果是则直接返回一个包含单个NumericModelValidator 或者DateModelValidator对象的ModelValidator 集合。在这里被视为数字的类型包括byte 、sbyte 、short 、ushort 、int 、uint 、long 、ulong 、float 、double 和decimal 等。

public class ClientDataTypeModelValidatorProvider : ModelValidatorProvider
{ private static readonly HashSet<Type> _numericTypes = new HashSet<Type>(new Type[] { typeof(byte), typeof(sbyte), typeof(short), typeof(ushort), typeof(int), typeof(uint), typeof(long), typeof(ulong), typeof(float), typeof(double), typeof(decimal) }); //判断数据类型,返回Date或者Num的Validator private static IEnumerable<ModelValidator> GetValidatorsImpl(ModelMetadata metadata, ControllerContext context)
{ Type type = metadata.ModelType; if (IsDateTimeType(type, metadata)) { yield return new DateModelValidator(metadata, context); } if (IsNumericType(type)) { yield return new NumericModelValidator(metadata, context); } } }

  • DataErrorlnfoModelValidatorProvider

旨在对实现了IDataErrorInfo 接口的数据实施验证的两个DataErrorI nfoModelValidator(即DataErrorI nfoClassModelValidator 和DataErrorI nfoPrope均rModelValidator) ,最终是通过具有如下定义的System. Web.Mvc.DataErrorInfoModelValidatorProvider 来提供的。在实现的Get Validators 方法中,如果被验证数据类型实现了IDat aErrorI nfo 接口,它会基于指定的ModelMetadata 和ControllerContext 创建一个DataErrorInfoClassModelValidator 对象置于返回的ModelValidator 集合中。

如果被验证的对象是容器对象的某个属性,并且容器对象的类型(不是属性类型)实现了IDataE rrorInfo 接口,该方法返回的ModelValidator 集合中还会包含一个基于指定Mode lM etadata 和ControllerContext 创建的DataEηorI nfoPrope吗rModelValidator 对象。

private static IEnumerable<ModelValidator> GetValidatorsImpl(ModelMetadata metadata, ControllerContext context)
{ // If the metadata describes a model that implements IDataErrorInfo, we should call its // Error property at the appropriate time. if (TypeImplementsIDataErrorInfo(metadata.ModelType)) { yield return new DataErrorInfoClassModelValidator(metadata, context); } // If the metadata describes a property of a container that implements IDataErrorInfo, // we should call its Item indexer at the appropriate time. if (TypeImplementsIDataErrorInfo(metadata.ContainerType)) { yield return new DataErrorInfoPropertyModelValidator(metadata, context); } }

  • ModelValidatorProviders

ModelMetadata有一个方法,也可以获取ModelValidator.逻辑也是调用Provider获取的

public virtual IEnumerable<ModelValidator> GetValidators(ControllerContext context)
{ return ModelValidatorProviders.Providers.GetValidators(this, context); } public static class ModelValidatorProviders
{ private static readonly ModelValidatorProviderCollection _providers = new ModelValidatorProviderCollection() { new DataAnnotationsModelValidatorProvider(), new DataErrorInfoModelValidatorProvider(), new ClientDataTypeModelValidatorProvider() }; public static ModelValidatorProviderCollection Providers
{ get { return _providers; } } } public class ModelValidatorProviderCollection : Collection<ModelValidatorProvider>
{ public IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context)
{//集合中每个ModelValidatorProvider 创建的ModelValidator 会包含在该列表中。 return CombinedItems.SelectMany(provider => provider.GetValidators(metadata, context)); } }

Model绑定与验证

ModelState

  • Controller中有个ViewDataDictionary类型的ViewData属性
  • ViewDataDictionary类型中有一个ModelStateDictionary的ModelState属性
  • ModelStateDictionary:IDictionary<string, ModelState>
  • public class ModelState
    { private ModelErrorCollection _errors = new ModelErrorCollection(); //数据验证的结果,错误的集合 public ModelErrorCollection Errors
    { get
    { return this._errors; } } //ValueProvider提供的值 public ValueProviderResult Value { get; set; } }

验证消息的呈现

  • Model的验证是伴随着Model的绑定完成的.DefaultModelBinder中,在绑定的过程中,有如下的一段代码:
  • if (value == null && bindingContext.ModelState.IsValidField(modelStateKey)) {
    
                ModelValidator requiredValidator = ModelValidatorProviders.Providers.GetValidators(propertyMetadata, controllerContext).Where(v => v.IsRequired).FirstOrDefault();
    
                if (requiredValidator != null) {
    
                    foreach (ModelValidationResult validationResult in requiredValidator.Validate(bindingContext.Model)) {
    
                        bindingContext.ModelState.AddModelError(modelStateKey, validationResult.Message);
    
                    }
    
                }
    }

  • ValidationMessage/ ValidationMessageFor
  • ValidationSummary将所有的验证消息显示一起

ValidationSummary 方法通过判断ModelStateDictionary的Key 是否为空来判断ModelState 是否针对一个属性

Model绑定中的验证

  • Model绑定是递归进行的,验证不是递归的,在Model绑定的过程中会调用验证.
  • DefaultModelBinder中的验证是在这里
  • internal void BindComplexElementalModel(ControllerContext controllerContext, ModelBindingContext bindingContext, object model)
    { // need to replace the property filter + model object and create an inner binding context ModelBindingContext newBindingContext = CreateComplexElementalModelBindingContext(controllerContext, bindingContext, model); // validation if (OnModelUpdating(controllerContext, newBindingContext)) { BindProperties(controllerContext, newBindingContext); OnModelUpdated(controllerContext, newBindingContext); } } protected virtual void OnModelUpdated(ControllerContext controllerContext, ModelBindingContext bindingContext)
    { Dictionary<string, bool> startedValid = new Dictionary<string, bool>(StringComparer.OrdinalIgnoreCase); foreach (ModelValidationResult validationResult in ModelValidator.GetModelValidator(bindingContext.ModelMetadata, controllerContext).Validate(null)) { string subPropertyName = CreateSubPropertyName(bindingContext.ModelName, validationResult.MemberName); if (!startedValid.ContainsKey(subPropertyName)) { startedValid[subPropertyName] = bindingContext.ModelState.IsValidField(subPropertyName); } if (startedValid[subPropertyName]) { bindingContext.ModelState.AddModelError(subPropertyName, validationResult.Message); } } }

基于数据注解特性的Model验证

ValidationAttribute 特性

  • ValidationAttribute 不是MVC中的,是在System.ComponentModel.DataAnnotations中的

继承的时候,需要重写IsValid(,)方法.FormatErrorMessage会格式化错误消息,GetValidationResult会调用IsValid方法得到Result

  • ValidationResult包含错误消息和成员名称的组合.一组相关成员的列表

  • ValidationContext验证使用的上下文被验证对象的实例,类型,属性名称和显示名称

  • ValidationAttribute,只能在一个属性或类上应用一个,如果应用多个,只有一个生效.因为Provider在创建Validator的时候,会按照Attribute的TypeID分组,每个分组选择第一个.

DataAnnotationsModelValidator

  • DataAnnotationsModelValidator对象,在内部调用Attribute属性的验证方法
  • public class DataAnnotationsModelValidator : ModelValidator
    { public DataAnnotationsModelValidator(ModelMetadata metadata, ControllerContext context, ValidationAttribute attribute) { } public override IEnumerable<ModelValidationResult> Validate(object container)
    { // Per the WCF RIA Services team, instance can never be null (if you have // no parent, you pass yourself for the "instance" parameter). ValidationContext context = new ValidationContext(container ?? Metadata.Model, null, null); context.DisplayName = Metadata.GetDisplayName(); ValidationResult result = Attribute.GetValidationResult(Metadata.Model, context); if (result != ValidationResult.Success) { yield return new ModelValidationResult { Message = result.ErrorMessage }; } }
    }

    DataAnnotationsModelValidator<TAttribute>:DataAnnotationsModelValidator where TAttribute: ValidationAttribute
    public class DataAnnotationsModelValidator<TAttribute> : DataAnnotationsModelValidator where TAttribute : ValidationAttribute
    { public DataAnnotationsModelValidator(ModelMetadata metadata, ControllerContext context, TAttribute attribute) : base(metadata, context, attribute)
    { } protected new TAttribute Attribute
    { get { return (TAttribute)base.Attribute; } } }

    RequiredAttributeAdapter

    public class RequiredAttributeAdapter : DataAnnotationsModelValidator<RequiredAttribute>
    { public RequiredAttributeAdapter(ModelMetadata metadata, ControllerContext context, RequiredAttribute attribute) : base(metadata, context, attribute)
    { } public override IEnumerable<ModelClientValidationRule> GetClientValidationRules()
    { return new[] { new ModelClientValidationRequiredRule(ErrorMessage) }; } }

DataAnnotationsModelValidatorProvider

  • DataAnnotationsModelValidatorProvider

委托DataAnnotationsModelValidationFactory 根据ModelMetadata、ControllerContext 和ValidationAttribute 创建一个ModelValidator 对象。字段AttributeFactories 表示的字典将验证特性的类型作为Key ,换句话说它维护一个ValidationAttribute 特性类型和对应ModelValidator工厂的匹配关系。

在重写的GetValidators 方法中,针对提供的每一个ValidationAttribute 特性,它先根据其类型从AttributeFactories 字典中获取一个对应的DataAnn otationsModelValidationFactory 委托。如果该委托对象存在,则用它来创建相应的ModelValidator 对象,否则就采用字段DefaultAttributeFactory 表示的DataAnnotationsModelValidationFactory 委托来进行ModelValidator 的创建。

public class DataAnnotationsModelValidatorProvider : AssociatedValidatorProvider
{ internal static DataAnnotationsModelValidationFactory DefaultAttributeFactory = (metadata, context, attribute) => new DataAnnotationsModelValidator(metadata, context, attribute); internal static Dictionary<Type, DataAnnotationsModelValidationFactory> AttributeFactories = BuildAttributeFactoriesDictionary(); private static Dictionary<Type, DataAnnotationsModelValidationFactory> BuildAttributeFactoriesDictionary()
{ var dict = new Dictionary<Type, DataAnnotationsModelValidationFactory>(); AddValidationAttributeAdapter(dict, typeof(RangeAttribute), (metadata, context, attribute) => new RangeAttributeAdapter(metadata, context, (RangeAttribute)attribute)); AddValidationAttributeAdapter(dict, typeof(RegularExpressionAttribute), (metadata, context, attribute) => new RegularExpressionAttributeAdapter(metadata, context, (RegularExpressionAttribute)attribute)); AddValidationAttributeAdapter(dict, typeof(RequiredAttribute), (metadata, context, attribute) => new RequiredAttributeAdapter(metadata, context, (RequiredAttribute)attribute)); AddValidationAttributeAdapter(dict, typeof(StringLengthAttribute), (metadata, context, attribute) => new StringLengthAttributeAdapter(metadata, context, (StringLengthAttribute)attribute)); AddValidationAttributeAdapter(dict, ValidationAttributeHelpers.MembershipPasswordAttributeType, (metadata, context, attribute) => new MembershipPasswordAttributeAdapter(metadata, context, attribute)); AddValidationAttributeAdapter(dict, ValidationAttributeHelpers.CompareAttributeType, (metadata, context, attribute) => new CompareAttributeAdapter(metadata, context, attribute)); AddValidationAttributeAdapter(dict, ValidationAttributeHelpers.FileExtensionsAttributeType, (metadata, context, attribute) => new FileExtensionsAttributeAdapter(metadata, context, attribute)); AddDataTypeAttributeAdapter(dict, ValidationAttributeHelpers.CreditCardAttributeType, "creditcard"); AddDataTypeAttributeAdapter(dict, ValidationAttributeHelpers.EmailAddressAttributeType, "email"); AddDataTypeAttributeAdapter(dict, ValidationAttributeHelpers.PhoneAttributeType, "phone"); AddDataTypeAttributeAdapter(dict, ValidationAttributeHelpers.UrlAttributeType, "url"); return dict; } private static void AddValidationAttributeAdapter(Dictionary<Type, DataAnnotationsModelValidationFactory> dictionary, Type validataionAttributeType, DataAnnotationsModelValidationFactory factory)
{ Contract.Assert(dictionary != null); if (validataionAttributeType != null) { dictionary.Add(validataionAttributeType, factory); } } private static void AddDataTypeAttributeAdapter(Dictionary<Type, DataAnnotationsModelValidationFactory> dictionary, Type attributeType, string ruleName)
{ AddValidationAttributeAdapter( dictionary, attributeType, (metadata, context, attribute) => new DataTypeAttributeAdapter(metadata, context, (DataTypeAttribute)attribute, ruleName)); } }

除了AttributeFactories 和DefaultAttributeFactory , DataAnnotationsModelValidatorProvider还具有DefaultValidatableFactory 和ValidatableFactories 两个静态字段,它们用于针对可验证对象(实现了IValidatableObject 接口)的ModelValidator 创建。字段DefaultValidatableFactory的类型是另外一个名为DataAnnotations Validatab leObjectAdapterFactory 的委托,该委托根据

ModelMetadata 和ControllerContext 创建相应的ModelValidator 。字段Validatab leF actories 是一个以此委托为Value 、以Type 对象为Key 的字典。

当DataAnnotationsModelValidatorProvider 完成了针对基于验证特性的ModelValidator 的创建之后,如果被验证数据类型实现了IValidatableObject 接口,它会先从静态字段ValidatableFactories 中根据此类型获取一个对应的DataAnnotationsValidatableObjec tAdapterFactory委托。如果匹配的委托对象存在,则用其进行ModelValidator 的创建,否则采用字段DefaultValidatableFactory 表示的默认工厂来创建相应的ModelValidator 对象。创建的是 public class ValidatableObjectAdapter : ModelValidator.

可以根据需要对Adapter和AdapterFactory进行注册.

可以通过扩展,使用对参数添加的验证特性.默认的情况下,是不会读取应用在参数上的验证特性的.

DefaultModelBinder对简单参数的绑定,是不会进行参数验证的.只对复杂的参数类型进行验证.可以自定义继承者DefaultModelBinder的类,实现对简单类型的验证.添加对简单类型验证的代码

ParameterDescription包含了应用在参数上的特性

默认的数据验证Provider,是根据参数的数据类型生成ModelValidator的,没有读取参数上的特性.因此可以自定义继承自DataAnnotationsModelValidatorProvider的Provider,读取参数上的特性,创建ModelValidator,添加到默认的列表中.

想办法将ParameterDescription的信息传递到Provider中,因此可以将信息放入ControllerContext中传递过去.自定义ActionInvoke,将信息放入ControllerContext中

略…

一种Model类型,多种验证规则

  1. 定义一种应用在数据上的可使用多个的验证特性.每个特性有一个名称标示.重写TypeId属性,返回不同的值,这样Provider会根据每一个特性创建一个验证,否则会默认取相同类型的第一个特性.
  1. 定义一种应用在Controller或者Action上的特性,给这个特性添加一个参数,表示要使用的验证特性(第一步中定义的)的名称.
  1. 在某一个环节中,将第二部中定义的特性,也就是要使用的验证特性的名称添加到ControllerContext中,如DataTokens中.可以再ActionInvoke中或者ExecuteCore中实现这个操作.
  1. 定义一个Provider继承DataAnnotationsModelValidatorProvider,读取特性列表,读取DataToken中的名称,筛选出要使用的相同类型特性中的某一个.添加到原有的Validator集合中.并将此Provider替换原有的Provider

客户端验证

JQuery验证

  1. 以内敛的方式制定验证规则,将验证规则名称放在Html的Class属性中如<input Class="Required URL"…>
  1. 单独制定验证规则和错误消息,通过JS根据属性名称指定所使用的验证规则和错误消息.

基于JQuery的Model验证

Data-val表示对用户的输入值验证

Data-val-name name表示JQuery验证规则 的名称

Data-val-name-para表示可选的验证参数

ModelClientValidationRule表示客户端验证规则

ModelValidator中有一个方法GetClientValidationRules返回客户端验证规则

客户端验证在这里还涉及到一个重要的接口System. Web.Mvc.IClientValidatable ,它具有唯一的GetClientValidationRules 方法来返回一个以System.Web.Mvc.ModelClientValidationRule对象表示的客户端验证规则列表。所有支持客户端验证的ValidationAttribute 都需要实现IClientValidatable 接口并通过实现.DataAnnotationsModelValidator.GetClientValidationRules 方法,如果对应的ValidationA伽ibute 实现了IClientValidatable 接口,它( ValidationAttribute )的GetClientValidationRules 方法被调用并将返回的ModelClientValidationRule 列表作为该方法的返回值。

Model的验证的更多相关文章

  1. MVC3 Model Binding验证方式

    1.使用ModelState在Action中进行验证 [HttpPost] public ViewResult MakeBooking(Appointment appt) { if (string.I ...

  2. MVC验证07-自定义Model级别验证

    原文:MVC验证07-自定义Model级别验证 在一般的自定义验证特性中,我们通过继承ValidationAttribute,实现IClientValidatable,只能完成对某个属性的自定义验证. ...

  3. MVC使用jQuery从视图向控制器传递Model,数据验证,MVC HTML辅助方法小结

    //MVC HTML辅助类常用方法记录 (1)@Html.DisplayNameFor(model => model.Title)是显示列名, (2)@Html.DisplayFor(model ...

  4. 【ASP.NET Core快速入门】(十五)MVC开发:ReturnUrl实现、Model后端验证 、Model前端验证

    ReturnUrl实现 我们要实现returnUrl,我们需要在注册(Register)方法中接收传进的returnUrl并给它默认值null,然后将它保存在ViewData里面 然后我们定义一个内部 ...

  5. 菜鸟入门【ASP.NET Core】15:MVC开发:ReturnUrl实现、Model后端验证 、Model前端验证

    ReturnUrl实现 我们要实现returnUrl,我们需要在注册(Register)方法中接收传进的returnUrl并给它默认值null,然后将它保存在ViewData里面 然后我们定义一个内部 ...

  6. .NET MVC model数据验证

    MVC提供了很方便的数据验证,只需要在model里加入相关的正则等,那么就会在前台里生成相关的验证脚本.需要引用两个js文件: jquery.validate.min.js jquery.valida ...

  7. 任务48:Identity MVC:Model后端验证

    任务48:Identity MVC:Model后端验证 RegisterViewModel using System; using System.Collections.Generic; using ...

  8. 任务49:Identity MVC:Model前端验证

    任务49:Identity MVC:Model前端验证 前端验证使用的是jquery的validate的组件 _ValidationScriptsPartial.cshtml 在我们的layout里面 ...

  9. 关于MVC中模型model的验证问题

    今天在做项目练习的时候发现,MVC中使用自带的模型验证时会提前显示在界面上,比如下面所示: 这是什么原因了,是因为我在表示get请求的action里面返回了其界面所显示使用的model,我们知道mvc ...

随机推荐

  1. 为边框应用图片 border-image

    为边框应用图片 border-image 顾名思义就是为边框应用背景图片,它和我们常用的background属性比较相似.例如: background:url(xx.jpg) 10px 20px no ...

  2. Liferay IDE3.1 M1的一些新功能

    定于11月发布的Liferay IDE提供了一些让人期许的功能 1. code upgrade tools 这个工具将会帮助你把liferay 6.2的项目升级为7.0的项目.下面列举其主要功能 1. ...

  3. CPU大小端判断

    两种方式:1.通过指针         2.通过联合体,联合体里面的数据都是按顺序存储的,而且不论联合体里面有多少数据类型,联合体长度是最长的数据类型的长度.不论初始化多少联合体里面的数据,有效的是最 ...

  4. 关于Python中的yield

    关于Python中的yield   在介绍yield前有必要先说明下Python中的迭代器(iterator)和生成器(constructor). 一.迭代器(iterator) 在Python中,f ...

  5. modernizr.js

    1.判断浏览器是否支持 h5 if(Modernizr.canvas){ alert(123); }else{ alert(321); } 2.判断浏览器是否支持 canvas function su ...

  6. 对git的初步认识

    虽然经常听说博客,但是却是第一次用.就像,虽然经常见电脑,但是却第一次接触软件.对于git也是一样,从来没听过,更不了解. 因为自己私下也没有去过多的了解,所以对于git只有一些有关书面资料的很片面的 ...

  7. ip地址转化代码实例

    /*@author: lgh@ * * */ #include <stdio.h> #include <string.h> #include <unistd.h> ...

  8. 05.Hibernate多对多关联

        前言:本文讲解使用Hibernate映射多对多关联关系,并使用多种方式映射多对多关联. 1.数据库表的多对多关系     本文根据学生信息表(tb_student)和教师信息表(tb_teac ...

  9. 二分图匹配 分类: ACM TYPE 2014-10-01 19:57 94人阅读 评论(0) 收藏

    #include<cstdio> #include<cstring> using namespace std; bool map[505][505]; int n, k; bo ...

  10. Oracle 导入导出数据 imp/exp impdp/expdp

    IMPDP/EXPDP 一.创建逻辑目录,该命令不会在操作系统创建真正的目录,最好以system等管理员创建.         create directory dpdata as '/opt'; 二 ...