Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 0be3300

Browse files
Revert filter back
1 parent 04172a4 commit 0be3300

File tree

8 files changed

+56
-121
lines changed

8 files changed

+56
-121
lines changed

‎src/JsonApiDotNetCore/Extensions/IQueryableExtensions.cs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
using System.Reflection;
66
using JsonApiDotNetCore.Internal;
77
using JsonApiDotNetCore.Internal.Query;
8-
using JsonApiDotNetCore.Models;
98
using JsonApiDotNetCore.Services;
109

1110
namespace JsonApiDotNetCore.Extensions
@@ -122,7 +121,7 @@ public static IOrderedQueryable<TSource> Sort<TSource>(this IOrderedQueryable<TS
122121
return sortQuery.Direction == SortDirection.Descending
123122
? source.ThenByDescending(attr.GetPropertyPath())
124123
: source.ThenBy(attr.GetPropertyPath());
125-
}
124+
}
126125

127126
public static IOrderedQueryable<TSource> OrderBy<TSource>(this IQueryable<TSource> source, string propertyName)
128127
=> CallGenericOrderMethod(source, propertyName, "OrderBy");
@@ -183,7 +182,7 @@ public static IQueryable<TSource> Filter<TSource>(this IQueryable<TSource> sourc
183182
return source;
184183

185184
if (filterQuery.FilterOperation == FilterOperations.@in || filterQuery.FilterOperation == FilterOperations.nin)
186-
return CallGenericWhereContainsMethod(source,filterQuery);
185+
return CallGenericWhereContainsMethod(source,filterQuery);
187186
else
188187
return CallGenericWhereMethod(source, filterQuery);
189188
}
@@ -216,7 +215,7 @@ private static Expression GetFilterExpressionLambda(Expression left, Expression
216215
case FilterOperations.like:
217216
body = Expression.Call(left, "Contains", null, right);
218217
break;
219-
// {model.Id != 1}
218+
// {model.Id != 1}
220219
case FilterOperations.ne:
221220
body = Expression.NotEqual(left, right);
222221
break;

‎src/JsonApiDotNetCore/Internal/Query/BaseFilterQuery.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,13 @@ public BaseFilterQuery(
1111
: base(jsonApiContext, filterQuery)
1212
{
1313
PropertyValue = filterQuery.Value;
14-
FilterOperation = filterQuery.OperationType;
14+
FilterOperation = GetFilterOperation(filterQuery.Operation);
1515
}
1616

17-
[Obsolete("Use " + nameof(FilterQuery.OperationType) + " instead.")]
18-
protected FilterOperations GetFilterOperation(string prefix)
17+
public string PropertyValue { get; }
18+
public FilterOperations FilterOperation { get; }
19+
20+
private FilterOperations GetFilterOperation(string prefix)
1921
{
2022
if (prefix.Length == 0) return FilterOperations.eq;
2123

@@ -25,7 +27,5 @@ protected FilterOperations GetFilterOperation(string prefix)
2527
return opertion;
2628
}
2729

28-
public string PropertyValue { get; }
29-
public FilterOperations FilterOperation { get; }
3030
}
3131
}

‎src/JsonApiDotNetCore/Internal/Query/FilterQuery.cs

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,35 +6,18 @@ namespace JsonApiDotNetCore.Internal.Query
66
{
77
public class FilterQuery : BaseQuery
88
{
9-
[Obsolete("Use constructor with FilterOperations operationType paremeter. Filter operation should be provided " +
10-
"as enum type, not by string.")]
119
public FilterQuery(string attribute, string value, string operation)
12-
:base(attribute)
13-
{
14-
Key = attribute.ToProperCase();
15-
Value = value;
16-
Operation = operation;
17-
18-
Enum.TryParse(operation, out FilterOperations opertion);
19-
OperationType = opertion;
20-
}
21-
22-
public FilterQuery(string attribute, string value, FilterOperations operationType)
2310
: base(attribute)
2411
{
2512
Key = attribute.ToProperCase();
2613
Value = value;
27-
Operation = operationType.ToString();
28-
OperationType = operationType;
14+
Operation = operation;
2915
}
3016

3117
[Obsolete("Key has been replaced by '" + nameof(Attribute) + "'. Members should be located by their public name, not by coercing the provided value to the internal name.")]
3218
public string Key { get; set; }
3319
public string Value { get; set; }
34-
[Obsolete("Use '" + nameof(OperationType) + "' instead.")]
3520
public string Operation { get; set; }
3621

37-
public FilterOperations OperationType { get; set; }
38-
3922
}
4023
}

