Git Product home page Git Product logo

wcfdataannotations's People

Contributors

asmiech avatar ejustice avatar istvan86-nagy avatar krapaille avatar russcam avatar yazgoo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

wcfdataannotations's Issues

Sign the assembly with a strong name

Please, sign your assembly with a strong name to be usable in strong-named projects. I can't reference your NuGet package directly in my WCF library, I get the following error:

System.IO.FileLoadException: Could not load file or assembly 'Independer.WCFDataAnnotations, Version=1.1.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. A strongly-named assembly is required. (Exception from HRESULT: 0x80131044)
File name: 'Independer.WCFDataAnnotations, Version=1.1.0.0, Culture=neutral, PublicKeyToken=null'
   at System.ModuleHandle.ResolveType(RuntimeModule module, Int32 typeToken, IntPtr* typeInstArgs, Int32 typeInstCount, IntPtr* methodInstArgs, Int32 methodInstCount, ObjectHandleOnStack type)
   at System.ModuleHandle.ResolveTypeHandleInternal(RuntimeModule module, Int32 typeToken, RuntimeTypeHandle[] typeInstantiationContext, RuntimeTypeHandle[] methodInstantiationContext)
   at System.Reflection.RuntimeModule.ResolveType(Int32 metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments)
   at System.Reflection.CustomAttribute.FilterCustomAttributeRecord(CustomAttributeRecord caRecord, MetadataImport scope, Assembly& lastAptcaOkAssembly, RuntimeModule decoratedModule, MetadataToken decoratedToken, RuntimeType attributeFilterType, Boolean mustBeInheritable, Object[] attributes, IList derivedAttributes, RuntimeType& attributeType, IRuntimeMethodInfo& ctor, Boolean& ctorHasParameters, Boolean& isVarArg)
   at System.Reflection.CustomAttribute.IsCustomAttributeDefined(RuntimeModule decoratedModule, Int32 decoratedMetadataToken, RuntimeType attributeFilterType, Int32 attributeCtorToken, Boolean mustBeInheritable)
   at System.Reflection.CustomAttribute.IsDefined(RuntimeType type, RuntimeType caType, Boolean inherit)
   at Microsoft.Tools.Common.ServiceReflectionUtility.HasServiceContractAttribute(Type type)
   at Microsoft.Tools.Common.ServiceReflectionUtility.IsWcfServiceClass(Type type)
   at Microsoft.Tools.SvcHost.ServiceHostHelper.CheckServiceKind(Type type)
   at Microsoft.Tools.SvcHost.ServiceHostHelper.LoadServiceAssembly(String svcAssemblyPath)
   at Microsoft.Tools.SvcHost.ServiceHostHelper.LoadServiceAssembly(String svcAssemblyPath)
   at Microsoft.Tools.SvcHost.CrossAppDomainSvcHost..ctor(String svcAssemblyPath, String svcConfigPath)

Thanks,
Moski

Validation of nested collections

Hi,

I got very happy when i saw your fork as i need to validate nested collections within my serviceoperation argument types. But im not getting it to work. i have the following class.


[DataContract(IsReference = true)]
public class MyDto : MyBase
{
   [DataMember]
   [Required]
   public string OrderNo { get; set; }
   
   [DataMember]
   public ICollection<MySubDto> MySubDtoCollection = new  List<MySubDto>();
}

And my subcollection class:

[DataContract(IsReference = true)]
public class MySubDto : IValidatableObject
{
    [DataMember]
    [Required]
    public string IssueNo { get; set; }

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        throw new NotImplementedException();
    }
}

My service implements [ValidateDataAnnotationsBehavior] and my required attributes etc. work, but only for for MyDto but not for MySubDto. The Validate method is never called on MySubDto, i tried declaring the collectionproperty as IEnumerable, List etc but it does not work.

Thanks you

Suggestion: Expose DataAnnotation rules in WSDL

