/// <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 edmxHelper = new EdmxHelper(XElement.Parse(context.MetadataDocument)); var segments = ResourcePathHelper.GetPathSegments(context); UriType uriType; var target = edmxHelper.GetTargetType(segments, out uriType); // to check this rule only when returned resource is collection of ComplexType if (uriType == UriType.URI11) { JObject jo = JObject.Parse(context.ResponsePayload); var version = JsonParserHelper.GetPayloadODataVersion(jo); string jSchema = JsonSchemaHelper.WrapJsonSchema(coreSchema, version); TestResult testResult; passed = JsonParserHelper.ValidateJson(jSchema, context.ResponsePayload, out testResult); if (passed.HasValue && !passed.Value) { info = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload, testResult != null ? testResult.LineNumberInError : -1); } } 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"]; 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> /// 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 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; // if __metadata.etag property is there, ensure its value equals to ETag header value var entry = JsonParserHelper.GetResponseObject(context); var etag = entry.GetPropertyOfChild("__metadata", "etag"); bool etagInPlace = etag != null; if (etagInPlace) { var etagInHeader = context.ResponseHttpHeaders.GetHeaderValue("ETag").Trim(); var etagLiteral = StringHelper.ToLiteral(etagInHeader); RuleEngine.TestResult result = null; ODataVersion version = JsonParserHelper.GetPayloadODataVersion(entry); switch (version) { case ODataVersion.V1: string schemaV1 = string.Format(EntryCore2009.schemaFormat_v1, etagLiteral); passed = JsonParserHelper.ValidateJson(schemaV1, context.ResponsePayload, out result); break; case ODataVersion.V2: string schemaV2 = string.Format(EntryCore2009.schemaFormat_v2, etagLiteral); passed = JsonParserHelper.ValidateJson(schemaV2, context.ResponsePayload, out result); break; default: passed = false; break; } if (!passed.Value) { 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 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 edmxHelper = new EdmxHelper(XElement.Parse(context.MetadataDocument)); var segments = ResourcePathHelper.GetPathSegments(context); UriType uriType; var target = edmxHelper.GetTargetType(segments, out uriType); // to check this rule only when returned resource is a ComplexType if (uriType == UriType.URI3 || uriType == UriType.URI12) { JObject jo = JObject.Parse(context.ResponsePayload); var version = JsonParserHelper.GetPayloadODataVersion(jo); ComplexType ct = (uriType == UriType.URI12) ? (ComplexType)target : (ComplexType)((EdmProperty)target).TypeUsage.EdmType; var props = from p in ct.Properties select p.Name; var jsProps = props.Select(x => string.Format(@"""{0}"" : {{""required"" : false }}", x)); string jsCore = string.Format(fmtCoreSchema, ct.Name, string.Join(",", jsProps.ToArray())); string jSchema = JsonSchemaHelper.WrapJsonSchema(jsCore, version); TestResult result; passed = JsonParserHelper.ValidateJson(jSchema, context.ResponsePayload, out result); if (passed.HasValue && !passed.Value) { 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 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; // for each entry within the collection (feed) // to check its __metadata.etag value (if existent) is the same as ETag header in the single entry response that would have been requested JObject feed; context.ResponsePayload.TryToJObject(out feed); ODataVersion version = JsonParserHelper.GetPayloadODataVersion(feed); var entries = JsonParserHelper.GetEntries(feed); int indexEntry = 0; int count = entries.Count; foreach (JObject e in entries) { var etag = e.GetPropertyOfElement("__metadata", "etag"); bool etagInPlace = etag != null; if (etagInPlace) { var targetSingleEntry = e.GetPropertyOfElement("__metadata", "uri"); // get the ETag header value for the entry var etagInSingleEntry = WebResponseHelper.GetETagOfEntry(targetSingleEntry, Constants.AcceptHeaderAtom); JSconSchemaBuilder builder; if (version == ODataVersion.V2) { builder = new JSconSchemaBuilder(jschemaV2Header, jschemaV2Tail); } else { builder = new JSconSchemaBuilder(jschemaV1Header, jschemaV1Tail); } for (int i = 0; i < indexEntry; i++) { builder.AddItem("{},"); } var etagLiteral = StringHelper.ToLiteral(etagInSingleEntry); string entryCore = string.Format(entryCoreFormat, etagLiteral); builder.AddItem(entryCore); for (int i = indexEntry + 1; i < count; i++) { builder.AddItem(",{}"); } var jSchema = builder.GetProduct(); RuleEngine.TestResult result = null; passed = JsonParserHelper.ValidateJson(jSchema, context.ResponsePayload, out result); if (!passed.Value) { info = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload, result != null ? result.LineNumberInError : -1); break; } } indexEntry++; } return(passed); }