/// <summary>
        /// Construct a complex type value according to its metadata definition.
        /// </summary>
        /// <param name="complexName">The name of the complex type.</param>
        /// <returns>The JSON object value of the complex type.</returns>
        public JObject ConstructAComplexTypeValue(string complexName)
        {
            string        metadataDoc              = ServiceStatus.GetInstance().MetadataDocument;
            JObject       result                   = new JObject();
            List <string> complextTypeNames        = MetadataHelper.GetAllComplexNameFromMetadata(metadataDoc);
            Dictionary <string, string> properties = MetadataHelper.GetAllPropertiesOfComplexType(metadataDoc, complexName);

            foreach (string prop in properties.Keys)
            {
                string type = properties[prop];
                if (EdmTypeManager.IsEdmSimpleType(type))
                {
                    IEdmType edmType = EdmTypeManager.GetEdmType(type);
                    result[prop] = edmType.GetJsonValueTemplate();
                }
                else if (type.Contains("Collection"))
                {
                    string itemType = type.Substring(type.IndexOf('(') + 1, type.Length - 12).GetLastSegment();

                    result[prop] = ConstructCollectionTypeValue(itemType);
                }
                else if (MetadataHelper.IsEnumType(metadataDoc, type))
                {
                    result[prop] = ConstructEnumTypeValue(type);
                }
                else if (complextTypeNames != null && complextTypeNames.Contains(type))
                {
                    result[prop] = ConstructAComplexTypeValue(type);
                }
            }

            return(result);
        }
        /// <summary>
        /// Provide value template for a primitive type.
        /// </summary>
        /// <param name="type">The primitive type name.</param>
        /// <returns>The template value of the primitive type.</returns>
        public string ConstructPrimitiveTypeValue(string type)
        {
            if (EdmTypeManager.IsEdmSimpleType(type))
            {
                IEdmType edmType = EdmTypeManager.GetEdmType(type);
                return(edmType.GetJsonValueTemplate());
            }

            return(null);
        }
Beispiel #3
0
        /// <summary>
        /// Verify the code rule
        /// </summary>
        /// <param name="context">Service context</param>
        /// <param name="info">out paramater to return violation information when rule fail</param>
        /// <returns>true if rule passes; false otherwise</returns>
        public override bool?Verify(ServiceContext context, out ExtensionRuleViolationInfo info)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            bool?passed = null;

            info = null;

            var     segments   = ResourcePathHelper.GetPathSegments(context).ToArray();
            var     edmxHelper = new EdmxHelper(XElement.Parse(context.MetadataDocument));
            UriType uriType;
            var     target = edmxHelper.GetTargetType(segments, out uriType);

            if (uriType == UriType.URI4 || uriType == UriType.URI5)
            {
                passed = false;
                string  targetType = ((EdmProperty)target).TypeUsage.EdmType.FullName;
                string  property   = segments.LastOrDefault(s => !s.StartsWith("$"));
                JObject jo         = JObject.Parse(context.ResponsePayload);
                var     inner      = jo.ReachInnerToken();
                if (inner.Type == JTokenType.Object)
                {
                    JObject innerObj = (JObject)inner;
                    if (innerObj.Properties() != null && innerObj.Properties().Count() == 1)
                    {
                        var    value        = innerObj.Properties().First().Value;
                        string valueLiteral = value.ToString();

                        IEdmType type = EdmTypeManager.GetEdmType(targetType);

                        bool isValidJsonData = type.IsGoodInJsonWith(valueLiteral);
                        if (isValidJsonData)
                        {
                            passed = true;
                        }
                        else
                        {
                            // target type may allow null
                            //TODO: allow null only when the target type is nullable
                            passed = valueLiteral.Equals("null", StringComparison.Ordinal);
                        }
                    }
                }
            }

            if (passed.HasValue && !passed.Value)
            {
                info = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload, -1);
            }

            return(passed);
        }
Beispiel #4
0
        /// <summary>
        /// Verify the code rule
        /// </summary>
        /// <param name="context">Service context</param>
        /// <param name="info">out paramater to return violation information when rule fail</param>
        /// <returns>true if rule passes; false otherwise</returns>
        public override bool?Verify(ServiceContext context, out ExtensionRuleViolationInfo info)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            bool?passed = null;

            info = null;

            var segments = ResourcePathHelper.GetPathSegments(context).ToArray();

            if (segments.Length > 0)
            {
                string lastSeg = segments[segments.Length - 1];
                if (lastSeg.Equals("$value", StringComparison.Ordinal))
                {
                    var     edmxHelper = new EdmxHelper(XElement.Parse(context.MetadataDocument));
                    UriType uriType;
                    var     target = edmxHelper.GetTargetType(segments, out uriType);
                    if (uriType == UriType.URI4 || uriType == UriType.URI5)
                    {
                        string targetType = ((EdmProperty)target).TypeUsage.EdmType.FullName;
                        if (!string.IsNullOrEmpty(targetType))
                        {
                            // do the validation here
                            IEdmType type = EdmTypeManager.GetEdmType(targetType);
                            if (type != null)
                            {
                                passed = type.IsGoodWith(context.ResponsePayload);
                                if (passed.HasValue && !passed.Value)
                                {
                                    info = new ExtensionRuleViolationInfo("pattern not matched", context.Destination, context.ResponsePayload, 1);
                                }
                            }
                            else
                            {
                                // type unknown
                                info   = new ExtensionRuleViolationInfo("unrecognized Edm type", context.Destination, targetType, 1);
                                passed = false;
                            }
                        }
                    }
                }
            }

            return(passed);
        }