Hi,
I've written some code to expose the Data Annotation rules via the WSDL. Maybe you could add this to WfcDataAnnotations for completeness sake? I guess the code can be in co-operated into the ValidateDataAnnotationsBehaviorAttribute.

    /// <summary>
    /// Make DataAnnotations visible in the Wsdl.
    /// Place attribute on service implementation class.
    /// Use togehter with https://github.com/Independer/wcfdataannotations also get data annotations validation.
    /// 
    /// Example: 
    /// 
    ///     [ValidateDataAnnotationsBehavior]
    ///     [WsdlExportDataAnnotationsBehavior]
    ///     public class Service : IService
    ///     {
    ///         ...
    ///     }
    ///     
    /// </summary>
    [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
    public class WsdlExportDataAnnotationsBehaviorAttribute : Attribute, IContractBehavior, IWsdlExportExtension
    {
        private const string XmlDatatypeNamespace = "http://www.w3.org/2001/XMLSchema";
        private const string ValidateEmailPattern = @"(?i)^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$";

        public void ExportContract(WsdlExporter exporter, WsdlContractConversionContext context) { }

        public void ExportEndpoint(WsdlExporter exporter, WsdlEndpointConversionContext context)
        {
            if (context.ContractConversionContext.Contract == null)
                return;

            // Check all operations for properties
            foreach (OperationDescription op in context.ContractConversionContext.Contract.Operations)
            {
                foreach (ParameterInfo parameter in op.SyncMethod.GetParameters())
                {
                    AddPropertyAttributes(parameter.ParameterType, exporter.GeneratedXmlSchemas);
                }
            }
        }

        public void AddBindingParameters(ContractDescription contractDescription, ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) { }

        public void ApplyClientBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, ClientRuntime clientRuntime) { }

        public void ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, DispatchRuntime dispatchRuntime) { }

        public void Validate(ContractDescription contractDescription, ServiceEndpoint endpoint) { }

        private void AddPropertyAttributes(Type type, XmlSchemaSet schemaSet)
        {
            if (type == null)
                return;

            if (type.IsArray)
                type = type.GetElementType();

            if (type.IsGenericType)
                type = type.GenericTypeArguments[0];

            foreach (PropertyInfo property in type.GetProperties())
            {
                // Handle sub properties
                if (property.PropertyType.Assembly == type.Assembly || property.PropertyType.Namespace.StartsWith("System.Collections"))
                {
                    AddPropertyAttributes(property.PropertyType, schemaSet);
                }

                // There should at least exist DataMemberAttribute + a DataAnnotationAttribute
                var attributes = property.GetCustomAttributes();
                var attributeList = attributes as IList<Attribute> ?? attributes.ToList();
                if (attributeList.Count() < 2)
                    continue;

                // Only process properties with the Data Member attribute
                if (!attributeList.Any(x => x is DataMemberAttribute))
                    continue;

                // Find the property in the WSDL schema to update
                XmlSchemaElement propertyElement = null;
                foreach (var value in schemaSet.GlobalTypes.Values)
                {
                    var complexType = value as XmlSchemaComplexType;
                    if (complexType != null && complexType.ContentTypeParticle is XmlSchemaSequence)
                    {
                        if (property.DeclaringType == null || complexType.Name != property.DeclaringType.Name)
                            continue;

                        var sequence = (XmlSchemaSequence)complexType.ContentTypeParticle;
                        propertyElement = sequence.Items.Cast<XmlSchemaElement>().ToList().SingleOrDefault(x => x.Name == property.Name);
                        break;
                    }
                }

                // Handle different types of annotations
                foreach (var attribute in attributeList)
                {
                    if (attribute is DataMemberAttribute)
                        continue;

                    if (attribute is RequiredAttribute)
                    {
                        ApplyRequiredAttribute(propertyElement);
                    }
                    else if (attribute is StringLengthAttribute)
                    {
                        ApplyStringLengthAttribute(propertyElement, ((StringLengthAttribute)attribute));
                    }
                    else if (attribute is MinLengthAttribute)
                    {
                        ApplyMinLengthAttribute(propertyElement, ((MinLengthAttribute)attribute));
                    }
                    else if (attribute is MaxLengthAttribute)
                    {
                        ApplyMaxLengthAttribute(propertyElement, ((MaxLengthAttribute)attribute));
                    }
                    else if (attribute is RangeAttribute)
                    {
                        ApplyRangeAttribute(propertyElement, ((RangeAttribute)attribute));
                    }
                    else if (attribute is RegularExpressionAttribute)
                    {
                        ApplyRegularExpressionAttribute(propertyElement, ((RegularExpressionAttribute)attribute));
                    }
                    else if (attribute is EmailAddressAttribute)
                    {
                        ApplyEmailAddressAttribute(propertyElement);
                    }
                    else
                    {
                        // Don't let anything slipp through without us knowing
                        throw new Exception("Unhandled annotation exception!");
                    }
                }
            }
        }

        private XmlSchemaSimpleTypeRestriction GetSimpleTypeRestriction(XmlSchemaElement element, XmlQualifiedName baseTypeName)
        {
            var simpleType = element.SchemaType as XmlSchemaSimpleType;
            if (simpleType == null)
                element.SchemaType = simpleType = new XmlSchemaSimpleType();

            var simpleTypeRestriction = simpleType.Content as XmlSchemaSimpleTypeRestriction;
            if (simpleTypeRestriction == null)
                simpleType.Content = simpleTypeRestriction = new XmlSchemaSimpleTypeRestriction { BaseTypeName = baseTypeName };
            element.SchemaTypeName = null;

            return simpleTypeRestriction;
        }

        private void ApplyRequiredAttribute(object item)
        {
            var element = item as XmlSchemaElement;
            if (element != null)
            {
                element.IsNillable = false;
                element.MinOccurs = 1;
            }
        }

        private void ApplyStringLengthAttribute(object item, StringLengthAttribute attribute)
        {
            var element = item as XmlSchemaElement;
            if (element != null && element.ElementSchemaType.Datatype.TypeCode == XmlTypeCode.String)
            {
                var simpleTypeRestriction = GetSimpleTypeRestriction(element, new XmlQualifiedName("string", XmlDatatypeNamespace));
                simpleTypeRestriction.Facets.Add(new XmlSchemaMinLengthFacet { Value = attribute.MinimumLength.ToString() });
                simpleTypeRestriction.Facets.Add(new XmlSchemaMaxLengthFacet { Value = attribute.MaximumLength.ToString() });
            }
        }

        private void ApplyMinLengthAttribute(object item, MinLengthAttribute attribute)
        {
            var element = item as XmlSchemaElement;
            if (element != null && element.ElementSchemaType.Datatype.TypeCode == XmlTypeCode.String)
            {
                var simpleTypeRestriction = GetSimpleTypeRestriction(element, new XmlQualifiedName("string", XmlDatatypeNamespace));
                simpleTypeRestriction.Facets.Add(new XmlSchemaMinLengthFacet { Value = attribute.Length.ToString() });
            }
        }

        private void ApplyMaxLengthAttribute(object item, MaxLengthAttribute attribute)
        {
            var element = item as XmlSchemaElement;
            if (element != null && element.ElementSchemaType.Datatype.TypeCode == XmlTypeCode.String)
            {
                var simpleTypeRestriction = GetSimpleTypeRestriction(element, new XmlQualifiedName("string", XmlDatatypeNamespace));
                simpleTypeRestriction.Facets.Add(new XmlSchemaMaxLengthFacet { Value = attribute.Length.ToString() });
            }
        }

        private void ApplyRangeAttribute(object item, RangeAttribute attribute)
        {
            var element = item as XmlSchemaElement;
            if (element != null)
            {
                dynamic minimum = attribute.Minimum;
                dynamic maximum = attribute.Maximum;

                var simpleTypeRestriction = GetSimpleTypeRestriction(element, new XmlQualifiedName(element.ElementSchemaType.Datatype.TypeCode.ToString().ToLower(), XmlDatatypeNamespace));
                simpleTypeRestriction.Facets.Add(new XmlSchemaMinInclusiveFacet { Value = XmlConvert.ToString(minimum) });
                simpleTypeRestriction.Facets.Add(new XmlSchemaMaxInclusiveFacet { Value = XmlConvert.ToString(maximum) });
            }
        }

        private void ApplyRegularExpressionAttribute(object item, RegularExpressionAttribute attribute)
        {
            var element = item as XmlSchemaElement;
            if (element != null)
            {
                var simpleTypeRestriction = GetSimpleTypeRestriction(element, new XmlQualifiedName(element.ElementSchemaType.Datatype.TypeCode.ToString().ToLower(), XmlDatatypeNamespace));
                simpleTypeRestriction.Facets.Add(new XmlSchemaPatternFacet() { Value = attribute.Pattern });
            }
        }

        private void ApplyEmailAddressAttribute(object item)
        {
            var element = item as XmlSchemaElement;
            if (element != null)
            {
                // Regexp pattern taken from http://referencesource.microsoft.com/#System.ComponentModel.DataAnnotations/DataAnnotations/EmailAddressAttribute.cs
                var simpleTypeRestriction = GetSimpleTypeRestriction(element, new XmlQualifiedName("string", XmlDatatypeNamespace));
                simpleTypeRestriction.Facets.Add(new XmlSchemaPatternFacet() { Value = ValidateEmailPattern });
            }
        }
    }

Sequence contains more than one matching element

Independer.WCFDataAnnotations.ValidateDataAnnotationsBehavior.GetParameterInfo(String operationName, IEnumerable`1 contractOperations)

I am having multiple types of binding for same contract

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.