Skip to content

Commit

Permalink
OData#1645 unit test added and all unit tests passing
Browse files Browse the repository at this point in the history
  • Loading branch information
kccarter76 committed Jun 30, 2020
1 parent 691a0ef commit fa89897
Show file tree
Hide file tree
Showing 30 changed files with 227 additions and 132 deletions.
11 changes: 11 additions & 0 deletions src/Microsoft.AspNet.OData.Shared/Common/SRResources.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 8 additions & 8 deletions src/Microsoft.AspNet.OData.Shared/EnableQueryAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,7 @@ private object OnActionExecuted(
IWebApiActionDescriptor actionDescriptor,
IWebApiRequestMessage request,
Func<Type, IEdmModel> modelFunction,
Func<ODataQueryContext, ODataQueryOptions> createQueryOptionFunction,
Func<ODataQueryContext, IODataQueryOptions> createQueryOptionFunction,
Action<HttpStatusCode> createResponseAction,
Action<HttpStatusCode, string, Exception> createErrorAction)
{
Expand Down Expand Up @@ -466,9 +466,9 @@ private object OnActionExecuted(
/// </summary>
/// <param name="queryable">The original queryable instance from the response message.</param>
/// <param name="queryOptions">
/// The <see cref="ODataQueryOptions"/> instance constructed based on the incoming request.
/// The <see cref="IODataQueryOptions"/> instance constructed based on the incoming request.
/// </param>
public virtual IQueryable ApplyQuery(IQueryable queryable, ODataQueryOptions queryOptions)
public virtual IQueryable ApplyQuery(IQueryable queryable, IODataQueryOptions queryOptions)
{
if (queryable == null)
{
Expand All @@ -487,10 +487,10 @@ public virtual IQueryable ApplyQuery(IQueryable queryable, ODataQueryOptions que
/// </summary>
/// <param name="entity">The original entity from the response message.</param>
/// <param name="queryOptions">
/// The <see cref="ODataQueryOptions"/> instance constructed based on the incoming request.
/// The <see cref="IODataQueryOptions"/> instance constructed based on the incoming request.
/// </param>
/// <returns>The new entity after the $select and $expand query has been applied to.</returns>
public virtual object ApplyQuery(object entity, ODataQueryOptions queryOptions)
public virtual object ApplyQuery(object entity, IODataQueryOptions queryOptions)
{
if (entity == null)
{
Expand Down Expand Up @@ -588,12 +588,12 @@ private object ExecuteQuery(
IWebApiActionDescriptor actionDescriptor,
Func<Type, IEdmModel> modelFunction,
IWebApiRequestMessage request,
Func<ODataQueryContext, ODataQueryOptions> createQueryOptionFunction)
Func<ODataQueryContext, IODataQueryOptions> createQueryOptionFunction)
{
ODataQueryContext queryContext = GetODataQueryContext(responseValue, singleResultCollection, actionDescriptor, modelFunction, request.Context.Path);

// Create and validate the query options.
ODataQueryOptions queryOptions = createQueryOptionFunction(queryContext);
IODataQueryOptions queryOptions = createQueryOptionFunction(queryContext);

// apply the query
IEnumerable enumerable = responseValue as IEnumerable;
Expand Down Expand Up @@ -718,7 +718,7 @@ internal static object SingleOrDefault(
/// Validate the select and expand options.
/// </summary>
/// <param name="queryOptions">The query options.</param>
internal static void ValidateSelectExpandOnly(ODataQueryOptions queryOptions)
internal static void ValidateSelectExpandOnly(IODataQueryOptions queryOptions)
{
if (queryOptions.Filter != null || queryOptions.Count != null || queryOptions.OrderBy != null
|| queryOptions.Skip != null || queryOptions.Top != null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -229,9 +229,9 @@ internal ExpandedReferenceSelectItem CurrentExpandedSelectItem
internal SelectItem CurrentSelectItem { get; set; }

/// <summary>
/// Gets or sets the <see cref="ODataQueryOptions"/>.
/// Gets or sets the <see cref="IODataQueryOptions"/>.
/// </summary>
public ODataQueryOptions QueryOptions { get; internal set; }
public IODataQueryOptions QueryOptions { get; internal set; }

/// <summary>
/// Gets or sets the relative path to the resouce being serialized
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,9 @@ internal interface IWebApiContext
SelectExpandClause ProcessedSelectExpandClause { get; set; }

/// <summary>
/// Gets or sets the <see cref="ODataQueryOptions"/> of the request.
/// Gets or sets the <see cref="IODataQueryOptions"/> of the request.
/// </summary>
ODataQueryOptions QueryOptions { get; set; }
IODataQueryOptions QueryOptions { get; set; }

/// <summary>
/// Gets or sets the total count for the OData response.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System;
using System.Diagnostics.Contracts;
using System.Linq;
using Microsoft.AspNet.OData.Interfaces;
using Microsoft.AspNet.OData.Query;

namespace Microsoft.AspNet.OData
Expand All @@ -18,7 +19,8 @@ internal static Type GetEntityClrTypeFromParameterType(Type parameterType)
Contract.Assert(parameterType != null);

if (parameterType.IsGenericType &&
parameterType.GetGenericTypeDefinition() == typeof(ODataQueryOptions<>))
(parameterType.GetGenericTypeDefinition() == typeof(ODataQueryOptions<>) ||
parameterType.GetGenericTypeDefinition() == typeof(IODataQueryOptions<>)))
{
return parameterType.GetGenericArguments().Single();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using Microsoft.AspNet.OData.Common;
using Microsoft.AspNet.OData.Formatter;
using Microsoft.AspNet.OData.Formatter.Serialization;
using Microsoft.AspNet.OData.Interfaces;
using Microsoft.AspNet.OData.Query.Expressions;
using Microsoft.OData;
using Microsoft.OData.Edm;
Expand Down Expand Up @@ -181,7 +182,7 @@ public override IQueryable ApplyTo(IQueryable query, SkipTokenQueryOption skipTo
}

ODataQuerySettings querySettings = skipTokenQueryOption.QuerySettings;
ODataQueryOptions queryOptions = skipTokenQueryOption.QueryOptions;
IODataQueryOptions queryOptions = skipTokenQueryOption.QueryOptions;
IList<OrderByNode> orderByNodes = null;

if (queryOptions != null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public partial class ODataQueryOptions
private OrderByQueryOption _stableOrderBy;

/// <summary>
/// Initializes a new instance of the <see cref="ODataQueryOptions"/> class based on the incoming request and some metadata information from
/// Initializes a new instance of the <see cref="IODataQueryOptions"/> class based on the incoming request and some metadata information from
/// the <see cref="ODataQueryContext"/>.
/// </summary>
/// <param name="context">The <see cref="ODataQueryContext"/> which contains the <see cref="IEdmModel"/> and some type information.</param>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNet.OData.Common;
using Microsoft.AspNet.OData.Interfaces;
using Microsoft.AspNet.OData.Query.Validators;
using Microsoft.OData.Edm;
using Microsoft.OData.UriParser;
Expand Down Expand Up @@ -74,7 +75,7 @@ public SkipTokenQueryOption(string rawValue, ODataQueryContext context, ODataQue
/// <summary>
/// Gets or sets the QueryOptions
/// </summary>
public ODataQueryOptions QueryOptions { get; private set; }
public IODataQueryOptions QueryOptions { get; private set; }

/// <summary>
/// Apply the $skiptoken query to the given IQueryable.
Expand All @@ -83,7 +84,7 @@ public SkipTokenQueryOption(string rawValue, ODataQueryContext context, ODataQue
/// <param name="querySettings">The query settings to use while applying this query option.</param>
/// <param name="queryOptions">Information about the other query options.</param>
/// <returns>The new <see cref="IQueryable"/> after the skiptoken query has been applied to.</returns>
public virtual IQueryable<T> ApplyTo<T>(IQueryable<T> query, ODataQuerySettings querySettings, ODataQueryOptions queryOptions)
public virtual IQueryable<T> ApplyTo<T>(IQueryable<T> query, ODataQuerySettings querySettings, IODataQueryOptions queryOptions)
{
QuerySettings = querySettings;
QueryOptions = queryOptions;
Expand All @@ -97,7 +98,7 @@ public virtual IQueryable<T> ApplyTo<T>(IQueryable<T> query, ODataQuerySettings
/// <param name="querySettings">The query settings to use while applying this query option.</param>
/// <param name="queryOptions">Information about the other query options.</param>
/// <returns>The new <see cref="IQueryable"/> after the skiptoken query has been applied to.</returns>
public virtual IQueryable ApplyTo(IQueryable query, ODataQuerySettings querySettings, ODataQueryOptions queryOptions)
public virtual IQueryable ApplyTo(IQueryable query, ODataQuerySettings querySettings, IODataQueryOptions queryOptions)
{
QuerySettings = querySettings;
QueryOptions = queryOptions;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
// Licensed under the MIT License. See License.txt in the project root for license information.

using Microsoft.AspNet.OData.Common;
using Microsoft.AspNet.OData.Interfaces;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.OData;
using System;

namespace Microsoft.AspNet.OData.Query.Validators
{
Expand All @@ -17,7 +19,7 @@ public class ODataQueryValidator
/// </summary>
/// <param name="options">The OData query to validate.</param>
/// <param name="validationSettings">The validation settings.</param>
public virtual void Validate(ODataQueryOptions options, ODataValidationSettings validationSettings)
public virtual void Validate(IODataQueryOptions options, ODataValidationSettings validationSettings)
{
if (options == null)
{
Expand Down Expand Up @@ -62,15 +64,22 @@ public virtual void Validate(ODataQueryOptions options, ODataValidationSettings
options.Filter.Validate(validationSettings);
}

if (options.Count != null || options.InternalRequest.IsCountRequest())
if (options is ODataQueryOptions _options)
{
ValidateQueryOptionAllowed(AllowedQueryOptions.Count, validationSettings.AllowedQueryOptions);

if (options.Count != null)
if (_options.Count != null || _options.InternalRequest.IsCountRequest())
{
options.Count.Validate(validationSettings);
ValidateQueryOptionAllowed(AllowedQueryOptions.Count, validationSettings.AllowedQueryOptions);

if (_options.Count != null)
{
_options.Count.Validate(validationSettings);
}
}
}
else
{
throw new NotSupportedException();
}

if (options.SkipToken != null)
{
Expand Down
16 changes: 6 additions & 10 deletions src/Microsoft.AspNetCore.OData/Adapters/WebApiContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,15 +93,14 @@ public SelectExpandClause ProcessedSelectExpandClause
}

/// <summary>
/// Gets or sets the parsed <see cref="ODataQueryOptions"/> of the request.
/// Gets or sets the parsed <see cref="IODataQueryOptions"/> of the request.
/// </summary>
public ODataQueryOptions QueryOptions
public IODataQueryOptions QueryOptions
{
get
{
// since we wanted to avoid a breaking change by modifying the interface, we cast to check if it is our ODataFeature class before we access the internal property. To be cleaned up with 8.x.
ODataFeature feature = this.innerFeature as ODataFeature;
if (feature != null)
if (this.innerFeature is ODataFeature feature)
{
return feature.QueryOptions;
}
Expand All @@ -110,8 +109,7 @@ public ODataQueryOptions QueryOptions
}
set
{
ODataFeature feature = this.innerFeature as ODataFeature;
if (feature != null)
if (this.innerFeature is ODataFeature feature)
{
feature.QueryOptions = value;
}
Expand All @@ -135,8 +133,7 @@ public int PageSize
get
{
// since we wanted to avoid a breaking change by modifying the interface, we cast to check if it is our ODataFeature class before we access the internal property.
ODataFeature feature = this.innerFeature as ODataFeature;
if (feature != null)
if (this.innerFeature is ODataFeature feature)
{
return feature.PageSize;
}
Expand All @@ -145,8 +142,7 @@ public int PageSize
}
set
{
ODataFeature feature = this.innerFeature as ODataFeature;
if (feature != null)
if (this.innerFeature is ODataFeature feature)
{
feature.PageSize = value;
}
Expand Down
11 changes: 6 additions & 5 deletions src/Microsoft.AspNetCore.OData/EnableQueryAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
using Microsoft.AspNet.OData.Common;
using Microsoft.AspNet.OData.Extensions;
using Microsoft.AspNet.OData.Formatter;
using Microsoft.AspNet.OData.Interfaces;
using Microsoft.AspNet.OData.Query;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
Expand Down Expand Up @@ -118,14 +119,14 @@ public override void OnActionExecuted(ActionExecutedContext actionExecutedContex
}

/// <summary>
/// Create and validate a new instance of <see cref="ODataQueryOptions"/> from a query and context.
/// Create and validate a new instance of <see cref="IODataQueryOptions"/> from a query and context.
/// </summary>
/// <param name="request">The incoming request.</param>
/// <param name="queryContext">The query context.</param>
/// <returns></returns>
private ODataQueryOptions CreateAndValidateQueryOptions(HttpRequest request, ODataQueryContext queryContext)
private IODataQueryOptions CreateAndValidateQueryOptions(HttpRequest request, ODataQueryContext queryContext)
{
ODataQueryOptions queryOptions = new ODataQueryOptions(queryContext, request);
IODataQueryOptions queryOptions = new ODataQueryOptions(queryContext, request);
ValidateQuery(request, queryOptions);

return queryOptions;
Expand Down Expand Up @@ -191,11 +192,11 @@ private static BadRequestObjectResult CreateBadRequestResult(string message, Exc
/// </summary>
/// <param name="request">The incoming request.</param>
/// <param name="queryOptions">
/// The <see cref="ODataQueryOptions"/> instance constructed based on the incoming request.
/// The <see cref="IODataQueryOptions"/> instance constructed based on the incoming request.
/// </param>
[SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope",
Justification = "Response disposed after being sent.")]
public virtual void ValidateQuery(HttpRequest request, ODataQueryOptions queryOptions)
public virtual void ValidateQuery(HttpRequest request, IODataQueryOptions queryOptions)
{
if (request == null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ namespace Microsoft.AspNet.OData.Interfaces
/// This defines a composite OData query options that can be used to perform query composition.
/// Currently this only supports $filter, $orderby, $top, $skip, and $count.
/// </summary>
[ODataQueryParameterBinding]
[NonValidatingParameterBinding]
public interface IODataQueryOptions
{
/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ namespace Microsoft.AspNet.OData.Interfaces
/// This defines a composite OData query options that can be used to perform query composition.
/// Currently this only supports $filter, $orderby, $top, $skip.
/// </summary>
[ODataQueryParameterBinding]
public interface IODataQueryOptions<TEntity>
: IODataQueryOptions
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace Microsoft.AspNet.OData
/// <remarks>
/// This is essentially a <see cref="ValidateNeverAttribute"/>.
/// </remarks>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
internal sealed partial class NonValidatingParameterBindingAttribute : ModelBinderAttribute, IPropertyValidationFilter
{
/// <inheritdoc />
Expand Down
4 changes: 2 additions & 2 deletions src/Microsoft.AspNetCore.OData/ODataFeature.cs
Original file line number Diff line number Diff line change
Expand Up @@ -145,9 +145,9 @@ public long? TotalCount
public IDictionary<string, object> RoutingConventionsStore { get; set; } = new Dictionary<string, object>();

/// <summary>
/// Gets or sets the parsed <see cref="ODataQueryOptions"/> of the request.
/// Gets or sets the parsed <see cref="IODataQueryOptions"/> of the request.
/// </summary>
internal ODataQueryOptions QueryOptions { get; set; }
internal IODataQueryOptions QueryOptions { get; set; }

/// <summary>
/// Page size to be used by skiptoken implementation for the top-level resource for the request.
Expand Down
Loading

0 comments on commit fa89897

Please sign in to comment.