/// <summary> /// Verify Common.Core.4015 /// </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 (context.ResponseHttpHeaders.Contains(context.Version == ODataVersion.V4 ? Constants.V4OdataStreaming : Constants.OdataStreaming) && context.Destination.Query.Contains(@"$expand=")) { List <XElement> props = MetadataHelper.GetAllPropertiesOfEntity(context.MetadataDocument, context.EntityTypeShortName, MatchPropertyType.Navigations); List <string> navigPropNames = new List <string>(); foreach (var prop in props) { navigPropNames.Add(prop.Attribute("Name").Value); } JObject jObj; context.ResponsePayload.TryToJObject(out jObj); if (jObj != null && jObj.Type == JTokenType.Object) { var jProps = jObj.Children(); foreach (JProperty j in jProps) { if (navigPropNames.Contains(j.Name) && j.Value.Type == JTokenType.Array) { //string uri = context.DestinationBasePath + "/" + j.Name + @"/$count"; string uri = VerificationHelper.BuildURL(context.DestinationBasePath, j.Name + @"/$count"); Response resp = WebHelper.Get(uri, null, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, context.RequestHeaders); passed = null; if ((j.Value as JArray).Count < Convert.ToInt32(resp.ResponsePayload)) { if ((j.Next as JProperty).Name == (ODataVersion.V4 == context.Version ? Constants.V4OdataNextLink : Constants.OdataNextLink)) { passed = true; } else { passed = false; info = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload); break; } } } } } } return(passed); }