/// <summary> /// The entry point of this validator class. Use this method to validate the FilterQueryOption /// </summary> public virtual void Validate(FilterQueryOption filterQueryOption, ODataValidationSettings settings) { if (filterQueryOption == null) { throw Error.ArgumentNull("filterQueryOption"); } if (settings == null) { throw Error.ArgumentNull("settings"); } ValidateQueryNode(filterQueryOption.FilterClause.Expression, settings); }
/// <summary> /// Returns a lambda expresion representing the filter /// </summary> /// <typeparam name="T"></typeparam> /// <param name="filterOption"></param> /// <returns></returns> public static Expression <Func <T, bool> > ToFilterExpression <T>(this FilterQueryOption filterOption, HandleNullPropagationOption handleNullPropagation = HandleNullPropagationOption.Default) { if (filterOption == null) { return(null); } IQueryable queryable = Enumerable.Empty <T>().AsQueryable(); queryable = filterOption.ApplyTo(queryable, new ODataQuerySettings() { HandleNullPropagation = handleNullPropagation }); MethodCallExpression whereMethodCallExpression = (MethodCallExpression)queryable.Expression; return((Expression <Func <T, bool> >)(whereMethodCallExpression.Arguments[1].Unquote() as LambdaExpression)); }
/// <summary> /// Validates a <see cref="FilterQueryOption" />. /// </summary> /// <param name="filterQueryOption">The $filter query.</param> /// <param name="settings">The validation settings.</param> /// <remarks> /// Please note this method is not thread safe. /// </remarks> public virtual void Validate(FilterQueryOption filterQueryOption, ODataValidationSettings settings) { if (filterQueryOption == null) { throw Error.ArgumentNull("filterQueryOption"); } if (settings == null) { throw Error.ArgumentNull("settings"); } _currentAnyAllExpressionDepth = 0; _currentNodeCount = 0; ValidateQueryNode(filterQueryOption.FilterClause.Expression, settings); }
public ODataQueryOptions(IEnumerable <KeyValuePair <string, string> > queryParameters, ODataQueryContext context, bool aggregate) { if (queryParameters == null) { throw new ArgumentNullException(nameof(queryParameters)); } foreach (var queryParameter in queryParameters) { switch (queryParameter.Key) { case "$filter": if (!aggregate) { Filter = new FilterQueryOption(queryParameter.Value, context); } break; case "$orderby": OrderBy = new OrderByQueryOption(queryParameter.Value, context); break; case "$select": if (aggregate) { Select = new SelectExpandQueryOption(queryParameter.Value, string.Empty, context); } break; case "$top": Top = new TopQueryOption(queryParameter.Value, context); break; case "$format": break; default: throw new ArgumentException($"'{queryParameter.Key}' option is not supported"); } } if (Top == null || Top.Value > MaxTop) { Top = new TopQueryOption($"{MaxTop}", context); } }
public void ValidateVisitLogicalOperatorEqual() { // Arrange FilterQueryOption option = new FilterQueryOption("Id eq 1", _context); // Act _validator.Validate(option, _settings); // Assert Assert.Equal(6, _validator.Times.Keys.Count); Assert.Equal(1, _validator.Times["Validate"]); // entry Assert.Equal(1, _validator.Times["ValidateSingleValuePropertyAccessNode"]); // Id Assert.Equal(1, _validator.Times["ValidateLogicalOperator"]); // eq Assert.Equal(1, _validator.Times["ValidateConstantQueryNode"]); // 1 Assert.Equal(1, _validator.Times["ValidateBinaryOperatorQueryNode"]); // eq Assert.Equal(1, _validator.Times["ValidateParameterQueryNode"]); // $it }
public IEnumerable <ProductDTO> Get(ODataQueryOptions <ProductDTO> q) { IQueryable <Product> products = this._products.AsQueryable(); IEdmModel model = GetModel(); IEdmType type = model.FindDeclaredType("TestAPI.Models.Product"); IEdmNavigationSource source = model.FindDeclaredEntitySet("Products"); ODataQueryOptionParser parser = new ODataQueryOptionParser(model, type, source, new Dictionary <string, string> { { "$filter", q.Filter.RawValue } }); ODataQueryContext context = new ODataQueryContext(model, typeof(Product), q.Context.Path); FilterQueryOption filter = new FilterQueryOption(q.Filter.RawValue, context, parser); if (filter != null) { products = filter.ApplyTo(products, new ODataQuerySettings()) as IQueryable <Product>; } return(products.Select(p => new ProductDTO(p))); }
/// <summary> /// Validates a <see cref="FilterQueryOption" />. /// </summary> /// <param name="filterQueryOption">The $filter query.</param> /// <param name="settings">The validation settings.</param> /// <remarks> /// Please note this method is not thread safe. /// </remarks> public virtual void Validate(FilterQueryOption filterQueryOption, ODataValidationSettings settings) { if (filterQueryOption == null) { throw Error.ArgumentNull("filterQueryOption"); } if (settings == null) { throw Error.ArgumentNull("settings"); } _currentAnyAllExpressionDepth = 0; _currentNodeCount = 0; _model = filterQueryOption.Context.Model; ValidateQueryNode(filterQueryOption.FilterClause.Expression, settings); }
public ICollection <BinderNode> BindFilter(FilterQueryOption filterQuery, Action <Exception> exceptionHandler) { var nodes = new HashSet <BinderNode>(); if (filterQuery != null) { try { Bind(filterQuery.FilterClause.Expression, nodes); } catch (Exception ex) { exceptionHandler(ex); } } return(nodes); }
public void ValidateVisitAny() { // Arrange FilterQueryOption option = new FilterQueryOption("Tags/any(t: t eq '42')", _context); // Act _validator.Validate(option, _settings); // Assert Assert.Equal(7, _validator.Times.Keys.Count); Assert.Equal(1, _validator.Times["Validate"]); // entry Assert.Equal(1, _validator.Times["ValidateAnyQueryNode"]); // all Assert.Equal(1, _validator.Times["ValidateLogicalOperator"]); // eq Assert.Equal(1, _validator.Times["ValidateCollectionPropertyAccessNode"]); // Tags Assert.Equal(1, _validator.Times["ValidateConstantQueryNode"]); // 42 Assert.Equal(1, _validator.Times["ValidateBinaryOperatorQueryNode"]); // eq Assert.Equal(2, _validator.Times["ValidateParameterQueryNode"]); // $it, t }
public void ValidateVisitAny() { // Arrange FilterQueryOption option = new FilterQueryOption("Tags/any(t: t eq '42')", _context); // Act _validator.Validate(option, _settings); // Assert Assert.Equal(7, _validator.Times.Keys.Count); Assert.Equal(1, _validator.Times["Validate"]); // entry Assert.Equal(1, _validator.Times["ValidateAnyQueryNode"]); // all Assert.Equal(1, _validator.Times["ValidateLogicalOperator"]); // eq Assert.Equal(1, _validator.Times["ValidateCollectionPropertyAccessNode"]); // Tags Assert.Equal(1, _validator.Times["ValidateConstantQueryNode"]); // 42 Assert.Equal(1, _validator.Times["ValidateBinaryOperatorQueryNode"]); // eq Assert.Equal(2, _validator.Times["ValidateParameterQueryNode"]); // $it, t }
/* * [EnableQuery] * public IHttpActionResult Get() * { * return Ok(db.Customers); * }*/ public IHttpActionResult Get(ODataQueryOptions <Customer> options) { IList <Customer> customers = db.Customers.ToList(); FilterQueryOption filter = options.Filter; FilterClause filterClause = filter.FilterClause; SingleValueFunctionCallNode functionCall = filterClause.Expression as SingleValueFunctionCallNode; if (functionCall != null) { if (functionCall.Name == "geo.intersects") { customers = BindGeoIntersections(functionCall, customers).ToList(); } } return(Ok(customers)); }
public static Expression <Func <TElement, bool> > ToExpression <TElement>(this FilterQueryOption filter) { var param = Expression.Parameter(typeof(TElement)); IQueryable queryable = Enumerable.Empty <TElement>().AsQueryable(); if (filter != null) { queryable = filter.ApplyTo(queryable, new ODataQuerySettings()); var mce = queryable.Expression as MethodCallExpression; if (mce != null) { var quote = mce.Arguments[1] as UnaryExpression; if (quote != null) { return(quote.Operand as Expression <Func <TElement, bool> >); } } } return(Expression.Lambda <Func <TElement, bool> >(Expression.Constant(true), param)); }
/// <summary> /// Validates a <see cref="FilterQueryOption" />. /// </summary> /// <param name="filterQueryOption">The $filter query.</param> /// <param name="settings">The validation settings.</param> /// <remarks> /// Please note this method is not thread safe. /// </remarks> public virtual void Validate(FilterQueryOption filterQueryOption, ODataValidationSettings settings) { if (filterQueryOption == null) { throw Error.ArgumentNull("filterQueryOption"); } if (settings == null) { throw Error.ArgumentNull("settings"); } if (filterQueryOption.Context.Path != null) { Property = filterQueryOption.Context.TargetProperty; StructuredType = filterQueryOption.Context.TargetStructuredType; } Validate(filterQueryOption.FilterClause, settings, filterQueryOption.Context.Model); }
static private Expression <Func <T, bool> > GetFilterExpression <T>(FilterQueryOption filter) { var enumerable = Enumerable.Empty <T>().AsQueryable(); var param = Expression.Parameter(typeof(T)); if (filter != null) { enumerable = (IQueryable <T>)filter.ApplyTo(enumerable, new ODataQuerySettings()); var mce = enumerable.Expression as MethodCallExpression; if (mce != null) { var quote = mce.Arguments[1] as UnaryExpression; if (quote != null) { return(quote.Operand as Expression <Func <T, bool> >); } } } return(Expression.Lambda <Func <T, bool> >(Expression.Constant(true), param)); }
/// <summary> /// translate an odata filter clause to a documentdb where and self join clause. /// </summary> /// <param name="filterQuery">odata filter option object which contains a AST of odata filter clause</param> /// <returns>WhereAndJoinClause object that contains the where clause and a list of self join clauses. /// if filterQuery is null, it will return an empty where clause and an empty list of self join clauses.</returns> public WhereAndJoinClause TranslateODataFilterToDocDBWhereAndJoin(FilterQueryOption filterQuery) { whereAndJoinClause = new WhereAndJoinClause { Clause = String.Empty, JoinClause = new List <string>() }; RangeVariablesNameForAnyNodeBody = new Stack <string>(); if (filterQuery != null) { if (filterQuery.FilterClause != null && filterQuery.FilterClause.Expression != null) { whereAndJoinClause.Clause = Translate(filterQuery.FilterClause.Expression); // JoinClause will be filled in by TranslateFilter through the static instance whereAndJoinClause } } return(whereAndJoinClause); }
public static IEnumerable <string> GetPaths(FilterQueryOption filterOption, string separator = ".") { Console.WriteLine("------"); var v = new MyVisitor(separator); IEnumerable <string> returnVar; var expr = filterOption.FilterClause.Expression; var t = expr.GetType(); if (t == typeof(BinaryOperatorNode)) { returnVar = v.Visit((BinaryOperatorNode)expr); } else if (t == typeof(AnyNode)) { returnVar = v.Visit((AnyNode)expr); } else { throw new TypeAccessException(t.FullName); } return(returnVar.ToHashSet()); }
/// <summary> /// Validates a <see cref="FilterQueryOption" />. /// </summary> /// <param name="filterQueryOption">The $filter query.</param> /// <param name="settings">The validation settings.</param> /// <remarks> /// Please note this method is not thread safe. /// </remarks> public virtual void Validate(FilterQueryOption filterQueryOption, ODataValidationSettings settings) { if (filterQueryOption == null) { throw Error.ArgumentNull(nameof(filterQueryOption)); } if (settings == null) { throw Error.ArgumentNull(nameof(settings)); } if (filterQueryOption.Context.Path != null) { _property = filterQueryOption.Context.TargetProperty; _structuredType = filterQueryOption.Context.TargetStructuredType; } _defaultQuerySettings = filterQueryOption.Context.DefaultQuerySettings; Validate(filterQueryOption.FilterClause, settings, filterQueryOption.Context.Model); }
public void TestFilterVisitor() { ODataConventionModelBuilder builder = new ODataConventionModelBuilder(); builder.EntitySet <Bar>("Bar"); ODataQueryContext context = new ODataQueryContext(builder.GetEdmModel(), typeof(Bar)); //ODataQueryOptions<Customer> query = new ODataQueryOptions<Customer>(context, new HttpRequestMessage(HttpMethod.Get, "http://server/?$top=10")); FilterQueryOption f = new FilterQueryOption("startswith(BarString,'b') eq true", context); var pathsString = FindNavigationFilterOptions.GetPaths(f).ToList(); CollectionAssert.AreEqual(pathsString, new string[0]); f = new FilterQueryOption("F/FooId eq 1", context); pathsString = FindNavigationFilterOptions.GetPaths(f).ToList(); CollectionAssert.AreEqual(pathsString, new[] { "F" }); f = new FilterQueryOption("Foos/any(x1: x1/B/BarId eq 1)", context); pathsString = FindNavigationFilterOptions.GetPaths(f).ToList(); CollectionAssert.AreEqual(pathsString, new[] { "Foos.B" }); f = new FilterQueryOption("(startswith(BarString,'b') eq true) and (not (Foos/any(x1: x1/B/BarId eq 1)))", context); pathsString = FindNavigationFilterOptions.GetPaths(f).ToList(); CollectionAssert.AreEqual(pathsString, new[] { "Foos.B" }); f = new FilterQueryOption("Foos/any(x1: x1/B/F/FooId eq 1)", context); pathsString = FindNavigationFilterOptions.GetPaths(f).ToList(); CollectionAssert.AreEqual(pathsString, new[] { "Foos.B.F" }); f = new FilterQueryOption("F/Bars/any(x1: x1/BarId eq 1)", context); pathsString = FindNavigationFilterOptions.GetPaths(f).ToList(); CollectionAssert.AreEqual(pathsString, new[] { "F.Bars" }); f = new FilterQueryOption("F/Bars/any(x1: ((x1/BarId eq 1) and (x1/BarString eq 'abc')) and (x1/F/FooId lt 3))", context); pathsString = FindNavigationFilterOptions.GetPaths(f).ToList(); CollectionAssert.AreEqual(pathsString, new[] { "F.Bars.F" }); }
public static Expression <Func <TElement, bool> > ToExpression <TElement>(this FilterQueryOption filter) { if (filter == null) { return(null); } // Avoid InvalidOperationException // see https://github.com/aspnet/EntityFrameworkCore/issues/10721 var oDataSettings = new ODataQuerySettings(); oDataSettings.HandleNullPropagation = HandleNullPropagationOption.False; var queryable = Enumerable.Empty <TElement>().AsQueryable(); var where = filter.ApplyTo(queryable, oDataSettings).Expression; var whereType = where.GetType(); var whereArguments = (ReadOnlyCollection <Expression>)whereType.GetProperty("Arguments").GetGetMethod().Invoke(where, new object[0]); var unaryExpression = whereArguments[1]; var result = unaryExpression.GetType().GetProperty("Operand")?.GetGetMethod()?.Invoke(unaryExpression, new object[0]); return((Expression <Func <TElement, bool> >)result); }
/// <summary> /// Parses the Filter portion of the ODataQueryOptions object and adds its details to the used QueryInformation. /// </summary> /// <param name="filter">FilterQueryOption object contained in the ODataQueryOptions from the OData controller.</param> /// <param name="info">The QueryInformation object that is maintained to give back the results.</param> public void ParseFilterData(FilterQueryOption filter, QueryInformation info) { try { // If the filter comes null, there is no work to be done by this method. if (filter == null) { return; } // There is at least one parameter so we instantiate the collection in the info object. info.FilterParameters = new ODataFilterParameterCollection(); // The abstract syntax tree of the expression is a binary tree, we perform it here from the root. BinarySearchForNodes(filter.FilterClause.Expression, info); return; } catch (Exception ex) { LogException(ex); } }
public void Validator_Doesnot_Throw_For_ParameterAlias() { // Arrange FilterQueryOption option = new FilterQueryOption( "Id eq @p", _context, new ODataQueryOptionParser( _context.Model, _context.ElementType, _context.NavigationSource, new Dictionary <string, string> { { "$filter", "Id eq @p" }, { "@p", "1" } })); // Act & Assert Assert.DoesNotThrow(() => _validator.Validate(option, _settings)); Assert.Equal(6, _validator.Times.Keys.Count); Assert.Equal(1, _validator.Times["Validate"]); // entry Assert.Equal(1, _validator.Times["ValidateParameterQueryNode"]); // $it Assert.Equal(1, _validator.Times["ValidateSingleValuePropertyAccessNode"]); // Id Assert.Equal(1, _validator.Times["ValidateBinaryOperatorQueryNode"]); // eq Assert.Equal(1, _validator.Times["ValidateLogicalOperator"]); // eq Assert.Equal(1, _validator.Times["ValidateConstantQueryNode"]); // 1 }
public void DateTimeFunctions_Unsupported_ThrowODataException(AllowedFunctions unused, string query, string functionName) { // Arrange var settings = new ODataValidationSettings { AllowedFunctions = AllowedFunctions.None, }; var expectedMessage = string.Format( "An unknown function with name '{0}' was found. " + "This may also be a key lookup on a navigation property, which is not allowed.", functionName); var option = new FilterQueryOption(query, _productContext); // Act & Assert Assert.Throws<ODataException>(() => _validator.Validate(option, settings), expectedMessage); }
public void ArithmeticOperators_CheckArguments_ThrowIfNotAllowed(string query) { // Arrange var settings = new ODataValidationSettings { AllowedFunctions = AllowedFunctions.AllFunctions & ~AllowedFunctions.Day, }; var expectedMessage = string.Format( "Function 'day' is not allowed. " + "To allow it, set the 'AllowedFunctions' property on EnableQueryAttribute or QueryValidationSettings."); var option = new FilterQueryOption(query, _productContext); // Act & Assert Assert.Throws<ODataException>(() => _validator.Validate(option, settings), expectedMessage); }
public void AllowedArithmeticOperators_ThrowIfNoneAllowed(AllowedArithmeticOperators unused, string query, string operatorName) { // Arrange var settings = new ODataValidationSettings { AllowedArithmeticOperators = AllowedArithmeticOperators.None, }; var expectedMessage = string.Format( "Arithmetic operator '{0}' is not allowed. " + "To allow it, set the 'AllowedArithmeticOperators' property on EnableQueryAttribute or QueryValidationSettings.", operatorName); var option = new FilterQueryOption(query, _productContext); // Act & Assert Assert.Throws<ODataException>(() => _validator.Validate(option, settings), expectedMessage); }
public void AlmostLongInputs_DonotCauseMaxNodeCountExceededExceptionOrTimeoutDuringCompilation(string filter) { // Arrange ODataValidationSettings settings = new ODataValidationSettings { MaxAnyAllExpressionDepth = Int32.MaxValue }; FilterQueryOption option = new FilterQueryOption(filter, _productContext); // Act & Assert Assert.DoesNotThrow(() => _validator.Validate(option, settings)); Assert.DoesNotThrow(() => option.ApplyTo(new List<Product>().AsQueryable(), new ODataQuerySettings())); }
public void LongInputs_CauseMaxNodeCountExceededException(string filter) { // Arrange ODataValidationSettings settings = new ODataValidationSettings { MaxAnyAllExpressionDepth = Int32.MaxValue }; FilterQueryOption option = new FilterQueryOption(filter, _productContext); // Act & Assert Assert.Throws<ODataException>(() => _validator.Validate(option, settings), "The node count limit of '100' has been exceeded. To increase the limit, set the 'MaxNodeCount' property on EnableQueryAttribute or ODataValidationSettings."); }
public void Validator_Doesnot_Throw_For_ValidQueries(string filter) { // Arrange FilterQueryOption option = new FilterQueryOption(filter, _context); // Act & Assert Assert.DoesNotThrow(() => _validator.Validate(option, _settings)); }
public async Task <ActionResult <FeatureCollection> > GetGeoJsonAsync(string id, ODataQueryOptions <RouteInstance> q, [FromQuery] string language) { var userClaim = User.Claims.SingleOrDefault(c => c.Type == ClaimTypes.NameIdentifier); var userIdClaim = int.Parse(userClaim != null ? userClaim.Value : "-1"); var guid = Guid.Parse(id); var map = await _context.Maps.SingleOrDefaultAsync(m => m.MapGuid == guid); if (map == null) { return(NotFound()); } if (string.IsNullOrWhiteSpace(map.SharingLinkName)) { if (!User.Claims.Any()) { return(Forbid()); } var adminClaim = (User.Claims.SingleOrDefault(c => c.Type == "admin").Value ?? "false"); if ((userIdClaim < 0 || map.UserId != userIdClaim) && !string.Equals(adminClaim, "true", StringComparison.OrdinalIgnoreCase)) { return(Forbid()); } } var routes = _context.RouteInstances .Include(ri => ri.Route) .ThenInclude(r => r.RouteType) .AsQueryable(); var types = await _context.RouteTypes.ToListAsync(); var colours = new Dictionary <int, LineStyle>(); types.ForEach(t => { colours.Add(t.TypeId, new LineStyle { Color = Color32.Parse(t.Colour) }); }); if (q.Filter != null) { var model = Startup.GetEdmModel(); IEdmType type = model.FindDeclaredType("OVDB_database.Models.RouteInstance"); IEdmNavigationSource source = model.FindDeclaredEntitySet("Products"); var parser = new ODataQueryOptionParser(model, type, source, new Dictionary <string, string> { { "$filter", q.Filter.RawValue } }); var context = new ODataQueryContext(model, typeof(RouteInstance), q.Context.Path); var filter = new FilterQueryOption(q.Filter.RawValue, context, parser); routes = q.Filter.ApplyTo(routes, new ODataQuerySettings()) as IQueryable <RouteInstance>; } routes = routes.Where(r => r.RouteInstanceMaps.Any(rim => rim.MapId == map.MapId) || r.Route.RouteMaps.Any(rm => rm.MapId == map.MapId)); var collection = new FeatureCollection(); var routesList = new List <Route>(); var routesToReturn = new Dictionary <int, int>(); await routes.ForEachAsync(r => { if (!routesToReturn.ContainsKey(r.RouteId)) { routesToReturn.Add(r.RouteId, 0); routesList.Add(r.Route); } routesToReturn[r.RouteId] += 1; }); routesList.ForEach(r => { try { var multi = r.Coordinates.Split("###").ToList(); var lines = new List <GeoJSON.Net.Geometry.LineString>(); multi.ForEach(block => { var coordinates = block.Split('\n').Where(a => !string.IsNullOrWhiteSpace(a)).ToList(); var coords = coordinates.Select(r => new Position(double.Parse(r.Split(',')[1], CultureInfo.InvariantCulture), double.Parse(r.Split(',')[0], CultureInfo.InvariantCulture))).ToList(); if (coords.Count >= 2) { var geo = new GeoJSON.Net.Geometry.LineString(coords); lines.Add(geo); } }); GeoJSON.Net.Feature.Feature feature; if (lines.Count == 1) { feature = new GeoJSON.Net.Feature.Feature(lines.Single()); } else { var multiLineString = new MultiLineString(lines); feature = new GeoJSON.Net.Feature.Feature(multiLineString); } feature.Properties.Add("id", r.RouteId); feature.Properties.Add("totalInstances", routesToReturn[r.RouteId]); if (map.ShowRouteOutline) { feature.Properties.Add("o", 1); } if (map.ShowRouteInfo) { if (language == "nl" && !string.IsNullOrWhiteSpace(r.NameNL)) { feature.Properties.Add("name", r.NameNL); } else { feature.Properties.Add("name", r.Name); } if (language == "nl" && !string.IsNullOrWhiteSpace(r.RouteType.NameNL)) { feature.Properties.Add("type", r.RouteType.NameNL); } else { feature.Properties.Add("type", r.RouteType.Name); } if (language == "nl" && !string.IsNullOrWhiteSpace(r.DescriptionNL)) { feature.Properties.Add("description", r.DescriptionNL); } else { feature.Properties.Add("description", r.Description); } feature.Properties.Add("lineNumber", r.LineNumber); feature.Properties.Add("operatingCompany", r.OperatingCompany); if (r.OverrideDistance.HasValue) { feature.Properties.Add("distance", r.OverrideDistance); } else { feature.Properties.Add("distance", r.CalculatedDistance); } } if (map.UserId == userIdClaim) { feature.Properties.Add("owner", true); } if (!string.IsNullOrWhiteSpace(r.OverrideColour)) { feature.Properties.Add("stroke", r.OverrideColour); } else { feature.Properties.Add("stroke", r.RouteType.Colour); } collection.Features.Add(feature); } catch (Exception ex) { Console.WriteLine(ex.Message); throw; } }); return(collection); }
public void LogicalOperators_CheckArguments_ThrowIfNotAllowed(string query) { // Arrange var settings = new ODataValidationSettings { AllowedArithmeticOperators = AllowedArithmeticOperators.All & ~AllowedArithmeticOperators.Add, }; var expectedMessage = string.Format( "Arithmetic operator 'Add' is not allowed. " + "To allow it, set the 'AllowedArithmeticOperators' property on EnableQueryAttribute or QueryValidationSettings."); var option = new FilterQueryOption(query, _productContext, queryTranslator: null); // Act & Assert Assert.Throws<ODataException>(() => _validator.Validate(option, settings), expectedMessage); }
public void MathFunctions_ThrowIfGroupNotAllowed(AllowedFunctions unused, string query, string functionName) { // Arrange var settings = new ODataValidationSettings { AllowedFunctions = AllowedFunctions.AllFunctions & ~AllowedFunctions.AllMathFunctions, }; var expectedMessage = string.Format( "Function '{0}' is not allowed. " + "To allow it, set the 'AllowedFunctions' property on EnableQueryAttribute or QueryValidationSettings.", functionName); var option = new FilterQueryOption(query, _productContext, queryTranslator: null); // Act & Assert Assert.Throws<ODataException>(() => _validator.Validate(option, settings), expectedMessage); }
private static WhereClause ToFilterQuery(FilterQueryOption filterQuery) { return(NHibernateFilterBinder.BindFilterQueryOption(filterQuery)); }
public async Task <IActionResult> OData(ODataQueryOptions <DeveloperDto> oDataQuery) { var edmModel = EdmModelConfig.GetEdmModel(); var edmEntitySet = edmModel.FindDeclaredEntitySet(nameof(Developer)); var context = new ODataQueryContext(edmModel, typeof(Developer), oDataQuery.Context.Path); var edmType = context.ElementType; var parameters = new Dictionary <string, string>(); if (!string.IsNullOrWhiteSpace(oDataQuery.RawValues.Filter)) { parameters.Add("$filter", oDataQuery.RawValues.Filter); } if (!string.IsNullOrWhiteSpace(oDataQuery.RawValues.Expand)) { parameters.Add("$expand", oDataQuery.RawValues.Expand); } if (!string.IsNullOrWhiteSpace(oDataQuery.RawValues.OrderBy)) { parameters.Add("$orderby", oDataQuery.RawValues.OrderBy); } var parser = new ODataQueryOptionParser(edmModel, edmType, edmEntitySet, parameters); var queryable = (IQueryable <Developer>)_databaseContext.Developer; if (!string.IsNullOrWhiteSpace(oDataQuery.RawValues.Filter)) { var filter = new FilterQueryOption(oDataQuery.RawValues.Filter, context, parser); queryable = (IQueryable <Developer>)filter.ApplyTo(queryable, new ODataQuerySettings()); } if (!string.IsNullOrWhiteSpace(oDataQuery.RawValues.OrderBy)) { var orderBy = new OrderByQueryOption(oDataQuery.RawValues.OrderBy, context, parser); queryable = orderBy.ApplyTo(queryable, new ODataQuerySettings()); } IQueryable <object> expandableQueryable = null; if (!string.IsNullOrWhiteSpace(oDataQuery.RawValues.Expand)) { var expand = new SelectExpandQueryOption(null, oDataQuery.RawValues.Expand, context, parser); expandableQueryable = (IQueryable <object>)expand.ApplyTo(queryable, new ODataQuerySettings()); } int pageIndex = 1; var hasPageIndex = oDataQuery.Request.Query.TryGetValue("$pageindex", out StringValues pageIndexRaw); if (hasPageIndex) { var isTrue = int.TryParse(pageIndexRaw, out int _pageIndexRaw); pageIndex = (isTrue && _pageIndexRaw > 0) ? _pageIndexRaw : pageIndex; } int pageSize = 10; var hasPageSize = oDataQuery.Request.Query.TryGetValue("$pagesize", out StringValues pageSizeRaw); if (hasPageSize) { var isTrue = int.TryParse(pageSizeRaw, out int _pageSizeRaw); pageSize = (isTrue && _pageSizeRaw > 0) ? _pageSizeRaw : pageSize; } IQueryable <object> queryToExecute = expandableQueryable ?? queryable; var records = await queryToExecute.Skip((pageIndex - 1) *pageSize).Take(pageSize).ToListAsync(); var count = await queryToExecute.CountAsync(); var pageList = new PageList <Developer>(MapDomain(records).ToList(), count, pageIndex, pageSize); var response = PageListDto <DeveloperDto> .Map(pageList, DeveloperDto.MapDomainToDto); return(Ok(response)); }
protected string BindFilter(FilterQueryOption filterQuery) { return(BindFilterClause(filterQuery.FilterClause)); }
public void OtherFunctions_Unsupported_ThrowNotSupported(AllowedFunctions unused, string query, string unusedName) { // Arrange var settings = new ODataValidationSettings { AllowedFunctions = AllowedFunctions.None, }; var expectedMessage = "Validating OData QueryNode of kind SingleEntityFunctionCall is not supported by FilterQueryValidator."; var option = new FilterQueryOption(query, _productContext); // Act & Assert Assert.Throws<NotSupportedException>(() => _validator.Validate(option, settings), expectedMessage); }
public void OtherFunctions_SomeTwoParameterCasts_ThrowODataException(AllowedFunctions unused, string query, string unusedName) { // Arrange var settings = new ODataValidationSettings { AllowedFunctions = AllowedFunctions.None, }; var expectedMessage = string.Format( "Encountered invalid type cast. '{0}' is not assignable from '{1}'.", typeof(DerivedCategory).FullName, typeof(Product).FullName); var option = new FilterQueryOption(query, _productContext); // Act & Assert Assert.Throws<ODataException>(() => _validator.Validate(option, settings), expectedMessage); }
public void Functions_CheckArguments_ThrowIfNotAllowed(AllowedFunctions outer, AllowedFunctions inner, string query, string functionName) { // Arrange var settings = new ODataValidationSettings { AllowedFunctions = outer, }; var expectedMessage = string.Format( "Function '{0}' is not allowed. " + "To allow it, set the 'AllowedFunctions' property on EnableQueryAttribute or QueryValidationSettings.", functionName); var option = new FilterQueryOption(query, _productContext); // Act & Assert Assert.Throws<ODataException>(() => _validator.Validate(option, settings), expectedMessage); }
public void ValidateVisitLogicalOperatorEqual() { // Arrange FilterQueryOption option = new FilterQueryOption("Id eq 1", _context); // Act _validator.Validate(option, _settings); // Assert Assert.Equal(6, _validator.Times.Keys.Count); Assert.Equal(1, _validator.Times["Validate"]); // entry Assert.Equal(1, _validator.Times["ValidateSingleValuePropertyAccessNode"]); // Id Assert.Equal(1, _validator.Times["ValidateLogicalOperator"]); // eq Assert.Equal(1, _validator.Times["ValidateConstantQueryNode"]); // 1 Assert.Equal(1, _validator.Times["ValidateBinaryOperatorQueryNode"]); // eq Assert.Equal(1, _validator.Times["ValidateParameterQueryNode"]); // $it }
public static string Parse(FilterQueryOption queryOption, string target) { return(Parse(queryOption.FilterClause.Expression, target)); }
public override void Validate(FilterQueryOption filterQueryOption, ODataValidationSettings settings) { IncrementCount("Validate"); base.Validate(filterQueryOption, settings); }
public void AllowedArithmeticOperators_ThrowsOnNotAllowedOperators() { // Arrange ODataValidationSettings settings = new ODataValidationSettings { AllowedArithmeticOperators = AllowedArithmeticOperators.All & ~AllowedArithmeticOperators.Modulo }; FilterQueryOption option = new FilterQueryOption("ProductID mod 2 eq 0", _productContext); // Act & Assert Assert.Throws<ODataException>( () => _validator.Validate(option, settings), "Arithmetic operator 'Modulo' is not allowed. To allow it, set the 'AllowedArithmeticOperators' property on EnableQueryAttribute or QueryValidationSettings."); }
public void IncreaseMaxNodeCountWillAllowLongInputs(string filter) { // Arrange ODataValidationSettings settings = new ODataValidationSettings { MaxAnyAllExpressionDepth = Int32.MaxValue, MaxNodeCount = 105, }; FilterQueryOption option = new FilterQueryOption(filter, _productContext); // Act & Assert Assert.DoesNotThrow(() => _validator.Validate(option, settings)); }
public void AllowedFunctions_ThrowsOnNotAllowedFunctions() { // Arrange ODataValidationSettings settings = new ODataValidationSettings { AllowedFunctions = AllowedFunctions.All & ~AllowedFunctions.Length }; FilterQueryOption option = new FilterQueryOption("length(ProductName) eq 6", _productContext); // Act & Assert Assert.Throws<ODataException>( () => _validator.Validate(option, settings), "Function 'length' is not allowed. To allow it, set the 'AllowedFunctions' property on EnableQueryAttribute or QueryValidationSettings."); }
public void AllowedArithmeticOperators_SucceedIfAllowed(AllowedArithmeticOperators allow, string query, string unused) { // Arrange var settings = new ODataValidationSettings { AllowedArithmeticOperators = allow, }; var option = new FilterQueryOption(query, _productContext); // Act & Assert Assert.DoesNotThrow(() => _validator.Validate(option, settings)); }
public void AllowedLogicalOperators_ThrowsOnNotAllowedOperators() { // Arrange ODataValidationSettings settings = new ODataValidationSettings { AllowedLogicalOperators = AllowedLogicalOperators.All & ~AllowedLogicalOperators.NotEqual }; FilterQueryOption option = new FilterQueryOption("length(ProductName) ne 6", _productContext); // Act & Assert Assert.Throws<ODataException>( () => _validator.Validate(option, settings), "Logical operator 'NotEqual' is not allowed. To allow it, set the 'AllowedLogicalOperators' property on EnableQueryAttribute or QueryValidationSettings."); }
public void ArithmeticOperators_CheckArguments_SucceedIfAllowed(string query) { // Arrange var settings = new ODataValidationSettings { AllowedFunctions = AllowedFunctions.Day, }; var option = new FilterQueryOption(query, _productContext); // Act & Assert Assert.DoesNotThrow(() => _validator.Validate(option, settings)); }
public void ValidateVisitLogicalOperatorHas() { // Arrange FilterQueryOption option = new FilterQueryOption("FavoriteColor has System.Web.OData.Builder.TestModels.Color'Red'", _context); // Act _validator.Validate(option, _settings); // Assert Assert.Equal(6, _validator.Times.Keys.Count); Assert.Equal(1, _validator.Times["Validate"]); // entry Assert.Equal(1, _validator.Times["ValidateSingleValuePropertyAccessNode"]); // FavouriteColor Assert.Equal(1, _validator.Times["ValidateLogicalOperator"]); // has Assert.Equal(1, _validator.Times["ValidateBinaryOperatorQueryNode"]); // has Assert.Equal(1, _validator.Times["ValidateParameterQueryNode"]); // $it }
public void StringFunctions_SucceedIfGroupAllowed(AllowedFunctions unused, string query, string unusedName) { // Arrange var settings = new ODataValidationSettings { AllowedFunctions = AllowedFunctions.AllStringFunctions, }; var option = new FilterQueryOption(query, _productContext); // Act & Assert Assert.DoesNotThrow(() => _validator.Validate(option, settings)); }
public void Validator_Doesnot_Throw_For_ParameterAlias() { // Arrange FilterQueryOption option = new FilterQueryOption( "Id eq @p", _context, new ODataQueryOptionParser( _context.Model, _context.ElementType, _context.NavigationSource, new Dictionary<string, string> { { "$filter", "Id eq @p" }, { "@p", "1" } })); // Act & Assert Assert.DoesNotThrow(() => _validator.Validate(option, _settings)); Assert.Equal(6, _validator.Times.Keys.Count); Assert.Equal(1, _validator.Times["Validate"]); // entry Assert.Equal(1, _validator.Times["ValidateParameterQueryNode"]); // $it Assert.Equal(1, _validator.Times["ValidateSingleValuePropertyAccessNode"]); // Id Assert.Equal(1, _validator.Times["ValidateBinaryOperatorQueryNode"]); // eq Assert.Equal(1, _validator.Times["ValidateLogicalOperator"]); // eq Assert.Equal(1, _validator.Times["ValidateConstantQueryNode"]); // 1 }
public void OtherFunctions_UnsupportedTargetType_ThrowODataException(string query, string targetType) { // Arrange var settings = new ODataValidationSettings { AllowedFunctions = AllowedFunctions.None, }; var expectedMessage = string.Format( "The child type '{0}' in a cast was not an entity type. Casts can only be performed on entity types.", targetType); var option = new FilterQueryOption(query, _productContext); // Act & Assert Assert.Throws<ODataException>(() => _validator.Validate(option, settings), expectedMessage); }
public void ArithmeticNegation_SucceedsIfLogicalNotIsAllowed() { // Arrange var settings = new ODataValidationSettings { AllowedLogicalOperators = AllowedLogicalOperators.LessThan | AllowedLogicalOperators.Not, }; var option = new FilterQueryOption("-UnitPrice lt 0", _productContext); // Act & Assert Assert.DoesNotThrow(() => _validator.Validate(option, settings)); }
public void OtherFunctions_SomeSingleParameterCasts_ThrowODataException(AllowedFunctions unused, string query, string unusedName) { // Arrange var settings = new ODataValidationSettings { AllowedFunctions = AllowedFunctions.None, }; var expectedMessage = "Cast or IsOf Function must have a type in its arguments."; var option = new FilterQueryOption(query, _productContext); // Act & Assert Assert.Throws<ODataException>(() => _validator.Validate(option, settings), expectedMessage); }
public void ArithmeticNegation_ThrowsIfLogicalNotIsNotAllowed() { // Arrange var settings = new ODataValidationSettings { AllowedLogicalOperators = AllowedLogicalOperators.LessThan, }; var expectedMessage = string.Format( "Logical operator 'Negate' is not allowed. " + "To allow it, set the 'AllowedLogicalOperators' property on EnableQueryAttribute or QueryValidationSettings."); var option = new FilterQueryOption("-UnitPrice lt 0", _productContext); // Act & Assert Assert.Throws<ODataException>(() => _validator.Validate(option, settings), expectedMessage); }
public void Functions_CheckArguments_SucceedIfAllowed(AllowedFunctions outer, AllowedFunctions inner, string query, string unused) { // Arrange var settings = new ODataValidationSettings { AllowedFunctions = outer | inner, }; var option = new FilterQueryOption(query, _productContext); // Act & Assert Assert.DoesNotThrow(() => _validator.Validate(option, settings)); }
public override void Validate(FilterQueryOption filterQueryOption, ODataValidationSettings settings) { IncrementCount("Validate"); base.Validate(filterQueryOption, settings); }
/// <summary> /// Bind the <see cref="FilterQueryOption"/> to a FetchXml Filter /// </summary> /// <param name="filterQueryOption"><see cref="FilterQueryOption"/></param> /// <returns><see cref="Filter"/></returns> public static Filter BindFilterQueryOption(FilterQueryOption filterQueryOption) { _applyLogicalNegation = false; return(BindFilterClause(filterQueryOption.FilterClause)); }
public override void Validate(FilterQueryOption filterQueryOption, ODataValidationSettings settings) { ValidateQueryNode(filterQueryOption.FilterClause.Expression, settings); }