/// <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; // run the rng rule if $inlinecount=allpages is part of query string of target uri var q = context.Destination.Query; var qs = HttpUtility.ParseQueryString(q); var v = qs["$inlinecount"]; if (v != null && v.Equals("allpages", StringComparison.Ordinal)) { var rngSchema = string.Format(FeedCore2005.rngSchemaFormat, 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); } } 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; XElement meta = XElement.Parse(context.MetadataDocument); XElement entry = XElement.Parse(context.ResponsePayload); string xpath = string.Format(".//*[local-name()='EntityType' and @Name='{0}']/*[local-name()='Property' and @Name and @m:FC_TargetPath]", context.EntityTypeShortName); var mappedProperties = meta.XPathSelectElements(xpath, ODataNamespaceManager.Instance); foreach (var mp in mappedProperties) { var custFeedProperty = new EntryCore2012CFP(mp, entry); string schema = custFeedProperty.GetRngSchema(); RngVerifier verifier = new RngVerifier(schema); 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 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 atom:entry[@m:etag] is there, ensure its value equals to ETag header value XElement entry; context.ResponsePayload.TryToXElement(out entry); bool etagInPlace = entry.Attribute("{http://docs.oasis-open.org/odata/ns/edm/dataservices/metadata}etag") != null; if (etagInPlace) { var etagInHeader = context.ResponseHttpHeaders.GetHeaderValue("ETag"); string rngSchema = string.Format(EntryCore2005.rngSchemaFormat, HttpUtility.HtmlEncode(etagInHeader)); 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); } } 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; //1-get the data service namespace name (try 1st property?) string dsns = ResourcePathHelper.GetDataServiceNamespace(XElement.Parse(context.ResponsePayload)); //2-get names of the properties of the involved entity type // ensure they are all unique to protect from repetitive type inheritance declarations in metadata documents string[] propertyNames = XmlHelper.GetProperties(context.MetadataDocument, context.EntityTypeShortName).Distinct().ToArray(); if (context.Projection) { List <string> aa = new List <string>(); var queries = HttpUtility.ParseQueryString(context.Destination.Query); var qSelect = queries["$select"]; var selects = qSelect.Split(new char[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries); foreach (var sel in selects) { var propName = propertyNames.FirstOrDefault(x => sel.Equals(x, StringComparison.OrdinalIgnoreCase)); if (!string.IsNullOrEmpty(propName)) { aa.Add(propName); } } propertyNames = aa.ToArray(); } //3-craft the rng StringBuilder sb = new StringBuilder(); foreach (var p in propertyNames) { sb.AppendFormat(rngProperty, p); } string schema = string.Format(rngSchema, dsns, sb.ToString()); //4-surrender it under rng validator RngVerifier verifier = new RngVerifier(schema); TestResult result; passed = verifier.Verify(context, out result); if (passed.Value) { info = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload, result.LineNumberInError); } 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 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 = true; info = null; // to check this rule only when request URI if os URI7, and about set of links (not single link) bool isCheckingTarget = false; bool isNullable = false; var edmxHelper = new EdmxHelper(XElement.Parse(context.MetadataDocument)); var segments = ResourcePathHelper.GetPathSegments(context); UriType uriType; var target = edmxHelper.GetTargetType(segments, out uriType); if (uriType == UriType.URI7) { // safe to convert since s must be a RelationshipEndMember var targetRelationEndMember = (RelationshipEndMember)target; isCheckingTarget = targetRelationEndMember.RelationshipMultiplicity == RelationshipMultiplicity.One || targetRelationEndMember.RelationshipMultiplicity == RelationshipMultiplicity.ZeroOrOne; isNullable = targetRelationEndMember.RelationshipMultiplicity == RelationshipMultiplicity.ZeroOrOne; } if (isCheckingTarget) { string rngSchema = string.Format(isNullable ? rngFormat_nullable : rngFormat_one, 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); } } 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 value of attribute of @href of node feed/link[@rel='self'] var xpath = "/atom:link[@rel='self' and @href]"; XElement feed; context.ResponsePayload.TryToXElement(out feed); var selfLink = feed.XPathSelectElement(xpath, ODataNamespaceManager.Instance); if (selfLink != null) { var href = selfLink.GetAttributeValue("href"); // consider the effect of xml:base in scope string xBase = selfLink.GetAttributeValue("xml:base", ODataNamespaceManager.Instance); if (string.IsNullOrEmpty(xBase)) { xBase = feed.GetAttributeValue("xml:base", ODataNamespaceManager.Instance); } var targetFull = context.DestinationBasePath; var targetRelative = (string.IsNullOrEmpty(xBase)) ? targetFull : targetFull.Substring(xBase.Length); var rngSchema = string.Format(FeedCore2004.rngSchemaFormat, HttpUtility.HtmlEncode(targetFull), HttpUtility.HtmlEncode(targetRelative), 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); } } 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; XElement meta; context.MetadataDocument.TryToXElement(out meta); string xpath = string.Format("//*[local-name()='EntityType' and @Name='{0}' and @m:HasStream='true']/*[local-name()='Property' and @ConcurrencyMode='Fixed']", context.EntityTypeShortName); bool IsConcurrentMle = meta.XPathSelectElement(xpath, ODataNamespaceManager.Instance) != null; if (IsConcurrentMle) { // get ETag header value of the media resource XElement entry; context.ResponsePayload.TryToXElement(out entry); var m = entry.XPathSelectElement("//atom:link[@rel='edit-media' and @href]", ODataNamespaceManager.Instance); var targetMedia = context.ServiceBaseUri.OriginalString.TrimEnd('/') + @"/" + m.GetAttributeValue("href"); var etag = WebResponseHelper.GetETagOfEntry(targetMedia, Constants.AcceptHeaderAtom); string rngSchema = string.Format(EntryCore2004.rngSchemaFormat, HttpUtility.HtmlEncode(etag)); 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); } } 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); if (uriType == UriType.URI3) { XElement meta = XElement.Parse(context.MetadataDocument); string targetType = ((EdmProperty)target).TypeUsage.EdmType.FullName; var complexType = ResourcePathHelper.GetComplexType(targetType, meta); if (complexType != null) { XElement payload = XElement.Parse(context.ResponsePayload); string schema = GetRngSchema(ResourcePathHelper.GetBaseName(targetType), payload.Name.NamespaceName); RngVerifier verifier = new RngVerifier(schema); TestResult result; passed = verifier.Verify(context, out result); if (passed.HasValue && !passed.Value) { info = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload, result.LineNumberInError); } } } 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 = false; info = null; RngVerifier verifier = new RngVerifier(EntryCore2003_NoMeta.rngSchema); TestResult result; passed = verifier.Verify(context, out result); if (!passed) { info = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload, result.LineNumberInError); } 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 rule logic /// </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 list of navigation properties of the interesting entity type var edmxHelper = new EdmxHelper(XElement.Parse(context.MetadataDocument)); EntityType et; edmxHelper.TryGetItem(context.EntityTypeFullName, out et); var navProps = et.NavigationProperties.Select(x => x.Name); // find out the data service namespace; falling back the implcit one if none exists string dsns = ResourcePathHelper.GetDataServiceNamespace(XElement.Parse(context.ResponsePayload)); // get the relaxNG schema and verify the payload var rngNavLinks = navProps.Select(x => string.Format(tmplRngNavLink, dsns, x)); var rng = string.Format(tmplRngSchema, string.Join(string.Empty, rngNavLinks), RngCommonPattern.CommonPatterns); RngVerifier verifier = new RngVerifier(rng); TestResult result; passed = verifier.Verify(context, out result); if (!passed.Value) { info = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload, result.LineNumberInError); } 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; // if entry in the feed has @m:etag, check @m:etag value is the same as ETag header value if single entry were represented. const string xpath = "//*[local-name()='entry' and @m:etag]"; XElement feed; context.ResponsePayload.TryToXElement(out feed); var x = feed.XPathSelectElements(xpath, ODataNamespaceManager.Instance); foreach (var e in x) { var href = e.XPathSelectElement("atom:id", ODataNamespaceManager.Instance); var target = href.Value; // get the ETag header value for the entry var etag = WebResponseHelper.GetETagOfEntry(target, Constants.AcceptHeaderAtom); var rngSchema = string.Format(FeedCore2003.rngSchemaFormat, HttpUtility.HtmlEncode(etag), HttpUtility.HtmlEncode(target), 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); }