/// <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 = null; //success is implied; otherwise OData error payload would have been received //apply rule when URI path points to a single entity, properties of an entity or Media Resource var edmxHelper = new EdmxHelper(XElement.Parse(context.MetadataDocument)); var segments = ResourcePathHelper.GetPathSegments(context); UriType uriType; var target = edmxHelper.GetTargetType(segments, out uriType); bool IsUriPathApplicable = uriType == UriType.URI2 || uriType == UriType.URI3 || uriType == UriType.URI4 || uriType == UriType.URI5 || uriType == UriType.URI10 || uriType == UriType.URI17; if (IsUriPathApplicable) { string entityName = ResourcePathHelper.GetEntityName(context); string concurrencyProperty = ResourcePathHelper.GetConcurrencyProperty(XElement.Parse(context.MetadataDocument), entityName); if (concurrencyProperty != null) { //to check the existence of ETag header var etagInHeader = context.ResponseHttpHeaders.GetHeaderValue("ETag"); passed = etagInHeader != null; if (!passed.Value) { info = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, string.Empty); } } } 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 = null; //to apply rule when payload has ETag header var etagInHeader = context.ResponseHttpHeaders.GetHeaderValue("ETag"); if (etagInHeader != null) { var valueInHeader = GetETagValueCore(etagInHeader.Trim()); string entityName = ResourcePathHelper.GetEntityName(context); string concurrencyProperty = ResourcePathHelper.GetConcurrencyProperty(XElement.Parse(context.MetadataDocument), entityName); if (concurrencyProperty != null) { string valueInEntry = null; //to get the concurrency token for the entity switch (context.PayloadFormat) { case RuleEngine.PayloadFormat.Atom: case RuleEngine.PayloadFormat.Xml: valueInEntry = GetProperty(XElement.Parse(context.ResponsePayload), concurrencyProperty); if (valueInEntry == null) { valueInEntry = GetRawValueOfProperty(context, concurrencyProperty, context); } break; case RuleEngine.PayloadFormat.Json: JObject jo = JObject.Parse(context.ResponsePayload); valueInEntry = GetProperty(jo, concurrencyProperty); if (valueInEntry == null) { valueInEntry = GetRawValueOfProperty(context, concurrencyProperty, context); } break; case RuleEngine.PayloadFormat.Other: { var edmxHelper = new EdmxHelper(XElement.Parse(context.MetadataDocument)); var segments = ResourcePathHelper.GetPathSegments(context); var segs = ResourcePathHelper.GetEntryUriSegments(segments.Take(segments.Count() - 1), edmxHelper); Uri uriEntry = new Uri(context.ServiceBaseUri, string.Join("/", segs) + "/"); Uri uriConcurrencyValue = new Uri(uriEntry, concurrencyProperty + "/$value"); if (context.Destination == uriConcurrencyValue) { valueInEntry = context.ResponsePayload; } else { valueInEntry = GetProperty(uriEntry, concurrencyProperty, context); } } break; } if (valueInEntry != null) { passed = valueInEntry == valueInHeader; } } } if (passed.HasValue && !passed.Value) { info = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, etagInHeader); } return(passed); }