/// <summary> /// Verifies the extension 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"); } bool?passed = null; bool isPrpoExistInMetadata = false; info = null; JObject entry; context.ResponsePayload.TryToJObject(out entry); List <XElement> propsEntity = MetadataHelper.GetAllPropertiesOfEntity(context.MetadataDocument, context.EntityTypeShortName, MatchPropertyType.All); if (entry != null && entry.Type == JTokenType.Object) { // Get all the properties in current entry. var o = (JObject)entry; var jProps = o.Children(); foreach (JProperty jProp in jProps) { if (!JsonSchemaHelper.IsAnnotation(jProp.Name)) { // Find the jPro in EntityType Property foreach (var prop in propsEntity) { if (prop.Attribute("Name").Value.Equals(jProp.Name)) { isPrpoExistInMetadata = true; break; } else { isPrpoExistInMetadata = false; } } if (isPrpoExistInMetadata) { passed = true; } else { passed = false; info = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload); break; } } } } return(passed); }
/// <summary> /// Verifies the extension 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"); } bool?passed = null; info = null; JObject entry; context.ResponsePayload.TryToJObject(out entry); List <string> complexTypeNames = MetadataHelper.GetAllComplexNameFromMetadata(context.MetadataDocument); if (entry != null && entry.Type == JTokenType.Object) { // Get all the properties in current entry. var jProps = entry.Children(); bool isHaveComplexType = false; foreach (JProperty jProp in jProps) { if (complexTypeNames.Contains(jProp.Name)) { isHaveComplexType = true; var propsInComplexType = jProp.Value.Children <JProperty>(); foreach (JProperty propInComplexType in propsInComplexType) { if (propInComplexType.Name.Contains(Constants.OdataNS) && propInComplexType.Value.ToString().Trim('"') == MetadataHelper.GetPropertyTypeFromMetadata(jProp.Name, context.EntityTypeShortName, context.MetadataDocument) && JsonSchemaHelper.IsAnnotation(propInComplexType.Name)) { return(true); } } } } if (isHaveComplexType && passed == null) { passed = false; info = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload); } } return(passed); }
/// <summary> /// Verify Common.Core.4123 /// </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; JObject jObj; context.ResponsePayload.TryToJObject(out jObj); List <JToken> jos = new List <JToken>(); JsonParserHelper.GetJsonObjectsFromRespPayload(jObj, ref jos); foreach (JObject jo in jos) { var jProps = jo.Children(); foreach (JProperty jProp in jProps) { if (JsonSchemaHelper.IsAnnotation(jProp.Name) && (context.Version == ODataVersion.V4 ? jProp.Name.StartsWith("@") : !jProp.Name.Contains("@"))) { passed = null; if (jo[jProp.Name] != null) { passed = true; } else { passed = false; info = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload); break; } } } } return(passed); }
/// <summary> /// Verify the annotation when odata.metadata=none. /// </summary> /// <param name="entry">The Entry object</param> /// <param name="odataCount">The odata.count name</param> /// <param name="odataNextLink">The odata.nextLink name</param> /// <returns>Annotation right-true;otherwise-false</returns> private bool?VerifyNoneMetadataAnnotation(JObject entry, string odataCount, string odataNextLink) { bool isExistRight = false; bool?isAnnotationsExist = null; string[] annotations = { @"odata.context", @"odata.metadata", @"odata.metadataEtag", @"odata.type", @"odata.count", @"odata.nextLink", @"odata.deltaLink", @"odata.id", @"odata.editLink", @"odata.readLink", @"odata.etag", @"odata.navigationLink", @"odata.associationLink", @"odata.media" }; var jProps = entry.Children(); foreach (JProperty jProp in jProps) { var temps = (from a in annotations where jProp.Name.Contains(a) select a).ToArray(); if (JsonSchemaHelper.IsAnnotation(jProp.Name) && temps.Length >= 0) { // Annotations exist in response payload. isAnnotationsExist = true; if (jProp.Name.Equals(odataCount) || jProp.Name.Equals(odataNextLink)) { // In above situation. If the annotation is odata.nextLink or odata.count, the result is true. isExistRight = true; } else { isExistRight = false; break; } } } if (isAnnotationsExist == null) { isExistRight = true; } return(isExistRight); }
/// <summary> /// Verify Common.Core.4019 /// </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; JObject jObj; context.ResponsePayload.TryToJObject(out jObj); string ctrlInfoAnnotationPrefix = context.Version == ODataVersion.V4 ? Constants.V4OdataNS : Constants.OdataNS; if (jObj != null && jObj.Type == JTokenType.Object) { var jProps = jObj.Children(); foreach (JProperty jProp in jProps) { if (JsonSchemaHelper.IsAnnotation(jProp.Name) && jProp.Name.StartsWith(ctrlInfoAnnotationPrefix)) { passed = true; break; } } if (passed == null) { passed = false; info = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload); } } return(passed); }
/// <summary> /// Verifies the extension 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"); } bool?passed = null; info = null; string propertyType = string.Empty; string formatLiteral = string.Empty; List <string> complexTypeValues = new List <string>(); JObject jo; context.ResponsePayload.TryToJObject(out jo); string contextUrl = string.Empty; if (jo[Constants.OdataV4JsonIdentity] == null) { passed = false; info = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload); return(passed); } else { // Use the XPath query language to access the metadata document and get all Namespace and alias values. string xpath = @"//*[local-name()='DataServices']/*[local-name()='Schema']"; XElement metadata = XElement.Parse(context.MetadataDocument); var schemaElement = metadata.XPathSelectElement(xpath, ODataNamespaceManager.Instance); string nameSpace = schemaElement.GetAttributeValue("Namespace"); string alias = schemaElement.GetAttributeValue("Alias"); complexTypeValues = MetadataHelper.GetAllComplexNameFromMetadata(context.MetadataDocument); contextUrl = jo[Constants.OdataV4JsonIdentity].Value <string>().StripOffDoubleQuotes(); string[] feedSegment = contextUrl.Remove(0, contextUrl.IndexOf(Constants.JsonFeedIdentity) + Constants.JsonFeedIdentity.Length).Split('/'); string entitySetName = feedSegment[0].Split('(')[0]; string entityTypeName = XmlHelper.GetEntityTypeShortName(entitySetName, context.MetadataDocument); var normalProperties = MetadataHelper.GetAllPropertiesOfEntity(context.MetadataDocument, entityTypeName, MatchPropertyType.Normal); Dictionary <string, string> propertyNameAndComplexTypeName = new Dictionary <string, string>(); foreach (XElement xe in normalProperties) { if ((!string.IsNullOrEmpty(nameSpace) && xe.GetAttributeValue("Type").StartsWith(nameSpace)) || (!string.IsNullOrEmpty(alias) && xe.GetAttributeValue("Type").StartsWith(alias))) { string typeShortName = xe.GetAttributeValue("Type").Remove(0, xe.GetAttributeValue("Type").LastIndexOf('.') + 1); if (complexTypeValues.Contains(typeShortName)) { propertyNameAndComplexTypeName.Add(xe.GetAttributeValue("Name"), typeShortName); } } } string propertyName = feedSegment[1]; if (propertyNameAndComplexTypeName.ContainsKey(propertyName)) { List <string> propertiesOfComplexType = MetadataHelper.GetAllPropertiesNamesOfComplexType(context.MetadataDocument, propertyNameAndComplexTypeName[propertyName]); foreach (JProperty jp in jo.Children()) { if (!JsonSchemaHelper.IsAnnotation(jp.Name)) { if (propertiesOfComplexType.Contains(jp.Name)) { passed = true; } else { passed = false; info = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload); break; } } } } } return(passed); }
/// <summary> /// Verify Common.Core.4700 /// </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; JObject allobject; string acceptHeader = string.Empty; string noneMetadata = Constants.V3AcceptHeaderJsonNoMetadata; string odataCount = Constants.OdataCount; string odataNextLink = Constants.OdataNextLink; if (context.Version == ODataVersion.V4) { odataCount = Constants.V4OdataCount; odataNextLink = Constants.V4OdataNextLink; noneMetadata = Constants.V4AcceptHeaderJsonNoMetadata; } // Send none metadata Get request with no metadata acceptheader and get the Content-Type for response header. acceptHeader = Constants.V3AcceptHeaderJsonNoMetadata; if (context.Version == ODataVersion.V4) { acceptHeader = Constants.V4AcceptHeaderJsonNoMetadata; } Response response = WebHelper.Get(context.Destination, acceptHeader, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, context.RequestHeaders); response.ResponsePayload.TryToJObject(out allobject); string contentType = response.ResponseHeaders.GetHeaderValue("Content-Type"); // Whether the odata.metadata=none format parameter exist in response header. if (contentType.Contains(noneMetadata)) { if (context.PayloadType == RuleEngine.PayloadType.Feed) { JArray result = null; // Get children of Value property. foreach (var r in allobject.Children <JProperty>()) { if (JsonSchemaHelper.IsAnnotation(r.Name)) { if (r.Name.Equals(odataCount, StringComparison.Ordinal) || r.Name.Equals(odataNextLink, StringComparison.Ordinal)) { passed = true; } else { passed = false; } } else if (r.Name.Equals(Constants.Value, StringComparison.Ordinal) && r.Value.Type == JTokenType.Array) { result = (JArray)r.Value; } } foreach (JObject entry in result) { bool?valueArrayPass = this.VerifyNoneMetadataAnnotation(entry, odataCount, odataNextLink); if (!passed.HasValue && valueArrayPass.HasValue) { passed = valueArrayPass; } else if (passed.HasValue && valueArrayPass.HasValue) { passed = valueArrayPass.Value && passed.Value; } } } else { passed = this.VerifyNoneMetadataAnnotation(allobject, odataCount, odataNextLink); } } if (passed == false) { info = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload); } return(passed); }
/// <summary> /// Verifies the extension 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"); } bool? passed = null; info = null; JObject allobject; context.ResponsePayload.TryToJObject(out allobject); // If PayloadType is Feed, verify as below, eles is Entry. if (context.PayloadType.Equals(RuleEngine.PayloadType.Feed)) { var entries = JsonParserHelper.GetEntries(allobject); foreach (JObject entry in entries) { var o = (JObject)entry; var jProps = o.Children(); foreach (JProperty jProp in jProps) { if (JsonSchemaHelper.IsAnnotation(jProp.Name)) { if (Regex.IsMatch(jProp.Name, @"[a-zA-Z0-9]+\.[a-zA-Z0-9]+")) { passed = true; continue; } else { passed = false; info = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload); return passed; } } } } } else { var o = (JObject)allobject; var jProps = o.Children(); foreach (JProperty jProp in jProps) { if (JsonSchemaHelper.IsAnnotation(jProp.Name)) { if (Regex.IsMatch(jProp.Name, @"[a-zA-Z0-9]+\.[a-zA-Z0-9]+")) { passed = true; continue; } else { passed = false; info = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload); return passed; } } } } return passed; }
/// <summary> /// Verifies the extension 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"); } bool?passed = null; bool isComplexExistInMetadata = false; bool isObjecPropInMetadata = false; info = null; JObject entry; context.ResponsePayload.TryToJObject(out entry); string appropriatecomplexType = string.Empty; // Use the XPath query language to access the metadata document and get all Namespace value. string xpath = @"//*[local-name()='DataServices']/*[local-name()='Schema']"; List <string> appropriateNamespace = MetadataHelper.GetPropertyValues(context, xpath, "Namespace"); // Get Alias value. List <string> appropriateAlias = MetadataHelper.GetPropertyValues(context, xpath, "Alias"); XElement metadata = XElement.Parse(context.MetadataDocument); // Use the XPath query language to access the metadata document and get the node which will be used. xpath = string.Format(@"//*[local-name()='EntityType' and @Name='{0}']/*[local-name()='Property']", context.EntityTypeShortName); IEnumerable <XElement> propsEntity = metadata.XPathSelectElements(xpath, ODataNamespaceManager.Instance); xpath = @"//*[local-name()='Schema']/*[local-name()='ComplexType']"; List <string> propsComplex = MetadataHelper.GetPropertyValues(context, xpath, "Name"); if (entry != null && entry.Type == JTokenType.Object) { // Get all the properties in current entry. var o = (JObject)entry; var jProps = o.Children(); foreach (JProperty jProp in jProps) { if (!JsonSchemaHelper.IsAnnotation(jProp.Name)) { // whether the type of jProp is Object. if (jProp.Value.Type.Equals(JTokenType.Object)) { string complexType = string.Empty; // Find the jPro in EntityType Property foreach (var prop in propsEntity) { if (prop.Attribute("Name").Value.Equals(jProp.Name)) { isObjecPropInMetadata = true; complexType = prop.Attribute("Type").Value; break; } else { isObjecPropInMetadata = false; } } // Whether the Property with the Object Type is in metadata. if (isObjecPropInMetadata) { // Split the Object type value to get the appropriate complex type name. if ((appropriateNamespace.Count != 0) || (appropriateAlias.Count != 0)) { appropriatecomplexType = splitAliasOrNamespace(appropriateAlias, appropriateNamespace, complexType); } // Whether the appropriate complex type name can be found. if (appropriatecomplexType != null) { // Find the according complex type in EntityType Property if (propsComplex.Contains(appropriatecomplexType)) { isComplexExistInMetadata = true; } else { isComplexExistInMetadata = false; } // Whether the Complex type is in metadata. if (isComplexExistInMetadata) { // Use the XPath query language to access the metadata document and get the node which will be used. xpath = string.Format("//*[local-name()='ComplexType' and @Name='{0}']/*[local-name()='Property']", appropriatecomplexType); IEnumerable <XElement> propsComplexChild = metadata.XPathSelectElements(xpath, ODataNamespaceManager.Instance); // Find the jPro in EntityType Property foreach (var prop in propsComplexChild) { foreach (JProperty jPropChild in jProp.Value.Children()) { if (!JsonSchemaHelper.IsAnnotation(jPropChild.Name)) { if (prop.Attribute("Name").Value.Equals(jPropChild.Name)) { passed = true; break; } else { passed = false; } } } if (passed == false) { info = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload); break; } } } } else { break; } } } } } } return(passed); }
/// <summary> /// Verifies the extension 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"); } bool?passed = null; info = null; Dictionary <string, string> propertyNameAndCollectionComplex = new Dictionary <string, string>(); List <string> complexTypeNames = MetadataHelper.GetAllComplexNameFromMetadata(context.MetadataDocument); if (complexTypeNames.Count > 0) { List <XElement> propertyElements = MetadataHelper.GetAllPropertiesOfEntity(context.MetadataDocument, context.EntityTypeShortName, MatchPropertyType.Normal); foreach (XElement xe in propertyElements) { if (xe.GetAttributeValue("Type").StartsWith("Collection(")) { string collectionType = xe.GetAttributeValue("Type"); string complexType = collectionType.Substring(collectionType.IndexOf('(') + 1, collectionType.LastIndexOf(')') - collectionType.IndexOf('(') - 1).GetLastSegment(); if (complexTypeNames.Contains(complexType)) { propertyNameAndCollectionComplex.Add(xe.GetAttributeValue("Name"), complexType); } } } if (propertyNameAndCollectionComplex.Count > 0) { JObject entry; context.ResponsePayload.TryToJObject(out entry); foreach (JProperty jp in entry.Properties()) { if (propertyNameAndCollectionComplex.Keys.Contains(jp.Name)) { if (jp.Value.Type != JTokenType.Array) { passed = false; break; } else { // Find the property with complex type. List <string> complexProperties = MetadataHelper.GetAllPropertiesNamesOfComplexType(context.MetadataDocument, propertyNameAndCollectionComplex[jp.Name]); foreach (var jv in (JArray)jp.Value) { if (jv.Type != JTokenType.Object) { passed = false; break; } else { foreach (JProperty pro in ((JObject)jv).Properties()) { // Check whether the properties of complex exist in metadata. if (!JsonSchemaHelper.IsAnnotation(pro.Name)) { if (complexProperties.Contains(pro.Name)) { passed = true; } else { passed = false; break; } } } if (passed == false) { break; } } } if (passed == false) { break; } } } } } } if (passed == false) { info = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload); } return(passed); }
/// <summary> /// Verifies the extension 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"); } bool?passed = null; info = null; JObject allobject; context.ResponsePayload.TryToJObject(out allobject); string namespaceValue = string.Empty; string alias = string.Empty; // Whether odata.type value is namespace- or alias-qualified the instance's type bool isNamespaceValue = false; bool isAliasValue = false; bool isStartwithodata = false; // Use the XPath query language to access the metadata document and get all Namespace value. string xpath = @"//*[local-name()='DataServices']/*[local-name()='Schema']"; List <string> appropriateNamespace = MetadataHelper.GetPropertyValues(context, xpath, "Namespace"); namespaceValue = appropriateNamespace[0]; // Get Alias value. List <string> appropriateAlias = MetadataHelper.GetPropertyValues(context, xpath, "Alias"); if (appropriateAlias.Count > 0) { alias = appropriateAlias[0]; } // If PayloadType is Feed, verify as below, eles is Entry. if (context.PayloadType.Equals(RuleEngine.PayloadType.Feed)) { var entries = JsonParserHelper.GetEntries(allobject); foreach (JObject entry in entries) { var o = (JObject)entry; var jProps = o.Children(); foreach (JProperty jProp in jProps) { if (JsonSchemaHelper.IsAnnotation(jProp.Name) && jProp.Name.StartsWith("@")) { // odata is the namespace element, if contains it the whole element must be annotation. isStartwithodata = jProp.Name.StartsWith(@"@odata"); isNamespaceValue = jProp.Name.StartsWith("@" + namespaceValue); if (!string.IsNullOrEmpty(alias)) { isAliasValue = jProp.Name.StartsWith("@" + alias); } if (isStartwithodata || isNamespaceValue || isAliasValue) { passed = true; } else { passed = false; break; } } } if (passed == false) { break; } } } else { var o = (JObject)allobject; var jProps = o.Children(); foreach (JProperty jProp in jProps) { if (JsonSchemaHelper.IsAnnotation(jProp.Name) && jProp.Name.StartsWith("@")) { // odata is the namespace element, if contains it the whole element must be annotation. isStartwithodata = jProp.Name.StartsWith(@"@odata"); isNamespaceValue = jProp.Name.StartsWith("@" + namespaceValue); if (!string.IsNullOrEmpty(alias)) { isAliasValue = jProp.Name.StartsWith("@" + alias); } if (isStartwithodata || isNamespaceValue || isAliasValue) { passed = true; } else { passed = false; break; } } } } if (passed == false) { info = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload); } return(passed); }
/// <summary> /// Verifies the extension 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"); } bool?passed = null; info = null; XElement metadata = XElement.Parse(context.MetadataDocument); // Use the XPath query language to access the metadata document and get the node which will be used. string xpath = @"//*[local-name()='EntityType']/*[local-name()='Property' or local-name()='NavigationProperty']"; IEnumerable <XElement> propNameElements = metadata.XPathSelectElements(xpath, ODataNamespaceManager.Instance); List <string> propNames = new List <string>(); foreach (var propNameElement in propNameElements) { propNames.Add(propNameElement.Attribute("Name").Value); } List <string> queryOptionVals = ODataUriAnalyzer.GetQueryOptionValsFromUrl(context.Destination.ToString(), @"expand"); bool isQueryRefVals = context.Destination.ToString().Contains(@"$ref"); if (queryOptionVals.Count != 0) { JObject entry; context.ResponsePayload.TryToJObject(out entry); if (entry != null && entry.Type == JTokenType.Object) { // Get all the properties in current entry. var jProps = entry.Children(); // If the url contains the "$ref" marker, the program can verify the condition that each element must be represented as an entity reference. // If the url does not contain the "$ref" marker, the program can verify the condition that each element must be represented as an entity. if (isQueryRefVals) { foreach (JProperty jProp in jProps) { if (queryOptionVals.Contains(jProp.Name) && JTokenType.Array == jProp.Value.Type) { JEnumerable <JObject> jObjs = jProp.Value.Children <JObject>(); foreach (JObject jObj in jObjs) { passed = null; var subProps = jObj.Children(); foreach (JProperty subProp in subProps) { if (JsonSchemaHelper.IsAnnotation(subProp.Name) && subProp.Name.Contains(@"id")) { passed = true; break; } } if (passed == null) { passed = false; info = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload); break; } } } } } else { foreach (JProperty jProp in jProps) { if (queryOptionVals.Contains(jProp.Name) && JTokenType.Array == jProp.Value.Type) { JEnumerable <JObject> jObjs = jProp.Value.Children <JObject>(); foreach (JObject jObj in jObjs) { passed = null; // Get all the expand properties from current entity's property. var subProps = jObj.Children(); foreach (JProperty subProp in subProps) { if (!JsonSchemaHelper.IsAnnotation(subProp.Name) && propNames.Contains(subProp.Name)) { passed = true; } else if (!JsonSchemaHelper.IsAnnotation(subProp.Name) && !propNames.Contains(subProp.Name)) { passed = false; info = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload); break; } } } } } } } } return(passed); }
/// <summary> /// Verifies the extension 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"); } bool?passed = null; info = null; JObject allobject; context.ResponsePayload.TryToJObject(out allobject); // Whether odata.type value is namespace- or alias-qualified the instance's type bool isNamespaceValue = false; bool isAliasValue = false; // Use the XPath query language to access the metadata document and get all Namespace value. string xpath = @"//*[local-name()='DataServices']/*[local-name()='Schema']"; List <string> appropriateNamespace = MetadataHelper.GetPropertyValues(context, xpath, "Namespace"); // Get Alias value. List <string> appropriateAlias = MetadataHelper.GetPropertyValues(context, xpath, "Alias"); // If PayloadType is Feed, verify as below, eles is Entry. if (context.PayloadType.Equals(RuleEngine.PayloadType.Feed)) { var entries = JsonParserHelper.GetEntries(allobject); foreach (JObject entry in entries) { var o = (JObject)entry; var jProps = o.Children(); foreach (JProperty jProp in jProps) { if (JsonSchemaHelper.IsAnnotation(jProp.Name) && jProp.Parent.Type.Equals(JTokenType.Object)) { if (appropriateNamespace.Count != 0) { // Verify the annoatation start with namespace. foreach (string currentvalue in appropriateNamespace) { if (jProp.Name.Contains(currentvalue)) { isNamespaceValue = true; } else { isNamespaceValue = false; } } } if (appropriateAlias.Count != 0) { // Verify the annoatation start with alias. foreach (string currentvalue in appropriateAlias) { if (jProp.Name.Contains(currentvalue)) { isAliasValue = true; } else { isAliasValue = false; } } } if (!isNamespaceValue && !isAliasValue) { // Whether the annoatation use odata instead of namespace- or alias-qualified name of the annotation. if (jProp.Name.Contains(Constants.OdataNS)) { passed = true; continue; } else { passed = false; info = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload); break; } } } } if (passed == false) { break; } } } else { var jProps = allobject.Children(); foreach (JProperty jProp in jProps) { if (JsonSchemaHelper.IsAnnotation(jProp.Name) && jProp.Parent.Type.Equals(JTokenType.Object)) { if (appropriateNamespace.Count != 0) { // Verify the annoatation start with namespace. foreach (string currentvalue in appropriateNamespace) { if (jProp.Name.Contains(currentvalue)) { isNamespaceValue = true; } else { isNamespaceValue = false; } } } if (appropriateAlias.Count != 0) { // Verify the annoatation start with alias. foreach (string currentvalue in appropriateAlias) { if (jProp.Name.Contains(currentvalue)) { isAliasValue = true; } else { isAliasValue = false; } } } if (!isNamespaceValue && !isAliasValue) { // Whether the annoatation use odata instead of namespace- or alias-qualified name of the annotation. if (jProp.Name.Contains(Constants.OdataNS)) { passed = true; continue; } else { passed = false; info = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload); break; } } } } } return(passed); }
/// <summary> /// Verifies Common.Core.4703 /// </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"); } bool?passed = null; info = null; string[] annotations = { @"odata.context", @"odata.metadataEtag", @"odata.type", @"odata.count", @"odata.nextLink", @"odata.deltaLink", @"odata.id", @"odata.editLink", @"odata.readLink", @"odata.etag", @"odata.navigationLink", @"odata.associationLink", @"odata.media", @"odata.metadata" }; JObject jObj; context.ResponsePayload.TryToJObject(out jObj); if (jObj != null && jObj.Type == JTokenType.Object) { var jProps = jObj.Children(); foreach (JProperty jProp in jProps) { var temps = (from a in annotations where jProp.Name.Contains(a) select a).ToArray(); if (JsonSchemaHelper.IsAnnotation(jProp.Name) && temps.Length > 0) { if (ODataVersion.V3 == context.Version) { passed = null; if (jProp.Name.Contains("@")) { string str = jProp.Name.Remove(0, jProp.Name.IndexOf("@") + 1); if (!str.StartsWith("odata")) { passed = true; } else { if (!jProp.Name.StartsWith("odata")) { passed = true; } else { passed = false; info = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload); break; } } } else { if (!jProp.Name.StartsWith("odata")) { passed = true; } else { passed = false; info = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload); break; } } } else if (ODataVersion.V4 == context.Version) { passed = null; string str = jProp.Name.Remove(0, jProp.Name.IndexOf("@") + 1); if (!str.StartsWith("odata")) { passed = true; } else { if (!jProp.Name.StartsWith("odata")) { passed = true; } else { passed = false; info = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload); break; } } } } } } return(passed); }
private bool?VerifyOneEntry(JObject entry, ServiceContext context, List <string> appropriateNamespace, List <string> appropriateAlias) { bool? passed = null; string appropriateType = string.Empty; // Whether odata.type value is namespace- or alias-qualified the instance's type bool isNamespaceValue = false; bool isAliasValue = false; var jProps = entry.Children(); foreach (JProperty jProp in jProps) { // Whether odata.type exist in response. if (JsonSchemaHelper.IsAnnotation(jProp.Name) && jProp.Name.EndsWith("@" + Constants.OdataType) && !jProp.Name.StartsWith("@" + Constants.OdataType)) { string jPropName = jProp.Name.Remove(jProp.Name.IndexOf("@" + Constants.OdataType)); // Compare the value of odata.type with EntityType and ComplexType. if (MetadataHelper.IsPropsExistInMetadata(jPropName, context, out appropriateType)) { // Verify the annotation start with namespace. foreach (string currentvalue in appropriateNamespace) { if (appropriateType.Contains(currentvalue)) { isNamespaceValue = true; break; } else { isNamespaceValue = false; } } // Verify the annotation start with alias. foreach (string currentvalue in appropriateAlias) { if (appropriateType.Contains(currentvalue)) { isAliasValue = true; break; } else { isAliasValue = false; } } if (!appropriateType.StartsWith("Edm.") && !isNamespaceValue && !isAliasValue) { passed = true; } else { passed = false; break; } } } } return(passed); }
/// <summary> /// Verifies the extension 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"); } bool?passed = null; info = null; List <string> complexTypeNames = MetadataHelper.GetAllComplexNameFromMetadata(context.MetadataDocument); if (complexTypeNames.Count > 0) { Dictionary <string, string> propertyWithComplexType = MetadataHelper.GetPropertyNameWithComplexTypeFromEntity(context.EntityTypeShortName, context.MetadataDocument, complexTypeNames); if (propertyWithComplexType.Count > 0) { JObject entry; context.ResponsePayload.TryToJObject(out entry); foreach (JProperty jp in entry.Properties()) { if (propertyWithComplexType.Keys.Contains(jp.Name)) { if (jp.Value.Type != JTokenType.Array) { passed = false; info = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload); break; } else { // Find the property with complex type. List <string> complexProperties = MetadataHelper.GetAllPropertiesNamesOfComplexType(context.MetadataDocument, propertyWithComplexType[jp.Name]); foreach (var jv in ((JArray)jp.Value)) { if (jv.Type != JTokenType.Object) { passed = false; break; } else { foreach (JProperty pro in ((JObject)jv).Properties()) { // Check whether the properties of complex exist in metadata. if (!JsonSchemaHelper.IsAnnotation(pro.Name)) { if (complexProperties.Contains(pro.Name)) { passed = true; } else { passed = false; break; } } } } } if (passed == false) { info = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload); break; } } } } } } return(passed); }
/// <summary> /// Verifies the extension 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"); } bool?passed = null; info = null; bool isDefinedInMetadata = false; bool isAnnotatingProNext = false; bool isAnnotatingProPrevious = false; JObject allobject; context.ResponsePayload.TryToJObject(out allobject); // Access the metadata document and get the node which will be used. string xpath = string.Format(@"//*[local-name()='EntityType']/*[local-name()='Property']", context.EntityTypeShortName); XElement metadata = XElement.Parse(context.MetadataDocument); var propNodesList = metadata.XPathSelectElements(xpath, ODataNamespaceManager.Instance); // If PayloadType is Feed, verify as below, else is Entry. if (context.PayloadType.Equals(RuleEngine.PayloadType.Feed)) { var entries = JsonParserHelper.GetEntries(allobject); foreach (JObject entry in entries) { var jProps = entry.Children(); foreach (JProperty jProp in jProps) { // Whether json property is annotation. if (JsonSchemaHelper.IsAnnotation(jProp.Name) && !jProp.Name.StartsWith("@")) { if (jProp.Name.Contains("@")) { // Parse the annotation name to two parts. string annotatedPro = jProp.Name.Remove(jProp.Name.LastIndexOf("@"), (jProp.Name.Length - jProp.Name.LastIndexOf("@"))); JProperty nextJProperty = ((JProperty)jProp.Next); JProperty previousJProperty = ((JProperty)jProp.Previous); // Compare the navigation properties of navigation links, foreach (var propNode in propNodesList) { if (propNode.Attribute("Name").ToString().Contains(annotatedPro)) { isDefinedInMetadata = true; break; } else { isDefinedInMetadata = false; } } // Whether the property defined in metadata. if (isDefinedInMetadata && nextJProperty != null) { if (nextJProperty.Name.ToString().Equals(annotatedPro)) { if ((nextJProperty.Value.Type == JTokenType.Array) || (nextJProperty.Value.Type != JTokenType.Object)) { isAnnotatingProNext = true; } else if ((nextJProperty.Value.Type == JTokenType.Object)) { if ((context.Version == ODataVersion.V3) && (jProp.Value.ToString().StripOffDoubleQuotes().StartsWith("Edm.Geography") || jProp.Value.ToString().StripOffDoubleQuotes().StartsWith("Edm.Geometry"))) { isAnnotatingProNext = true; } else if ((context.Version == ODataVersion.V4) && (jProp.Value.ToString().StripOffDoubleQuotes().TrimStart('#').StartsWith("Geography") || jProp.Value.ToString().StripOffDoubleQuotes().TrimStart('#').StartsWith("Geometry"))) { isAnnotatingProNext = true; } else { isAnnotatingProNext = false; } } } else if (previousJProperty.Name.ToString().Equals(annotatedPro)) { if ((previousJProperty.Value.Type == JTokenType.Array) || (nextJProperty.Value.Type != JTokenType.Object)) { isAnnotatingProPrevious = true; } else if ((previousJProperty.Value.Type == JTokenType.Object)) { if ((context.Version == ODataVersion.V3) && (jProp.Value.ToString().StripOffDoubleQuotes().StartsWith("Edm.Geography") || jProp.Value.ToString().StripOffDoubleQuotes().StartsWith("Edm.Geometry"))) { isAnnotatingProNext = true; } else if ((context.Version == ODataVersion.V4) && (jProp.Value.ToString().StripOffDoubleQuotes().TrimStart('#').StartsWith("Geography") || jProp.Value.ToString().StripOffDoubleQuotes().TrimStart('#').StartsWith("Geometry"))) { isAnnotatingProNext = true; } else { isAnnotatingProNext = false; } } } // If isAnnotatingProNext or isAnnotatingProPrevious is true, it means the name and value of annotation is not null. if (isAnnotatingProNext || isAnnotatingProPrevious) { passed = true; } else { passed = false; } } } } } } } else { if (allobject != null) { var jProps = allobject.Children(); // New a string to record the annotation name. string recordName = string.Empty; string recordValue = string.Empty; foreach (JProperty jProp in jProps) { // Whether json property is annotation. if (JsonSchemaHelper.IsAnnotation(jProp.Name) && !jProp.Name.StartsWith("@")) { if (jProp.Name.Contains("@")) { // Prase the annotation name to two parts. string annotatedPro = jProp.Name.Remove(jProp.Name.LastIndexOf("@"), (jProp.Name.Length - jProp.Name.LastIndexOf("@"))); JProperty nextJProperty = ((JProperty)jProp.Next); JProperty previousJProperty = ((JProperty)jProp.Previous); // Compare the navigation properties of navigation links, foreach (var propNode in propNodesList) { if (propNode.Attribute("Name").ToString().Contains(annotatedPro)) { isDefinedInMetadata = true; break; } else { isDefinedInMetadata = false; } } // Whether the property defined in metadata. if (isDefinedInMetadata && nextJProperty != null) { if (nextJProperty.Name.ToString().Equals(annotatedPro)) { if ((nextJProperty.Value.Type == JTokenType.Array) || (nextJProperty.Value.Type != JTokenType.Object)) { isAnnotatingProNext = true; } else if ((nextJProperty.Value.Type == JTokenType.Object)) { if ((context.Version == ODataVersion.V3) && (jProp.Value.ToString().StripOffDoubleQuotes().StartsWith("Edm.Geography") || jProp.Value.ToString().StripOffDoubleQuotes().StartsWith("Edm.Geometry"))) { isAnnotatingProNext = true; } else if ((context.Version == ODataVersion.V4) && (jProp.Value.ToString().StripOffDoubleQuotes().TrimStart('#').StartsWith("Geography") || jProp.Value.ToString().StripOffDoubleQuotes().TrimStart('#').StartsWith("Geometry"))) { isAnnotatingProNext = true; } else { isAnnotatingProNext = false; } } } else if (previousJProperty.Name.ToString().Equals(annotatedPro)) { if ((previousJProperty.Value.Type == JTokenType.Array) || (nextJProperty.Value.Type != JTokenType.Object)) { isAnnotatingProPrevious = true; } else if ((previousJProperty.Value.Type == JTokenType.Object)) { if ((context.Version == ODataVersion.V3) && (jProp.Value.ToString().StripOffDoubleQuotes().StartsWith("Edm.Geography") || jProp.Value.ToString().StripOffDoubleQuotes().StartsWith("Edm.Geometry"))) { isAnnotatingProNext = true; } else if ((context.Version == ODataVersion.V4) && (jProp.Value.ToString().StripOffDoubleQuotes().TrimStart('#').StartsWith("Geography") || jProp.Value.ToString().StripOffDoubleQuotes().TrimStart('#').StartsWith("Geometry"))) { isAnnotatingProNext = true; } else { isAnnotatingProNext = false; } } } // If isAnnotatingProNext or isAnnotatingProPrevious is true, it means the name and value of annotation is not null. if (isAnnotatingProNext || isAnnotatingProPrevious) { passed = true; } else { passed = false; } } } } } } } if (passed == false) { info = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload); } return(passed); }
/// <summary> /// Verifies the extension 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"); } bool?passed = true; ExtensionRuleResultDetail detail = new ExtensionRuleResultDetail(this.Name); var payloadFormat = context.ServiceDocument.GetFormatFromPayload(); string[] feeds = ContextHelper.GetFeeds(context.ServiceDocument, payloadFormat).ToArray(); string entitySetName = feeds.First().MapEntitySetURLToEntitySetName(); Uri firstFeedFullUrl = new Uri(string.Format("{0}/{1}", context.DestinationBasePath.TrimEnd('/'), entitySetName)); Response response = WebHelper.Get(firstFeedFullUrl, Constants.V4AcceptHeaderJsonFullMetadata, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, context.RequestHeaders); detail = new ExtensionRuleResultDetail(this.Name, firstFeedFullUrl.AbsoluteUri, "GET", StringHelper.MergeHeaders(Constants.V4AcceptHeaderJsonFullMetadata, context.RequestHeaders), response); if (response != null && response.StatusCode != null) { JObject feed; response.ResponsePayload.TryToJObject(out feed); var entries = JsonParserHelper.GetEntries(feed); foreach (JObject entry in entries) { var jProps = entry.Children(); foreach (JProperty jProp in jProps) { if (JsonSchemaHelper.IsAnnotation(jProp.Name) && jProp.Name.EndsWith("@" + Constants.OdataType) && !jProp.Name.StartsWith("@" + Constants.OdataType)) { string typeValue = jProp.Value.ToString().TrimStart('#'); if (typeValue.Contains("Collection(")) { typeValue = typeValue.Substring(typeValue.IndexOf("(") + 1, typeValue.LastIndexOf(")") - typeValue.IndexOf("(") - 1); } // Don't contains dot means it is primitive value or collection. if (!typeValue.Contains(".")) { if (PrimitiveDataTypes.NonQualifiedTypes.Contains(typeValue)) { passed = true; } else { passed = false; detail.ErrorMessage += string.Format("The type {0} is not defined in OData-CSDL.", typeValue); break; } } } } if (passed == false) // Break to foreach all if anyone of them cannot match the rule { break; } } } else { passed = false; detail.ErrorMessage = string.Format(Constants.ErrorURI, "GET", firstFeedFullUrl.AbsoluteUri, "failed"); } info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail); return(passed); }
/// <summary> /// Get whether the group of annotations of structural or navigation properties stand immediately before the property they annotate. /// </summary> /// <param name="jo">The JSON jobject.</param> /// <param name="navigPropNames">Navigation property name list.</param> /// <param name="normalPropNames">normal structure property name list.</param> /// <param name="payloadType">Feed or entry for the payload type.</param> /// <returns>True: rule pass; false: rule fail.</returns> public bool?AnnotationsImmeBefore(JObject jo, List <string> navigPropNames, List <string> normalPropNames, RuleEngine.PayloadType payloadType) { if (payloadType == RuleEngine.PayloadType.Feed) { bool?result = null; foreach (JObject ob in (JArray)jo[Constants.Value]) { result = AnnotationsImmeBefore(ob, navigPropNames, normalPropNames, RuleEngine.PayloadType.Entry); if (result.HasValue && result.Value == false) { break; } } return(result); } else if (payloadType == RuleEngine.PayloadType.Entry) { bool?result = null; List <string> annotationNamesGroup = new List <string>(); string record = string.Empty; var jProps = jo.Children(); foreach (JProperty jProp in jProps) { if (JsonSchemaHelper.IsAnnotation(jProp.Name)) { if (jProp.Name.Contains("@") && !jProp.Name.StartsWith("@")) { string temp = jProp.Name.Remove(jProp.Name.IndexOf("@"), jProp.Name.Length - jProp.Name.IndexOf("@")); if (navigPropNames.Contains(temp) || normalPropNames.Contains(temp)) { if (string.Empty == record || temp == record) { annotationNamesGroup.Add(jProp.Name); record = temp; } else { annotationNamesGroup.Clear(); annotationNamesGroup.Add(jProp.Name); record = temp; } } } } else { if (annotationNamesGroup.Count > 0) { if (record == jProp.Name) { result = true; } else if (navigPropNames.Contains(record) && normalPropNames.Contains(jProp.Name)) { result = null; } else { result = false; break; } record = string.Empty; annotationNamesGroup.Clear(); } } } return(result); } return(null); }
/// <summary> /// Verifies the extension 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"); } bool?passed = null; info = null; bool isJSONprimitives = false; // Whether odata.type value is namespace- or alias-qualified the instance's type bool isNamespaceValue = false; bool isAliasValue = false; // Use the XPath query language to access the metadata document and get all Namespace value. string xpath = @"//*[local-name()='DataServices']/*[local-name()='Schema']"; List <string> appropriateNamespace = MetadataHelper.GetPropertyValues(context, xpath, "Namespace"); // Get Alias value. List <string> appropriateAlias = MetadataHelper.GetPropertyValues(context, xpath, "Alias"); JObject allobject; context.ResponsePayload.TryToJObject(out allobject); // If PayloadType is Feed, verify as below, eles is Entry. if (context.PayloadType.Equals(RuleEngine.PayloadType.Feed)) { var entries = JsonParserHelper.GetEntries(allobject); foreach (JObject entry in entries) { var jProps = entry.Children(); // New a string to record the annotation name. string record = string.Empty; foreach (JProperty jProp in jProps) { isJSONprimitives = jProp.Value.Type == JTokenType.Integer || jProp.Value.Type == JTokenType.Float || jProp.Value.Type == JTokenType.Bytes || jProp.Value.Type == JTokenType.Boolean || jProp.Value.Type == JTokenType.String; // Whether json property is annotation. if (JsonSchemaHelper.IsAnnotation(jProp.Name)) { record = jProp.Name; } else { if (record == string.Empty) { continue; } else { // Prase the annotation name to two parts. string[] splitedStr = record.Split('@'); // If the string before the sign "@" are the same with annotated name/value pair. And whether JSON arrays or primitives they are placed next to the annotated model construct. if (jProp.Name == splitedStr[0] && (jProp.Value.Type == JTokenType.Array || isJSONprimitives)) { if (appropriateNamespace.Count != 0) { // Verify the annoatation start with namespace. foreach (string currentvalue in appropriateNamespace) { if (jProp.Name.Contains(currentvalue)) { isNamespaceValue = true; } else { isNamespaceValue = false; } } } if (appropriateAlias.Count != 0) { // Verify the annoatation start with alias. foreach (string currentvalue in appropriateAlias) { if (jProp.Name.Contains(currentvalue)) { isAliasValue = true; } else { isAliasValue = false; } } } if (!isNamespaceValue && !isAliasValue) { // Whether the annoatation use odata instead of namespace- or alias-qualified name of the annotation. if (record.Contains(Constants.OdataNS)) { passed = true; record = string.Empty; continue; } else { passed = false; info = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload); break; } } } } } } if (passed == false) { break; } } } else { var jProps = allobject.Children(); // New a string to record the annotation name. string record = string.Empty; foreach (JProperty jProp in jProps) { isJSONprimitives = jProp.Value.Type == JTokenType.Integer || jProp.Value.Type == JTokenType.Float || jProp.Value.Type == JTokenType.Bytes || jProp.Value.Type == JTokenType.Boolean || jProp.Value.Type == JTokenType.String; // Whether json property is annotation. if (JsonSchemaHelper.IsAnnotation(jProp.Name)) { record = jProp.Name; } else { if (record == string.Empty) { continue; } else { // Prase the annotation name to two parts. string[] splitedStr = record.Split('@'); // If the string before the sign "@" are the same with annotated name/value pair. And whether JSON arrays or primitives they are placed next to the annotated model construct. if (jProp.Name == splitedStr[0] && (jProp.Value.Type == JTokenType.Array || isJSONprimitives)) { if (appropriateNamespace.Count != 0) { // Verify the annoatation start with namespace. foreach (string currentvalue in appropriateNamespace) { if (jProp.Name.Contains(currentvalue)) { isNamespaceValue = true; } else { isNamespaceValue = false; } } } if (appropriateAlias.Count != 0) { // Verify the annoatation start with alias. foreach (string currentvalue in appropriateAlias) { if (jProp.Name.Contains(currentvalue)) { isAliasValue = true; } else { isAliasValue = false; } } } if (!isNamespaceValue && !isAliasValue) { // Whether the annoatation use odata instead of namespace- or alias-qualified name of the annotation. if (record.Contains(Constants.OdataNS)) { passed = true; record = string.Empty; continue; } else { passed = false; info = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload); break; } } } } } } } return(passed); }