‎src/JsonApiDotNetCore/Services/QueryComposer.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ public string Compose(IJsonApiContext jsonApiContext)
3030
private string ComposeSingleFilter(FilterQuery query)
3131
{
3232
var result = "&filter";
33-
result += QueryConstants.OPEN_BRACKET + query.Attribute + QueryConstants.CLOSE_BRACKET + "=" + query.OperationType + QueryConstants.COLON + query.Value;
33+
var operation = string.IsNullOrWhiteSpace(query.Operation) ? query.Operation : query.Operation + ":";
34+
result += QueryConstants.OPEN_BRACKET + query.Attribute + QueryConstants.CLOSE_BRACKET + "=" + operation + query.Value;
3435
return result;
3536
}
3637
}

‎src/JsonApiDotNetCore/Services/QueryParser.cs

Lines changed: 32 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -85,29 +85,32 @@ protected virtual List<FilterQuery> ParseFilterQuery(string key, string value)
8585
var propertyName = key.Split(QueryConstants.OPEN_BRACKET, QueryConstants.CLOSE_BRACKET)[1];
8686

8787
// InArray case
88-
var arrOpVal = ParseFilterOperationAndValue(value);
89-
if (arrOpVal.operation == FilterOperations.@in || arrOpVal.operation == FilterOperations.nin)
90-
queries.Add(new FilterQuery(propertyName, arrOpVal.value, arrOpVal.operation));
88+
string op = GetFilterOperation(value);
89+
if (string.Equals(op, FilterOperations.@in.ToString(), StringComparison.OrdinalIgnoreCase)
90+
|| string.Equals(op, FilterOperations.nin.ToString(), StringComparison.OrdinalIgnoreCase))
91+
{
92+
(var operation, var filterValue) = ParseFilterOperation(value);
93+
queries.Add(new FilterQuery(propertyName, filterValue, op));
94+
}
9195
else
9296
{
9397
var values = value.Split(QueryConstants.COMMA);
9498
foreach (var val in values)
9599
{
96-
var opVal=ParseFilterOperationAndValue(val);
97-
queries.Add(new FilterQuery(propertyName, opVal.value,opVal.operation));
100+
(var operation,varfilterValue)=ParseFilterOperation(val);
101+
queries.Add(new FilterQuery(propertyName, filterValue,operation));
98102
}
99103
}
100104

101105
return queries;
102106
}
103107