Beispiel #5
0
        /// <summary>
        /// Checks whether the value is well-formatted based on the type
        /// </summary>
        /// <param name="value">The value</param>
        /// <param name="typeName">Name of the type</param>
        /// <returns>bool indicating value being well-formatted</returns>
        protected bool VerifyValueByPrimitiveType(string value, string typeName)
        {
            bool result = true;

            if (!string.IsNullOrEmpty(value))
            {
                IEdmType type = EdmTypeManager.GetEdmType(typeName);
                if (type == null)
                {
                    //unrecognized primitive type
                    result = false;
                }
                else
                {
                    result = type.IsGoodWith(value);
                }
            }

            return(result);
        }
Beispiel #6
0
        /// <summary>
        /// Verifies the service implementation feature.
        /// </summary>
        /// <param name="context">The Interop service context</param>
        /// <param name="info">out parameter to return violation information when rule does not pass</param>
        /// <returns>true if the service implementation feature passes; false otherwise</returns>
        public override bool?Verify(ServiceContext context, out ExtensionRuleViolationInfo info)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            bool?passed = null;

            info = null;
            var svcStatus = ServiceStatus.GetInstance();

            string url    = svcStatus.RootURL.TrimEnd('/');
            var    detail = new ExtensionRuleResultDetail(this.Name, url, HttpMethod.Get, string.Empty);

            JObject serviceJO;

            svcStatus.ServiceDocument.TryToJObject(out serviceJO);

            JArray serviceOA = JsonParserHelper.GetEntries(serviceJO);

            string   xpath          = string.Format(@"//*[local-name()='FunctionImport']");
            XElement md             = XElement.Parse(svcStatus.MetadataDocument);
            XElement functionImport = md.XPathSelectElement(xpath, ODataNamespaceManager.Instance);

            if (functionImport == null)
            {
                detail.ErrorMessage = "The service has no function Import.";
                info = new ExtensionRuleViolationInfo(new Uri(url), string.Empty, detail);
                return(passed);
            }

            string functionShortName = functionImport.Attribute("Function").Value.GetLastSegment();

            XElement function = md.XPathSelectElement(string.Format(@"//*[local-name()='Function' and @Name='{0}' and not (@IsBound='true')]", functionShortName), ODataNamespaceManager.Instance);

            string parameterString = string.Empty;
            List <KeyValuePair <string, string> > paralist = new List <KeyValuePair <string, string> >();

            if (function != null)
            {
                IEnumerable <XElement> parameters = function.XPathSelectElements(@"./*[local-name()='Parameter' and @Nullable='false']");
                foreach (XElement pa in parameters)
                {
                    string value = string.Empty;

                    if (EdmTypeManager.IsEdmSimpleType(pa.Attribute("Type").Value))
                    {
                        IEdmType typeInterface = EdmTypeManager.GetEdmType(pa.Attribute("Type").Value);
                        if (typeInterface != null)
                        {
                            value = typeInterface.GetXmlValueTemplate();
                        }
                    }

                    if (!string.IsNullOrEmpty(value))
                    {
                        KeyValuePair <string, string> kv = new KeyValuePair <string, string>(pa.Attribute("Name").Value, value);
                        paralist.Add(kv);
                    }
                    else
                    {
                        detail.ErrorMessage = "Parameter type is not supported by this test.";
                        info = new ExtensionRuleViolationInfo(new Uri(url), string.Empty, detail);
                        return(passed);
                    }
                }
            }

            for (int i = 0; i < paralist.Count; i++)
            {
                if (i == 0)
                {
                    parameterString = "(" + paralist[i].Key + "=" + paralist[i].Value;
                }
                else if (i < paralist.Count - 1)
                {
                    parameterString += "," + paralist[i].Key + "=" + paralist[i].Value;
                }
                else if (i == paralist.Count - 1)
                {
                    parameterString += "," + paralist[i].Key + "=" + paralist[i].Value + ")";
                }
            }

            url += @"/" + functionShortName + parameterString;

            Response response = WebHelper.GetEntity(url);

            if (response.StatusCode == HttpStatusCode.OK || response.StatusCode == HttpStatusCode.NoContent)
            {
                detail = new ExtensionRuleResultDetail(this.Name, url, HttpMethod.Get, string.Empty);
                passed = true;
            }
            else
            {
                passed = false;
            }

            info = new ExtensionRuleViolationInfo(new Uri(url), string.Empty, detail);
            return(passed);
        }
        /// <summary>
        /// Verify Common.Core.4623
        /// </summary>
        /// <param name="context">Service context</param>
        /// <param name="info">out parameter to return violation information when rule fail</param>
        /// <returns>true if rule passes; false otherwise</returns>
        public override bool?Verify(ServiceContext context, out ExtensionRuleViolationInfo info)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            bool?passed = null;

            info = null;

            // Single primitive individual property is not allowed to have instance annotation.
            if (VerificationHelper.IsIndividualPropertySinglePrimitiveType(context.ResponsePayload, context.PayloadType))
            {
                return(null);
            }

            XmlDocument xmlDoc = new XmlDocument();

            // Test Data
            // Url:http://services.odata.org/V4/OData/OData.svc/Products(0)/Description?$format=xml
            // xmlDoc.LoadXml("<?xml version=\"1.0\" encoding=\"utf-8\"?><m:value m:context=\"http://services.odata.org/V4/OData/OData.svc/$metadata#Products(0)/Description\" xmlns:atom=\"http://www.w3.org/2005/Atom\"  xmlns:d=\"http://docs.oasis-open.org/odata/ns/data\" xmlns:georss=\"http://www.georss.org/georss\" xmlns:gml=\"http://www.opengis.net/gml\" xmlns:m=\"http://docs.oasis-open.org/odata/ns/metadata\">Whole grain bread <m:annotation atom:term=\"ODataDemo.Product.Display\" m:target=\"Description\" m:type=\"Boolean\">true</m:annotation></m:value>");
            xmlDoc.LoadXml(context.ResponsePayload);

            XmlNodeList annotationElements = xmlDoc.SelectNodes(@"//*[local-name()='annotation']", ODataNamespaceManager.Instance);

            foreach (XmlNode annotatEle in annotationElements)
            {
                if (annotatEle.Attributes["null", Constants.NSMetadata] != null &&
                    annotatEle.Attributes["null", Constants.NSMetadata].Value.Equals("true"))
                {
                    return(null);
                }

                string content = annotatEle.InnerText;

                if (annotatEle.Attributes["type", Constants.NSMetadata] != null)
                {
                    string typeName = annotatEle.Attributes["type", Constants.NSMetadata].Value;

                    if (!typeName.Contains("."))
                    {
                        typeName = "Edm." + typeName;
                    }

                    if (EdmTypeManager.IsEdmSimpleType(typeName))
                    {
                        IEdmType edmType = EdmTypeManager.GetEdmType(typeName);
                        if (edmType.IsGoodWith(content))
                        {
                            passed = true;
                        }
                        else
                        {
                            passed = false;
                            info   = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload);
                            break;
                        }
                    }
                }
            }

            return(passed);
        }
