private void ParseUriAndVerify( Uri uri, Action <ODataPath, FilterClause, OrderByClause, SelectExpandClause, IDictionary <string, SingleValueNode> > verifyAction) { // run 2 test passes: // 1. low level api - ODataUriParser instance methods { List <CustomQueryOptionToken> queries = UriUtils.ParseQueryOptions(uri); ODataUriParser parser = new ODataUriParser(HardCodedTestModel.TestModel, new Uri("http://gobbledygook/"), uri); ODataPath path = parser.ParsePath(); IEdmNavigationSource entitySource = ResolveEntitySource(path); IEdmEntitySet entitySet = entitySource as IEdmEntitySet; var dic = queries.ToDictionary(customQueryOptionToken => customQueryOptionToken.Name, customQueryOptionToken => queries.GetQueryOptionValue(customQueryOptionToken.Name)); ODataQueryOptionParser queryOptionParser = new ODataQueryOptionParser(HardCodedTestModel.TestModel, entitySet.EntityType(), entitySet, dic) { Configuration = { ParameterAliasValueAccessor = parser.ParameterAliasValueAccessor } }; FilterClause filterClause = queryOptionParser.ParseFilter(); SelectExpandClause selectExpandClause = queryOptionParser.ParseSelectAndExpand(); OrderByClause orderByClause = queryOptionParser.ParseOrderBy(); // Two parser should share same ParameterAliasNodes verifyAction(path, filterClause, orderByClause, selectExpandClause, parser.ParameterAliasNodes); verifyAction(path, filterClause, orderByClause, selectExpandClause, queryOptionParser.ParameterAliasNodes); } //2. high level api - ParseUri { ODataUriParser parser = new ODataUriParser(HardCodedTestModel.TestModel, new Uri("http://gobbledygook/"), uri); verifyAction(parser.ParsePath(), parser.ParseFilter(), parser.ParseOrderBy(), parser.ParseSelectAndExpand(), parser.ParameterAliasNodes); } }
/// <summary> /// Build an ODataUriParser /// </summary> /// <param name="model">Model to use for metadata binding.</param> /// <param name="fullUri">full Uri to be parsed, it should be a relative Uri.</param> public ODataUriParser(IEdmModel model, Uri fullUri) { ExceptionUtils.CheckArgumentNotNull(fullUri, "fullUri"); if (fullUri.IsAbsoluteUri) { throw new ODataException(Strings.UriParser_FullUriMustBeRelative); } this.configuration = new ODataUriParserConfiguration(model); this.fullUri = fullUri; this.queryOptions = UriUtils.ParseQueryOptions(UriUtils.CreateMockAbsoluteUri(this.fullUri)); }
/// <summary> /// Build an ODataUriParser /// </summary> /// <param name="model">Model to use for metadata binding.</param> /// <param name="serviceRoot">Absolute URI of the service root.</param> /// <param name="fullUri">full Uri to be parsed</param> public ODataUriParser(IEdmModel model, Uri serviceRoot, Uri fullUri) { ExceptionUtils.CheckArgumentNotNull(fullUri, "fullUri"); if (serviceRoot == null) { throw new ODataException(ODataErrorStrings.UriParser_NeedServiceRootForThisOverload); } if (!serviceRoot.IsAbsoluteUri) { throw new ODataException(ODataErrorStrings.UriParser_UriMustBeAbsolute(serviceRoot)); } this.configuration = new ODataUriParserConfiguration(model); this.serviceRoot = Core.UriUtils.EnsureTaillingSlash(serviceRoot); this.fullUri = fullUri.IsAbsoluteUri ? fullUri : Core.UriUtils.UriToAbsoluteUri(this.ServiceRoot, fullUri); this.queryOptions = UriUtils.ParseQueryOptions(this.fullUri); }
/// <summary> /// Parses the <paramref name="queryUri"/> and returns a new instance of <see cref="SyntacticTree"/> /// describing the query specified by the uri. /// </summary> /// <param name="queryUri">The absolute URI which holds the query to parse. This must be a path relative to the <paramref name="serviceBaseUri"/>.</param> /// <param name="serviceBaseUri">The base URI of the service.</param> /// <param name="maxDepth">The maximum depth of any single query part. Security setting to guard against DoS attacks causing stack overflows and such.</param> /// <returns>A new instance of <see cref="SyntacticTree"/> which represents the query specified in the <paramref name="queryUri"/>.</returns> public static SyntacticTree ParseUri(Uri queryUri, Uri serviceBaseUri, int maxDepth) { ExceptionUtils.CheckArgumentNotNull(queryUri, "queryUri"); if (!queryUri.IsAbsoluteUri) { throw new ArgumentException(Strings.SyntacticTree_UriMustBeAbsolute(queryUri), "queryUri"); } ExceptionUtils.CheckArgumentNotNull(serviceBaseUri, "serviceBaseUri"); if (!serviceBaseUri.IsAbsoluteUri) { throw new ArgumentException(Strings.SyntacticTree_UriMustBeAbsolute(serviceBaseUri), "serviceBaseUri"); } if (maxDepth <= 0) { throw new ArgumentException(Strings.SyntacticTree_MaxDepthInvalid, "maxDepth"); } UriPathParser pathParser = new UriPathParser(maxDepth); var path = pathParser.ParsePathIntoSegments(queryUri, serviceBaseUri); // COMPAT 32: Differencies in query options parsing in WCF DS // // We allow non-system $ query options in the lexical space. // We allow multiple instances of a custom or non-system $ query option in the lexical space. // TODO: we need to decide whether we want to allow multiple system $ query options with the same name (OIPI suggests that this is valid); we currently don't. List <CustomQueryOptionToken> queryOptions = UriUtils.ParseQueryOptions(queryUri); IDictionary <string, string> parameterAliases = queryOptions.GetParameterAliases(); QueryToken filter = null; string filterQuery = queryOptions.GetQueryOptionValueAndRemove(UriQueryConstants.FilterQueryOption); if (filterQuery != null) { UriQueryExpressionParser expressionParser = new UriQueryExpressionParser(maxDepth); filter = expressionParser.ParseFilter(filterQuery); } IEnumerable <OrderByToken> orderByTokens = null; string orderByQuery = queryOptions.GetQueryOptionValueAndRemove(UriQueryConstants.OrderByQueryOption); if (orderByQuery != null) { UriQueryExpressionParser expressionParser = new UriQueryExpressionParser(maxDepth); orderByTokens = expressionParser.ParseOrderBy(orderByQuery); } SelectToken select = null; string selectQuery = queryOptions.GetQueryOptionValueAndRemove(UriQueryConstants.SelectQueryOption); if (selectQuery != null) { SelectExpandParser selectParser = new SelectExpandParser(selectQuery, ODataUriParserSettings.DefaultSelectExpandLimit); select = selectParser.ParseSelect(); } ExpandToken expand = null; string expandQuery = queryOptions.GetQueryOptionValueAndRemove(UriQueryConstants.ExpandQueryOption); if (expandQuery != null) { SelectExpandParser expandParser = new SelectExpandParser(expandQuery, ODataUriParserSettings.DefaultSelectExpandLimit); expand = expandParser.ParseExpand(); } int? skip = null; string skipQuery = queryOptions.GetQueryOptionValueAndRemove(UriQueryConstants.SkipQueryOption); if (skipQuery != null) { int skipValue; if (!UriPrimitiveTypeParser.TryUriStringToNonNegativeInteger(skipQuery, out skipValue)) { throw new ODataException(Strings.SyntacticTree_InvalidSkipQueryOptionValue(skipQuery)); } skip = skipValue; } int? top = null; string topQuery = queryOptions.GetQueryOptionValueAndRemove(UriQueryConstants.TopQueryOption); if (topQuery != null) { int topValue; if (!UriPrimitiveTypeParser.TryUriStringToNonNegativeInteger(topQuery, out topValue)) { throw new ODataException(Strings.SyntacticTree_InvalidTopQueryOptionValue(topQuery)); } top = topValue; } string countQuery = queryOptions.GetQueryOptionValueAndRemove(UriQueryConstants.CountQueryOption); bool? count = ParseQueryCount(countQuery); string format = queryOptions.GetQueryOptionValueAndRemove(UriQueryConstants.FormatQueryOption); return(new SyntacticTree( parameterAliases, path, filter, orderByTokens, select, expand, skip, top, count, format, queryOptions.Count == 0 ? null : new ReadOnlyCollection <CustomQueryOptionToken>(queryOptions))); }
/// <summary> /// Parses the <paramref name="queryUri"/> and returns a new instance of <see cref="SyntacticTree"/> /// describing the query specified by the uri. /// </summary> /// <param name="queryUri">The absolute URI which holds the query to parse. This must be a path relative to the <paramref name="serviceBaseUri"/>.</param> /// <param name="serviceBaseUri">The base URI of the service.</param> /// <param name="maxDepth">The maximum depth of any single query part. Security setting to guard against DoS attacks causing stack overflows and such.</param> /// <returns>A new instance of <see cref="SyntacticTree"/> which represents the query specified in the <paramref name="queryUri"/>.</returns> public static SyntacticTree ParseUri(Uri queryUri, Uri serviceBaseUri, int maxDepth) { ExceptionUtils.CheckArgumentNotNull(queryUri, "queryUri"); if (!queryUri.IsAbsoluteUri) { throw new ArgumentException(Strings.SyntacticTree_UriMustBeAbsolute(queryUri), "queryUri"); } ExceptionUtils.CheckArgumentNotNull(serviceBaseUri, "serviceBaseUri"); if (!serviceBaseUri.IsAbsoluteUri) { throw new ArgumentException(Strings.SyntacticTree_UriMustBeAbsolute(serviceBaseUri), "serviceBaseUri"); } if (maxDepth <= 0) { throw new ArgumentException(Strings.SyntacticTree_MaxDepthInvalid, "maxDepth"); } UriPathParser pathParser = new UriPathParser(maxDepth); var path = pathParser.ParsePathIntoSegments(queryUri, serviceBaseUri); List <CustomQueryOptionToken> queryOptions = UriUtils.ParseQueryOptions(queryUri); IDictionary <string, string> parameterAliases = queryOptions.GetParameterAliases(); QueryToken filter = null; string filterQuery = queryOptions.GetQueryOptionValueAndRemove(UriQueryConstants.FilterQueryOption); if (filterQuery != null) { UriQueryExpressionParser expressionParser = new UriQueryExpressionParser(maxDepth); filter = expressionParser.ParseFilter(filterQuery); } IEnumerable <OrderByToken> orderByTokens = null; string orderByQuery = queryOptions.GetQueryOptionValueAndRemove(UriQueryConstants.OrderByQueryOption); if (orderByQuery != null) { UriQueryExpressionParser expressionParser = new UriQueryExpressionParser(maxDepth); orderByTokens = expressionParser.ParseOrderBy(orderByQuery); } SelectToken select = null; string selectQuery = queryOptions.GetQueryOptionValueAndRemove(UriQueryConstants.SelectQueryOption); if (selectQuery != null) { SelectExpandParser selectParser = new SelectExpandParser(selectQuery, ODataUriParserSettings.DefaultSelectExpandLimit); select = selectParser.ParseSelect(); } ExpandToken expand = null; string expandQuery = queryOptions.GetQueryOptionValueAndRemove(UriQueryConstants.ExpandQueryOption); if (expandQuery != null) { SelectExpandParser expandParser = new SelectExpandParser(expandQuery, ODataUriParserSettings.DefaultSelectExpandLimit); expand = expandParser.ParseExpand(); } int? skip = null; string skipQuery = queryOptions.GetQueryOptionValueAndRemove(UriQueryConstants.SkipQueryOption); if (skipQuery != null) { int skipValue; if (!UriPrimitiveTypeParser.TryUriStringToNonNegativeInteger(skipQuery, out skipValue)) { throw new ODataException(Strings.SyntacticTree_InvalidSkipQueryOptionValue(skipQuery)); } skip = skipValue; } int? top = null; string topQuery = queryOptions.GetQueryOptionValueAndRemove(UriQueryConstants.TopQueryOption); if (topQuery != null) { int topValue; if (!UriPrimitiveTypeParser.TryUriStringToNonNegativeInteger(topQuery, out topValue)) { throw new ODataException(Strings.SyntacticTree_InvalidTopQueryOptionValue(topQuery)); } top = topValue; } string countQuery = queryOptions.GetQueryOptionValueAndRemove(UriQueryConstants.CountQueryOption); bool? count = QueryTokenUtils.ParseQueryCount(countQuery); string format = queryOptions.GetQueryOptionValueAndRemove(UriQueryConstants.FormatQueryOption); return(new SyntacticTree( parameterAliases, path, filter, orderByTokens, select, expand, skip, top, count, format, queryOptions.Count == 0 ? null : new ReadOnlyCollection <CustomQueryOptionToken>(queryOptions))); }