104-
[Obsolete("Use " + nameof(ParseFilterOperationAndValue) + " method instead.")]
105108
protected virtual (string operation, string value) ParseFilterOperation(string value)
106109
{
107110
if (value.Length < 3)
108111
return (string.Empty, value);
109112

110-
var operation = GetFilterOperationOld(value);
113+
var operation = GetFilterOperation(value);
111114
var values = value.Split(QueryConstants.COLON);
112115

113116
if (string.IsNullOrEmpty(operation))
@@ -118,63 +121,6 @@ protected virtual (string operation, string value) ParseFilterOperation(string v
118121
return (operation, value);
119122
}
120123

121-
/// <summary>
122-
/// Parse filter operation enum and value by string value.
123-
/// Input string can contain:
124-
/// a) property value only, then FilterOperations.eq and value is returned
125-
/// b) filter prefix and value e.g. "prefix:value", then FilterOperations.prefix and value is returned
126-
/// In case of prefix is provided and is not in FilterOperations enum,
127-
/// invalid filter prefix exception is thrown.
128-
/// </summary>
129-
/// <param name="input"></param>
130-
/// <returns></returns>
131-
protected virtual (FilterOperations operation, string value) ParseFilterOperationAndValue(string input)
132-
{
133-
// value is empty
134-
if (input.Length == 0)
135-
return (FilterOperations.eq, input);
136-
137-
// split value
138-
var values = input.Split(QueryConstants.COLON);
139-
// value only
140-
if (values.Length == 1)
141-
return (FilterOperations.eq, input);
142-
// prefix:value
143-
else if (values.Length == 2)
144-
{
145-
var (operation, succeeded) = GetFilterOperation(values[0]);
146-
if (succeeded == false)
147-
throw new JsonApiException(400, $"Invalid filter prefix '{values[0]}'");
148-
149-
return (operation, values[1]);
150-
}
151-
// some:colon:value OR prefix:some:colon:value (datetime)
152-
else
153-
{
154-
// succeeded = false means no prefix found => some value with colons(datetime)
155-
// succeeded = true means prefix provide + some value with colons(datetime)
156-
var (operation, succeeded) = GetFilterOperation(values[0]);
157-
var value = "";
158-
// datetime
159-
if (succeeded == false)
160-
value = string.Join(QueryConstants.COLON_STR, values);
161-
else
162-
value = string.Join(QueryConstants.COLON_STR, values.Skip(1));
163-
return (operation, value);
164-
}
165-
}
166-
167-
/// <summary>
168-
/// Returns typed operation result and info about parsing success
169-
/// </summary>
170-
/// <param name="operation">String represented operation</param>
171-
/// <returns></returns>
172-
private static (FilterOperations operation, bool succeeded) GetFilterOperation(string operation)
173-
{
174-
var success = Enum.TryParse(operation, out FilterOperations opertion);
175-
return (opertion, success);
176-
}
177-
178124
protected virtual PageQuery ParsePageQuery(PageQuery pageQuery, string key, string value)
179125
{
180126
// expected input = page[size]=10
@@ -247,15 +193,35 @@ protected virtual List<string> ParseFieldsQuery(string key, string value)
247193
var fields = value.Split(QueryConstants.COMMA);
248194
foreach (var field in fields)
249195
{
250-
var attr = GetAttribute(field);
196+
var attr = _controllerContext.RequestEntity
197+
.Attributes
198+
.SingleOrDefault(a => a.Is(field));
199+
200+
if (attr == null) throw new JsonApiException(400, $"'{_controllerContext.RequestEntity.EntityName}' does not contain '{field}'.");
201+
251202
var internalAttrName = attr.InternalAttributeName;
252203
includedFields.Add(internalAttrName);
253204
}
254205

255206
return includedFields;
256207
}
257208

258-
private string GetFilterOperationOld(string value)
209+
protected virtual AttrAttribute GetAttribute(string propertyName)
210+
{
211+
try
212+
{
213+
return _controllerContext
214+
.RequestEntity
215+
.Attributes
216+
.Single(attr => attr.Is(propertyName));
217+
}
218+
catch (InvalidOperationException e)
219+
{
220+
throw new JsonApiException(400, $"Attribute '{propertyName}' does not exist on resource '{_controllerContext.RequestEntity.EntityName}'", e);
221+
}
222+
}
223+
224+
private string GetFilterOperation(string value)
259225
{
260226
var values = value.Split(QueryConstants.COLON);
261227

@@ -269,20 +235,5 @@ private string GetFilterOperationOld(string value)
269235

270236
return operation;
271237
}
272-
273-
protected virtual AttrAttribute GetAttribute(string attribute)
274-
{
275-
try
276-
{
277-
return _controllerContext
278-
.RequestEntity
279-
.Attributes
280-
.Single(attr => attr.Is(attribute));
281-
}
282-
catch (InvalidOperationException e)
283-
{
284-
throw new JsonApiException(400, $"Attribute '{attribute}' does not exist on resource '{_controllerContext.RequestEntity.EntityName}'", e);
285-
}
286-
}
287238
}
288239
}

