/// <summary>
        /// Verify the 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    qs      = HttpUtility.ParseQueryString(context.Destination.Query);
            string qExpand = qs["$expand"];

            if (!string.IsNullOrEmpty(qExpand))
            {
                JObject jo      = JObject.Parse(context.ResponsePayload);
                var     version = JsonParserHelper.GetPayloadODataVersion(jo);

                var        edmxHelper = new EdmxHelper(XElement.Parse(context.MetadataDocument));
                EntityType et;
                edmxHelper.TryGetItem(context.EntityTypeFullName, out et);

                var branches = ResourcePathHelper.GetBranchedSegments(qExpand);
                foreach (var paths in branches)
                {
                    var    navStack           = ODataUriAnalyzer.GetNavigationStack(et, paths).ToArray();
                    bool[] targetIsCollection = (from n in navStack select n.RelationshipMultiplicity == RelationshipMultiplicity.Many).ToArray();

                    // to verify each single entity type expanded along the navigation path to have proper properties
                    TestResult result = null;
                    for (int i = 0; i < paths.Length; i++)
                    {
                        string jSchema = null;

                        if (!targetIsCollection[i])
                        {
                            var    etShort = navStack[i].GetEntityType().FullName.GetLastSegment();
                            string jsET    = JsonSchemaHelper.GetSchemaForEntityType(etShort, context.MetadataDocument);
                            string jsCore  = string.Format(@"""{0}"" : {1}", paths[i], jsET);
                            jSchema = JsonSchemaHelper.GetJsonSchema(paths, i, version, jsCore, targetIsCollection);

                            passed = JsonParserHelper.ValidateJson(jSchema, context.ResponsePayload, out result);
                            if (!passed.Value)
                            {
                                break;
                            }
                        }
                    }

                    if (!passed.Value)
                    {
                        info = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload, result != null ? result.LineNumberInError : -1);
                        break;
                    }
                }
            }

            return(passed);
        }
Example #2
0
        /// <summary>
        /// Verifies the semantic rule
        /// </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 rule passes; false otherwise</returns>
        public override bool?Verify(ServiceContext context, out ExtensionRuleViolationInfo info)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            info = null;
            bool passed = true;

            // if query option of $expand is present, rule shall be verified
            // get the leftmost navigation property of expand query option
            var    qs      = HttpUtility.ParseQueryString(context.Destination.Query);
            string qExpand = qs["$expand"];

            if (!string.IsNullOrEmpty(qExpand))
            {
                var        edmxHelper = new EdmxHelper(XElement.Parse(context.MetadataDocument));
                EntityType et;
                edmxHelper.TryGetItem(context.EntityTypeFullName, out et);

                var     segments = ResourcePathHelper.GetPathSegments(context);
                UriType uriType;
                var     target = edmxHelper.GetTargetType(segments, out uriType);
                bool    isColletcionResource = uriType == UriType.URI1 || uriType == UriType.URI_CollEt;

                var branches = ResourcePathHelper.GetBranchedSegments(qExpand);
                foreach (var paths in branches)
                {
                    var    navStack           = ODataUriAnalyzer.GetNavigationStack(et, paths).ToArray();
                    bool[] targetIsCollection = (from n in navStack select n.RelationshipMultiplicity == RelationshipMultiplicity.Many).ToArray();

                    string rngCore = @"<ref name=""anyContent"" />";
                    for (int i = paths.Length - 1; i >= 0; i--)
                    {
                        rngCore = targetIsCollection[i] ? GetRngOfInlineFeed(paths[i], rngCore) : GetRngOfInlineEntry(paths[i], rngCore);
                    }

                    // construct the desired srng schema and verify
                    string rngSchema = isColletcionResource
                        ? string.Format(formatRngOfColl, rngCore, RngCommonPattern.CommonPatterns)
                        : string.Format(formatRngSingle, rngCore, RngCommonPattern.CommonPatterns);

                    RngVerifier verifier = new RngVerifier(rngSchema);
                    TestResult  result;
                    passed = verifier.Verify(context, out result);
                    if (!passed)
                    {
                        info = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload, result.LineNumberInError);
                        break;
                    }
                }
            }

            return(passed);
        }