9
9
using JsonApiDotNetCore . Models ;
10
10
using Microsoft . AspNetCore . Http ;
11
11
12
- namespace JsonApiDotNetCore . Services
13
- {
14
- public interface IQueryParser
15
- {
12
+ namespace JsonApiDotNetCore . Services {
13
+ public interface IQueryParser {
16
14
QuerySet Parse ( IQueryCollection query ) ;
17
15
}
18
16
19
- public class QueryParser : IQueryParser
20
- {
17
+ public class QueryParser : IQueryParser {
21
18
private readonly IControllerContext _controllerContext ;
22
19
private readonly JsonApiOptions _options ;
23
20
24
21
public QueryParser (
25
22
IControllerContext controllerContext ,
26
- JsonApiOptions options )
27
- {
23
+ JsonApiOptions options ) {
28
24
_controllerContext = controllerContext ;
29
25
_options = options ;
30
26
}
31
27
32
- public virtual QuerySet Parse ( IQueryCollection query )
33
- {
28
+ public virtual QuerySet Parse ( IQueryCollection query ) {
34
29
var querySet = new QuerySet ( ) ;
35
- var disabledQueries = _controllerContext . GetControllerAttribute < DisableQueryAttribute > ( ) ? . QueryParams ?? QueryParams . None ;
30
+ var disabledQueries = _controllerContext . GetControllerAttribute < DisableQueryAttribute > ( ) ? . QueryParams ?? QueryParams . None ;
36
31
37
- foreach ( var pair in query )
38
- {
39
- if ( pair . Key . StartsWith ( "filter" ) )
40
- {
32
+ foreach ( var pair in query ) {
33
+ if ( pair . Key . StartsWith ( "filter" ) ) {
41
34
if ( disabledQueries . HasFlag ( QueryParams . Filter ) == false )
42
35
querySet . Filters . AddRange ( ParseFilterQuery ( pair . Key , pair . Value ) ) ;
43
36
continue ;
44
37
}
45
38
46
- if ( pair . Key . StartsWith ( "sort" ) )
47
- {
39
+ if ( pair . Key . StartsWith ( "sort" ) ) {
48
40
if ( disabledQueries . HasFlag ( QueryParams . Sort ) == false )
49
41
querySet . SortParameters = ParseSortParameters ( pair . Value ) ;
50
42
continue ;
51
43
}
52
44
53
- if ( pair . Key . StartsWith ( "include" ) )
54
- {
45
+ if ( pair . Key . StartsWith ( "include" ) ) {
55
46
if ( disabledQueries . HasFlag ( QueryParams . Include ) == false )
56
47
querySet . IncludedRelationships = ParseIncludedRelationships ( pair . Value ) ;
57
48
continue ;
58
49
}
59
50
60
- if ( pair . Key . StartsWith ( "page" ) )
61
- {
51
+ if ( pair . Key . StartsWith ( "page" ) ) {
62
52
if ( disabledQueries . HasFlag ( QueryParams . Page ) == false )
63
53
querySet . PageQuery = ParsePageQuery ( querySet . PageQuery , pair . Key , pair . Value ) ;
64
54
continue ;
65
55
}
66
56
67
- if ( pair . Key . StartsWith ( "fields" ) )
68
- {
57
+ if ( pair . Key . StartsWith ( "fields" ) ) {
69
58
if ( disabledQueries . HasFlag ( QueryParams . Fields ) == false )
70
59
querySet . Fields = ParseFieldsQuery ( pair . Key , pair . Value ) ;
71
60
continue ;
@@ -78,26 +67,24 @@ public virtual QuerySet Parse(IQueryCollection query)
78
67
return querySet ;
79
68
}
80
69
81
- protected virtual List < FilterQuery > ParseFilterQuery ( string key , string value )
82
- {
70
+ protected virtual List < FilterQuery > ParseFilterQuery ( string key , string value ) {
83
71
// expected input = filter[id]=1
84
72
// expected input = filter[id]=eq:1
85
73
var queries = new List < FilterQuery > ( ) ;
86
74
87
- var propertyName = key . Split ( '[' , ']' ) [ 1 ] . ToProperCase ( ) ;
75
+ var propertyName = key . Split ( '[' , ']' ) [ 1 ] . ToProperCase ( ) ;
88
76
89
77
var values = value . Split ( ',' ) ;
90
- foreach ( var val in values )
91
- {
92
- ( var operation , var filterValue ) = ParseFilterOperation ( val ) ;
78
+ foreach ( var val in values ) {
79
+ ( var operation ,
80
+ var filterValue ) = ParseFilterOperation ( val ) ;
93
81
queries . Add ( new FilterQuery ( propertyName , filterValue , operation ) ) ;
94
82
}
95
83
96
84
return queries ;
97
85
}
98
86
99
- protected virtual ( string operation , string value ) ParseFilterOperation ( string value )
100
- {
87
+ protected virtual ( string operation , string value ) ParseFilterOperation ( string value ) {
101
88
if ( value . Length < 3 )
102
89
return ( string . Empty , value ) ;
103
90
@@ -116,13 +103,12 @@ protected virtual (string operation, string value) ParseFilterOperation(string v
116
103
return ( prefix , value ) ;
117
104
}
118
105
119
- protected virtual PageQuery ParsePageQuery ( PageQuery pageQuery , string key , string value )
120
- {
106
+ protected virtual PageQuery ParsePageQuery ( PageQuery pageQuery , string key , string value ) {
121
107
// expected input = page[size]=10
122
108
// page[number]=1
123
109
pageQuery = pageQuery ?? new PageQuery ( ) ;
124
110
125
- var propertyName = key . Split ( '[' , ']' ) [ 1 ] ;
111
+ var propertyName = key . Split ( '[' , ']' ) [ 1 ] ;
126
112
127
113
if ( propertyName == "size" )
128
114
pageQuery . PageSize = Convert . ToInt32 ( value ) ;
@@ -134,28 +120,31 @@ protected virtual PageQuery ParsePageQuery(PageQuery pageQuery, string key, stri
134
120
135
121
// sort=id,name
136
122
// sort=-id
137
- protected virtual List < SortQuery > ParseSortParameters ( string value )
138
- {
123
+ protected virtual List < SortQuery > ParseSortParameters ( string value ) {
124
+ const char SORT_DELIMITER = ',' ;
125
+ const char DESCENDING_SORT_OPERATOR = '-' ;
126
+
139
127
var sortParameters = new List < SortQuery > ( ) ;
140
- value . Split ( ',' ) . ToList ( ) . ForEach ( p =>
141
- {
128
+ var sortSegments = value . Split ( SORT_DELIMITER ) ;
129
+ foreach ( var sortSegment in sortSegments ) {
130
+
131
+ var propertyName = sortSegment ;
142
132
var direction = SortDirection . Ascending ;
143
- if ( p [ 0 ] == '-' )
144
- {
133
+
134
+ if ( sortSegment [ 0 ] == DESCENDING_SORT_OPERATOR ) {
145
135
direction = SortDirection . Descending ;
146
- p = p . Substring ( 1 ) ;
136
+ propertyName = propertyName . Substring ( 1 ) ;
147
137
}
148
138
149
- var attribute = GetAttribute ( p . ToProperCase ( ) ) ;
139
+ var attribute = GetAttribute ( propertyName ) ;
150
140
151
141
sortParameters . Add ( new SortQuery ( direction , attribute ) ) ;
152
- } ) ;
142
+ } ;
153
143
154
144
return sortParameters ;
155
145
}
156
146
157
- protected virtual List < string > ParseIncludedRelationships ( string value )
158
- {
147
+ protected virtual List < string > ParseIncludedRelationships ( string value ) {
159
148
if ( value . Contains ( "." ) )
160
149
throw new JsonApiException ( 400 , "Deeply nested relationships are not supported" ) ;
161
150
@@ -164,19 +153,17 @@ protected virtual List<string> ParseIncludedRelationships(string value)
164
153
. ToList ( ) ;
165
154
}
166
155
167
- protected virtual List < string > ParseFieldsQuery ( string key , string value )
168
- {
156
+ protected virtual List < string > ParseFieldsQuery ( string key , string value ) {
169
157
// expected: fields[TYPE]=prop1,prop2
170
- var typeName = key . Split ( '[' , ']' ) [ 1 ] ;
158
+ var typeName = key . Split ( '[' , ']' ) [ 1 ] ;
171
159
172
160
var includedFields = new List < string > { "Id" } ;
173
161
174
162
if ( typeName != _controllerContext . RequestEntity . EntityName )
175
163
return includedFields ;
176
164
177
165
var fields = value . Split ( ',' ) ;
178
- foreach ( var field in fields )
179
- {
166
+ foreach ( var field in fields ) {
180
167
var internalAttrName = _controllerContext . RequestEntity
181
168
. Attributes
182
169
. SingleOrDefault ( attr => attr . PublicAttributeName == field )
@@ -187,12 +174,11 @@ protected virtual List<string> ParseFieldsQuery(string key, string value)
187
174
return includedFields ;
188
175
}
189
176
190
- protected virtual AttrAttribute GetAttribute ( string propertyName )
191
- => _controllerContext
192
- . RequestEntity
193
- . Attributes
194
- . FirstOrDefault ( attr =>
195
- string . Equals ( attr . InternalAttributeName , propertyName , StringComparison . OrdinalIgnoreCase )
196
- ) ;
177
+ protected virtual AttrAttribute GetAttribute ( string propertyName ) => _controllerContext
178
+ . RequestEntity
179
+ . Attributes
180
+ . FirstOrDefault ( attr =>
181
+ string . Equals ( attr . PublicAttributeName , propertyName , StringComparison . OrdinalIgnoreCase )
182
+ ) ;
197
183
}
198
- }
184
+ }
0 commit comments