‎test/JsonApiDotNetCoreExampleTests/Acceptance/Spec/SparseFieldSetTests.cs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ public async Task Can_Select_Sparse_Fieldsets()
3535
{
3636
// arrange
3737
var fields = new List<string> { "Id", "Description", "CreatedDate", "AchievedDate" };
38-
var todoItem = new TodoItem {
38+
var todoItem = new TodoItem
39+
{
3940
Description = "description",
4041
Ordinal = 1,
4142
CreatedDate = DateTime.Now,
@@ -50,7 +51,7 @@ public async Task Can_Select_Sparse_Fieldsets()
5051
// act
5152
var query = _dbContext
5253
.TodoItems
53-
.Where(t=>t.Id == todoItem.Id)
54+
.Where(t=>t.Id == todoItem.Id)
5455
.Select(fields);
5556

5657
var resultSql = StringExtensions.Normalize(query.ToSql());
@@ -68,14 +69,15 @@ public async Task Can_Select_Sparse_Fieldsets()
6869
public async Task Fields_Query_Selects_Sparse_Field_Sets()
6970
{
7071
// arrange
71-
var todoItem = new TodoItem {
72+
var todoItem = new TodoItem
73+
{
7274
Description = "description",
73-
Ordinal = 1,
75+
Ordinal = 1,
7476
CreatedDate = DateTime.Now
7577
};
7678
_dbContext.TodoItems.Add(todoItem);
7779
await _dbContext.SaveChangesAsync();
78-
80+
7981
var builder = new WebHostBuilder()
8082
.UseStartup<Startup>();
8183
var httpMethod = new HttpMethod("GET");

‎test/UnitTests/Services/QueryComposerTests.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public void Can_ComposeEqual_FilterStringForUrl()
2323
var querySet = new QuerySet();
2424
List<FilterQuery> filters = new List<FilterQuery>();
2525
filters.Add(filter);
26-
querySet.Filters=filters;
26+
querySet.Filters=filters;
2727

2828
_jsonApiContext
2929
.Setup(m => m.QuerySet)
@@ -56,7 +56,7 @@ public void Can_ComposeLessThan_FilterStringForUrl()
5656
// act
5757
var filterString = queryComposer.Compose(_jsonApiContext.Object);
5858
// assert
59-
Assert.Equal("&filter[attribute]=le:value&filter[attribute2]=eq:value2", filterString);
59+
Assert.Equal("&filter[attribute]=le:value&filter[attribute2]=value2", filterString);
6060
}
6161

6262
[Fact]
@@ -73,7 +73,7 @@ public void NoFilter_Compose_EmptyStringReturned()
7373
// act
7474
var filterString = queryComposer.Compose(_jsonApiContext.Object);
7575
// assert
76-
Assert.Equal("", filterString);
76+
Assert.Equal("", filterString);
7777
}
7878
}
7979
}

‎test/UnitTests/Services/QueryParser_Tests.cs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
using JsonApiDotNetCore.Configuration;
44
using JsonApiDotNetCore.Controllers;
55
using JsonApiDotNetCore.Internal;
6-
using JsonApiDotNetCore.Internal.Query;
76
using JsonApiDotNetCore.Models;
87
using JsonApiDotNetCore.Services;
98
using Microsoft.AspNetCore.Http;
@@ -100,7 +99,7 @@ public void Filters_Properly_Parses_DateTime_Without_Operation()
10099

101100
// assert
102101
Assert.Equal(dt, querySet.Filters.Single(f => f.Attribute == "key").Value);
103-
Assert.Equal(FilterOperations.eq, querySet.Filters.Single(f => f.Attribute == "key").OperationType);
102+
Assert.Equal(string.Empty, querySet.Filters.Single(f => f.Attribute == "key").Operation);
104103
}
105104

106105
[Fact]
@@ -247,7 +246,7 @@ public void Can_Parse_Fields_Query()
247246
.Returns(new ContextEntity
248247
{
249248
EntityName = type,
250-
Attributes = new List<AttrAttribute>
249+
Attributes = new List<AttrAttribute>
251250
{
252251
new AttrAttribute(attrName)
253252
{
@@ -286,7 +285,7 @@ public void Throws_JsonApiException_If_Field_DoesNotExist()
286285
.Returns(new ContextEntity
287286
{
288287
EntityName = type,
289-
Attributes = new List<AttrAttribute>()
288+
Attributes = new List<AttrAttribute>()
290289
});
291290

292291
var queryParser = new QueryParser(_controllerContextMock.Object, new JsonApiOptions());

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /