/// <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 segments = ResourcePathHelper.GetPathSegments(context).ToArray(); var edmxHelper = new EdmxHelper(XElement.Parse(context.MetadataDocument)); UriType uriType; var target = edmxHelper.GetTargetType(segments, out uriType); if (uriType == UriType.URI4 || uriType == UriType.URI5) { passed = false; string targetType = ((EdmProperty)target).TypeUsage.EdmType.FullName; string property = segments.LastOrDefault(s => !s.StartsWith("$")); JObject jo = JObject.Parse(context.ResponsePayload); var inner = jo.ReachInnerToken(); if (inner.Type == JTokenType.Object) { JObject innerObj = (JObject)inner; if (innerObj.Properties() != null && innerObj.Properties().Count() == 1) { var value = innerObj.Properties().First().Value; string valueLiteral = value.ToString(); IEdmType type = EdmTypeManager.GetEdmType(targetType); bool isValidJsonData = type.IsGoodInJsonWith(valueLiteral); if (isValidJsonData) { passed = true; } else { // target type may allow null //TODO: allow null only when the target type is nullable passed = valueLiteral.Equals("null", StringComparison.Ordinal); } } } } if (passed.HasValue && !passed.Value) { info = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload, -1); } return(passed); }