/// <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> /// 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); }