/// <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); }
/// <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); }
/// <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"]; var branches = ResourcePathHelper.GetBranchedSegments(qExpand); var brHeaders = from br in branches select br.FirstOrDefault(); // to get collection of navigatio properties which is not expanded List <string> navProps = new List <string>(); XElement meta = XElement.Parse(context.MetadataDocument); const string fmtXPathToTypeProperty = "//*[local-name()='Schema' and @Namespace='{0}']/*[local-name()='EntityType' and @Name='{1}']/*[local-name()='NavigationProperty' and @Name]"; string xpath = string.Format(fmtXPathToTypeProperty, ResourcePathHelper.GetNamespaceName(context.EntityTypeFullName), ResourcePathHelper.GetBaseName(context.EntityTypeFullName)); var nodes = meta.XPathSelectElements(xpath); foreach (var n in nodes) { var name = ResourcePathHelper.GetBaseName(n.Attribute("Name").Value); if (!brHeaders.Any(x => x.Equals(name, StringComparison.Ordinal))) { navProps.Add(name); } } if (navProps.Count() > 0) { JObject jo = JObject.Parse(context.ResponsePayload); var version = JsonParserHelper.GetPayloadODataVersion(jo); var propSchemas = navProps.Select(x => string.Format(fmtCore, x)); string coreProperties = string.Join("\r\n,", propSchemas); string CoreObject = string.Format(fmtObj, coreProperties); string jSchema = JsonSchemaHelper.WrapJsonSchema(CoreObject, version); TestResult result; passed = JsonParserHelper.ValidateJson(jSchema, context.ResponsePayload, out result); if (!passed.HasValue) { info = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload, result != null ? result.LineNumberInError : -1); } } return(passed); }
/// <summary> /// Verify the code rule /// </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; // 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 branches = ResourcePathHelper.GetBranchedSegments(qExpand); foreach (var paths in branches) { string leadNavProp = paths.First(); // construct the desired srng schema and verify string rngSchema = string.Format(EntryCore2011.formatRng, leadNavProp, RngCommonPattern.CommonPatterns); RngVerifier verifier = new RngVerifier(rngSchema); TestResult result; passed = verifier.Verify(context, out result); if (!passed.Value) { info = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload, result.LineNumberInError); break; } } } return(passed); }
/// <summary> /// Verify the code rule /// </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"); } var queries = HttpUtility.ParseQueryString(context.Destination.Query); var expand = queries["$expand"]; if (!string.IsNullOrEmpty(expand)) { XElement root = XElement.Parse(context.ResponsePayload); var branches = ResourcePathHelper.GetBranchedSegments(expand); foreach (var paths in branches) { var currNode = root; for (int i = 0; i < paths.Length; i++) { string toExpand = paths[i]; var nodeExpanded = GetNodeWithExpandedLink(currNode, toExpand); //passed = VerifyExpandedLink(feed, toExpand, false) || VerifyExpandedLink(feed, toExpand, true); if (nodeExpanded == null) { info = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload); return(false); } currNode = nodeExpanded; } } } info = null; return(true); }