/// <summary> /// See whether an entity type is defined in one of the schemas in the metadata document. /// </summary> /// <param name="typeFullName">The qualified name of the entity type.</param> /// <param name="document">The document string.</param> /// <returns>True if the entity type is defined in the document, false otherwise.</returns> bool IsEntityTypeDefinedInDoc(string typeFullName, string document) { bool result = false; string typeSimpleName = typeFullName.GetLastSegment(); XElement metaXml = XElement.Parse(document); string xpath = string.Format("//*[local-name()='EntityType' and @Name='{0}']", typeSimpleName); IEnumerable <XElement> types = metaXml.XPathSelectElements(xpath, ODataNamespaceManager.Instance); foreach (XElement type in types) { AliasNamespacePair aliasAndNamespace = MetadataHelper.GetAliasAndNamespace(type); if ( string.Format("{0}.{1}", aliasAndNamespace.Alias, typeSimpleName) == typeFullName || string.Format("{0}.{1}", aliasAndNamespace.Namespace, typeSimpleName) == typeFullName ) { result = true; break; } } return(result); }
/// <summary> /// Verify Metadata.Core.4564 /// </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; XElement metaXml = XElement.Parse(context.MetadataDocument); string xpath = string.Format(@"//*[local-name()='Schema']"); XElement element = metaXml.XPathSelectElement(xpath, ODataNamespaceManager.Instance); AliasNamespacePair aliasNameSpace = MetadataHelper.GetAliasAndNamespace(element); // Load MetadataDocument into XMLDOM XmlDocument xmlDoc = new XmlDocument(); xmlDoc.LoadXml(context.MetadataDocument); List <string> typeDefinitionNames = MetadataHelper.GetNamesOfTypeDefinitionByUnderlyingType(context.MetadataDocument, "Edm.Stream"); List <string> qualifiedTypes = new List <string>(); foreach (string underlyingType in typeDefinitionNames) { if (!string.IsNullOrEmpty(aliasNameSpace.Alias)) { qualifiedTypes.Add(aliasNameSpace.Alias + "." + underlyingType); } if (!string.IsNullOrEmpty(aliasNameSpace.Namespace)) { qualifiedTypes.Add(aliasNameSpace.Namespace + "." + underlyingType); } } qualifiedTypes.Add("Edm.Stream"); foreach (string type in qualifiedTypes) { // Find all collection that uses Edm.Stream as core type or underlying type. xpath = string.Format("//*[@Type = 'Collection({0})']", type); XmlNodeList propertyNodeList = xmlDoc.SelectNodes(xpath); if (propertyNodeList.Count == 0) { passed = true; } else { passed = false; info = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload); break; } // Find non-binding parameter that uses Edm.Stream as type or underlying type. xpath = string.Format("//*[local-name()='Parameter' and @Type='{0}']", type); propertyNodeList = xmlDoc.SelectNodes(xpath); if (propertyNodeList.Count == 0) { passed = true; } else { passed = false; info = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload); break; } } return(passed); }
/// <summary> /// Verify Metadata.Core.4204 /// </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()='Reference']"; XmlNodeList refNodeList = xmlDoc.SelectNodes(xpath); // Add all included reference namespace alias pair in aliasNamespacePairList. foreach (XmlNode reference in refNodeList) { foreach (XmlNode child in reference.ChildNodes) { if (child.Attributes == null) { continue; // the comment nodes do not contain Attributes collection. } if (child.Name.Equals("edmx:Include")) { string namespaceString = string.Empty; string aliasString = string.Empty; if (child.Attributes == null) { continue; // the comment nodes do not contain Attributes collection. } if (child.Attributes["Namespace"] != null) { namespaceString = child.Attributes["Namespace"].Value; } if (child.Attributes["Alias"] != null) { aliasString = child.Attributes["Alias"].Value; } AliasNamespacePair referenceAliasNamespace = new AliasNamespacePair(aliasString, namespaceString); aliasNamespacePairList.Add(referenceAliasNamespace); } } } XElement metaXml = XElement.Parse(context.MetadataDocument); xpath = "//*[local-name()='ComplexType']"; IEnumerable <XElement> complexTypeElements = metaXml.XPathSelectElements(xpath, ODataNamespaceManager.Instance); foreach (XElement complexTypeElement in complexTypeElements) { passed = true; HashSet <string> descendantsSet = new HashSet <string>(StringComparer.Ordinal); AliasNamespacePair aliasNameSpace = complexTypeElement.GetAliasAndNamespace(); if (!string.IsNullOrEmpty(aliasNameSpace.Namespace)) { descendantsSet.Add(aliasNameSpace.Namespace + "." + complexTypeElement.Attribute("Name").Value); } if (!string.IsNullOrEmpty(aliasNameSpace.Alias)) { descendantsSet.Add(aliasNameSpace.Alias + "." + complexTypeElement.Attribute("Name").Value); } if (!aliasNamespacePairList.Contains(aliasNameSpace)) { aliasNamespacePairList.Add(aliasNameSpace); } if (this.IsComplextTypeBaseDeadCycled(complexTypeElement, context, ref descendantsSet)) { passed = true; } else { passed = false; info = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload); break; } } return(passed); }
/// <summary> /// Verify Metadata.Core.4561 /// </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); List <string> xPathTypes = new List <string>() { "//*[@Type]", "//*[@BaseType]", "//*[@UnderlyingType]", "//*[@EntityType]", }; List <string> xPathTypesContainPrefix = new List <string> () { "//*[starts-with(@Type,'{0}')]", "//*[starts-with(@BaseType,'{0}')]", "//*[starts-with(@UnderlyingType,'{0}')]", "//*[starts-with(@EntityType,'{0}')]", }; XElement metaXml = XElement.Parse(context.MetadataDocument); string xpath = string.Format(@"//*[local-name()='Schema']"); IEnumerable <XElement> schemaElements = metaXml.XPathSelectElements(xpath, ODataNamespaceManager.Instance); List <string> qualifiedNamePrefixes = new List <string>() { "Edm.", "Collection(Edm." }; foreach (XElement element in schemaElements) { AliasNamespacePair aliasNameSpace = MetadataHelper.GetAliasAndNamespace(element); if (!string.IsNullOrEmpty(aliasNameSpace.Alias)) { qualifiedNamePrefixes.Add(aliasNameSpace.Alias + "."); qualifiedNamePrefixes.Add("Collection(" + aliasNameSpace.Alias + "."); } if (!string.IsNullOrEmpty(aliasNameSpace.Namespace)) { qualifiedNamePrefixes.Add(aliasNameSpace.Namespace + "."); qualifiedNamePrefixes.Add("Collection(" + aliasNameSpace.Namespace + "."); } } // Add the namespace and alias of the references. xpath = "//*[local-name()='Reference']"; XmlNodeList refNodeList = xmlDoc.SelectNodes(xpath); foreach (XmlNode reference in refNodeList) { foreach (XmlNode child in reference.ChildNodes) { if (child.Name.Equals("edmx:Include")) { if (child.Attributes["Alias"] != null) { qualifiedNamePrefixes.Add(child.Attributes["Alias"].Value + "."); qualifiedNamePrefixes.Add("Collection(" + child.Attributes["Alias"].Value + "."); } if (child.Attributes["Namespace"] != null) { qualifiedNamePrefixes.Add(child.Attributes["Namespace"].Value + "."); qualifiedNamePrefixes.Add("Collection(" + child.Attributes["Namespace"].Value + "."); } } } } for (int i = 0; i < 4; i++) { string xPathForType = xPathTypes[i]; XmlNodeList typeNodeList = xmlDoc.SelectNodes(xPathForType); int typeCount = typeNodeList.Count; int sum = 0; foreach (string qualifiedNamePrefix in qualifiedNamePrefixes) { string xPathfull = string.Format(xPathTypesContainPrefix[i], qualifiedNamePrefix); XmlNodeList containsPrefixNodeList = xmlDoc.SelectNodes(xPathfull); sum += containsPrefixNodeList.Count; } if (typeCount == sum) { passed = true; } else { passed = false; info = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload); break; } } return(passed); }