Beispiel #8
0
        /// <summary>
        /// Verify Metadata.Core.4228
        /// </summary>
        /// <param name="context">Service context</param>
        /// <param name="info">out parameter to return violation information when rule fail</param>
        /// <returns>true if rule passes; false otherwise</returns>
        public override bool?Verify(ServiceContext context, out ExtensionRuleViolationInfo info)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            bool?passed = null;

            info = null;

            // Load MetadataDocument into XMLDOM
            XmlDocument xmlDoc = new XmlDocument();

            xmlDoc.LoadXml(context.MetadataDocument);

            string      xpath            = "//*[local-name()='EnumType']";
            XmlNodeList enumTypeNodeList = xmlDoc.SelectNodes(xpath);

            foreach (XmlNode enumType in enumTypeNodeList)
            {
                string underlyingType = string.Empty;
                if (enumType.Attributes["UnderlyingType"] != null)
                {
                    underlyingType = enumType.Attributes["UnderlyingType"].Value;
                }
                else
                {
                    underlyingType = "Edm.Int32";
                }

                foreach (XmlNode member in enumType.ChildNodes)
                {
                    if (!member.Name.Equals("Member"))
                    {
                        continue;
                    }
                    else
                    {
                        if (member.Attributes["Value"] != null)
                        {
                            IEdmType edmType = EdmTypeManager.GetEdmType(underlyingType);

                            if (edmType.IsGoodWith(member.Attributes["Value"].Value))
                            {
                                passed = true;
                            }
                            else
                            {
                                passed = false;
                                info   = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload);
                                break;
                            }
                        }
                    }
                }

                if (passed == false)
                {
                    break;
                }
            }

            return(passed);
        }