@@ -41,11 +41,12 @@ private void OnSerialize(StreamingContext context)
41
41
42
42
RepopulateRecursively ( ctx . HypermediaResolver , curies ) ;
43
43
44
- Links = curies
45
- . Distinct ( CuriesLink . EqualityComparer )
46
- . Select ( x => x . ToLink ( ) )
47
- . Union ( Links )
48
- . ToList ( ) ;
44
+ if ( Links != null )
45
+ Links = curies
46
+ . Distinct ( CuriesLink . EqualityComparer )
47
+ . Select ( x => x . ToLink ( ) )
48
+ . Union ( Links )
49
+ . ToList ( ) ;
49
50
50
51
ctx . IsRoot = false ;
51
52
}
@@ -123,7 +124,8 @@ private void RepopulateRecursively(IHypermediaResolver resolver, List<CuriesLink
123
124
property . SetValue ( this , null , null ) ;
124
125
}
125
126
126
- curies . AddRange ( Links . Where ( l => l . Curie != null ) . Select ( l => l . Curie ) ) ;
127
+ if ( Links != null )
128
+ curies . AddRange ( Links . Where ( l => l . Curie != null ) . Select ( l => l . Curie ) ) ;
127
129
128
130
if ( Embedded . Count == 0 )
129
131
Embedded = null ; // avoid the property from being serialized ...
@@ -138,39 +140,45 @@ void ProcessPropertyValue(IHypermediaResolver resolver, List<CuriesLink> curies,
138
140
139
141
var embeddedResource = new EmbeddedResource { IsSourceAnArray = true } ;
140
142
141
- foreach ( var resourceItem in resourceList )
142
- {
143
- embeddedResource . Resources . Add ( resourceItem ) ;
143
+ foreach ( var resourceItem in resourceList )
144
+ {
145
+ embeddedResource . Resources . Add ( resourceItem ) ;
144
146
145
- var representation = resourceItem as Representation ;
147
+ var representation = resourceItem as Representation ;
146
148
147
- if ( representation == null )
148
- continue ;
149
+ if ( representation == null )
150
+ continue ;
149
151
150
- representation . RepopulateRecursively ( resolver , curies ) ; // traverse ...
151
- Links . Add ( representation . ToLink ( resolver ) ) ; // add a link to embedded to the container ...
152
- }
152
+ representation . RepopulateRecursively ( resolver , curies ) ; // traverse ...
153
+ var link = representation . ToLink ( resolver ) ;
154
+
155
+ if ( link != null )
156
+ Links . Add ( link ) ; // add a link to embedded to the container ...
157
+ }
153
158
154
- Embedded . Add ( embeddedResource ) ;
159
+ Embedded . Add ( embeddedResource ) ;
155
160
}
156
161
157
- void ProcessPropertyValue ( IHypermediaResolver resolver , List < CuriesLink > curies , IResource resource )
158
- {
159
- var embeddedResource = new EmbeddedResource { IsSourceAnArray = false } ;
160
- embeddedResource . Resources . Add ( resource ) ;
162
+ void ProcessPropertyValue ( IHypermediaResolver resolver , List < CuriesLink > curies , IResource resource )
163
+ {
164
+ var embeddedResource = new EmbeddedResource { IsSourceAnArray = false } ;
165
+ embeddedResource . Resources . Add ( resource ) ;
161
166
162
- Embedded . Add ( embeddedResource ) ;
167
+ Embedded . Add ( embeddedResource ) ;
163
168
164
- var representation = resource as Representation ;
169
+ var representation = resource as Representation ;
165
170
166
- if ( representation == null )
167
- return ;
171
+ if ( representation == null )
172
+ return ;
168
173
169
- representation . RepopulateRecursively ( resolver , curies ) ; // traverse ...
170
- Links . Add ( representation . ToLink ( resolver ) ) ; // add a link to embedded to the container ...
171
- }
174
+ representation . RepopulateRecursively ( resolver , curies ) ; // traverse ...
175
+ var link = representation . ToLink ( resolver ) ;
176
+
177
+ if ( link != null )
178
+ Links . Add ( link ) ; // add a link to embedded to the container ...
179
+ }
172
180
173
- void ResolveAndAppend ( IHypermediaResolver resolver , Type type )
181
+ void ResolveAndAppend ( IHypermediaResolver resolver , Type type )
174
182
{
175
183
// We need reflection here, because appenders are of type IHypermediaAppender<T> whilst we define this logic in the base class of T
176
184
@@ -180,31 +188,49 @@ void ResolveAndAppend(IHypermediaResolver resolver, Type type)
180
188
genericMethod . Invoke ( this , new object [ ] { this , resolver } ) ;
181
189
}
182
190
183
- protected static void Append < T > ( IResource resource , IHypermediaResolver resolver ) where T : class , IResource // called using reflection ...
184
- {
185
- var typed = resource as T ;
191
+ protected static void Append < T > ( IResource resource , IHypermediaResolver resolver ) where T : class , IResource
192
+ // called using reflection ...
193
+ {
194
+ var typed = resource as T ;
186
195
187
- var appender = resolver . ResolveAppender ( typed ) ;
188
- var configured = resolver . ResolveLinks ( typed ) . ToList ( ) ;
196
+ var appender = resolver . ResolveAppender ( typed ) ;
197
+ var configured = resolver . ResolveLinks ( typed ) . ToList ( ) ;
198
+ var link = resolver . ResolveSelf ( typed ) ;
189
199
190
- configured . Insert ( 0 , resolver . ResolveSelf ( typed ) ) ;
200
+ if ( link != null )
201
+ configured . Insert ( 0 , link ) ;
191
202
192
- appender . Append ( typed , configured ) ;
193
- }
203
+ if ( configured . Any ( ) && ( appender != null ) )
204
+ {
205
+ if ( typed . Links == null )
206
+ typed . Links = new List < Link > ( ) ; // make sure resource.Links.Add() can safely be called inside the appender
207
+
208
+ appender . Append ( typed , configured ) ;
194
209
195
- internal static bool IsEmbeddedResourceType ( Type type )
210
+ if ( ( typed . Links != null ) && ! typed . Links . Any ( ) )
211
+ typed . Links = null ; // prevent _links property serialisation
212
+ }
213
+ }
214
+
215
+ internal static bool IsEmbeddedResourceType ( Type type )
196
216
{
197
217
return typeof ( IResource ) . IsAssignableFrom ( type ) ||
198
218
typeof ( IEnumerable < IResource > ) . IsAssignableFrom ( type ) ;
199
219
}
200
220
201
221
public void RepopulateHyperMedia ( )
202
222
{
203
- CreateHypermedia ( ) ;
223
+ if ( Links == null )
224
+ Links = new List < Link > ( ) ; // make sure resource.Links.Add() can safely be called inside the overload
204
225
205
- if ( ! string . IsNullOrEmpty ( Href ) && Links . Count ( l=> l . Rel == "self" ) == 0 )
226
+ CreateHypermedia ( ) ;
227
+
228
+ if ( ! string . IsNullOrEmpty ( Href ) && Links . Count ( l=> l . Rel == "self" ) == 0 )
206
229
Links . Insert ( 0 , new Link { Rel = "self" , Href = Href } ) ;
207
- }
230
+
231
+ if ( ( Links != null ) && ! Links . Any ( ) )
232
+ Links = null ; // prevent _links property serialisation
233
+ }
208
234
209
235
[ JsonIgnore ]
210
236
public virtual string Rel { get ; set ; }
0 commit comments