@@ -87,10 +87,12 @@ static internal class BindingModelValidator {
87
87
/// <param name="contentTypeDescriptor">
88
88
/// The <see cref="ContentTypeDescriptor"/> object against which to validate the model.
89
89
/// </param>
90
+ /// <param name="attributePrefix">The prefix to apply to the attributes.</param>
90
91
static internal void ValidateModel (
91
92
[ AllowNull ] Type sourceType ,
92
93
[ AllowNull ] MemberInfoCollection < PropertyInfo > properties ,
93
- [ AllowNull ] ContentTypeDescriptor contentTypeDescriptor
94
+ [ AllowNull ] ContentTypeDescriptor contentTypeDescriptor ,
95
+ [ AllowNull ] string attributePrefix = ""
94
96
) {
95
97
96
98
/*------------------------------------------------------------------------------------------------------------------------
@@ -111,7 +113,7 @@ [AllowNull]ContentTypeDescriptor contentTypeDescriptor
111
113
| Validate
112
114
\-----------------------------------------------------------------------------------------------------------------------*/
113
115
foreach ( var property in properties ) {
114
- ValidateProperty ( sourceType , property , contentTypeDescriptor ) ;
116
+ ValidateProperty ( sourceType , property , contentTypeDescriptor , attributePrefix ) ;
115
117
}
116
118
117
119
/*------------------------------------------------------------------------------------------------------------------------
@@ -139,10 +141,12 @@ [AllowNull]ContentTypeDescriptor contentTypeDescriptor
139
141
/// <param name="contentTypeDescriptor">
140
142
/// The <see cref="ContentTypeDescriptor"/> object against which to validate the model.
141
143
/// </param>
144
+ /// <param name="attributePrefix">The prefix to apply to the attributes.</param>
142
145
static internal void ValidateProperty (
143
146
[ AllowNull ] Type sourceType ,
144
147
[ AllowNull ] PropertyInfo property ,
145
- [ AllowNull ] ContentTypeDescriptor contentTypeDescriptor
148
+ [ AllowNull ] ContentTypeDescriptor contentTypeDescriptor ,
149
+ [ AllowNull ] string attributePrefix = ""
146
150
) {
147
151
148
152
/*------------------------------------------------------------------------------------------------------------------------
@@ -156,7 +160,7 @@ [AllowNull]ContentTypeDescriptor contentTypeDescriptor
156
160
| Define variables
157
161
\-----------------------------------------------------------------------------------------------------------------------*/
158
162
var propertyType = property . PropertyType ;
159
- var configuration = new PropertyConfiguration ( property ) ;
163
+ var configuration = new PropertyConfiguration ( property , attributePrefix ) ;
160
164
var compositeAttributeKey = configuration . AttributeKey ;
161
165
var attributeDescriptor = contentTypeDescriptor . AttributeDescriptors . GetTopic ( compositeAttributeKey ) ;
162
166
var childRelationships = new [ ] { RelationshipType . Children , RelationshipType . NestedTopics } ;
@@ -178,7 +182,8 @@ [AllowNull]ContentTypeDescriptor contentTypeDescriptor
178
182
ValidateModel (
179
183
propertyType ,
180
184
childProperties ,
181
- contentTypeDescriptor
185
+ contentTypeDescriptor ,
186
+ configuration . AttributePrefix
182
187
) ;
183
188
return ;
184
189
}
@@ -219,9 +224,9 @@ [AllowNull]ContentTypeDescriptor contentTypeDescriptor
219
224
\-----------------------------------------------------------------------------------------------------------------------*/
220
225
if ( attributeDescriptor == null ) {
221
226
throw new InvalidOperationException (
222
- $ "A { nameof ( sourceType ) } object was provided with a content type set to { contentTypeDescriptor . Key } '. This " +
227
+ $ "A ' { nameof ( sourceType ) } ' object was provided with a content type set to ' { contentTypeDescriptor . Key } '. This " +
223
228
$ "content type does not contain an attribute named '{ compositeAttributeKey } ', as requested by the " +
224
- $ "{ configuration . Property . Name } property. If this property is not intended to be mapped by the " +
229
+ $ "' { configuration . Property . Name } ' property. If this property is not intended to be mapped by the " +
225
230
$ "{ nameof ( ReverseTopicMappingService ) } , then it should be decorated with { nameof ( DisableMappingAttribute ) } ."
226
231
) ;
227
232
}
@@ -242,12 +247,12 @@ [AllowNull]ContentTypeDescriptor contentTypeDescriptor
242
247
listType != null
243
248
) {
244
249
throw new InvalidOperationException (
245
- $ "The { property . Name } on the { sourceType . Name } has been determined to be a { configuration . RelationshipType } , but " +
246
- $ "the generic type { listType . Name } does not implement the { nameof ( ITopicBindingModel ) } interface. This is " +
247
- $ "required for binding models. If this collection is not intended to be mapped to " +
248
- $ "{ ModelType . NestedTopic } then update the definition in the associated { nameof ( ContentTypeDescriptor ) } . If this " +
249
- $ "collection is not intended to be mapped at all, include the { nameof ( DisableMappingAttribute ) } to exclude it from " +
250
- $ "mapping."
250
+ $ "The ' { property . Name } ' property on the ' { sourceType . Name } ' class has been determined to be a " +
251
+ $ "{ configuration . RelationshipType } , but the generic type ' { listType . Name } ' does not implement the " +
252
+ $ "{ nameof ( ITopicBindingModel ) } interface. This is required for binding models. If this collection is not intended " +
253
+ $ "to be mapped as a { ModelType . NestedTopic } then update the definition in the associated " +
254
+ $ "{ nameof ( ContentTypeDescriptor ) } . If this collection is not intended to be mapped at all, include the " +
255
+ $ "{ nameof ( DisableMappingAttribute ) } to exclude it from mapping."
251
256
) ;
252
257
}
253
258
@@ -259,11 +264,12 @@ [AllowNull]ContentTypeDescriptor contentTypeDescriptor
259
264
! typeof ( IRelatedTopicBindingModel ) . IsAssignableFrom ( propertyType )
260
265
) {
261
266
throw new InvalidOperationException (
262
- $ "The { property . Name } on the { sourceType . Name } has been determined to be a { ModelType . Reference } , but " +
263
- $ "the generic type { propertyType . Name } does not implement the { nameof ( IRelatedTopicBindingModel ) } interface. This " +
264
- $ "is required for references. If this property is not intended to be mapped to { ModelType . Reference } then update " +
265
- $ "the definition in the associated { nameof ( ContentTypeDescriptor ) } . If this property is not intended to be mapped " +
266
- $ "at all, include the { nameof ( DisableMappingAttribute ) } to exclude it from mapping."
267
+ $ "The '{ property . Name } ' property on the '{ sourceType . Name } ' class has been determined to be a " +
268
+ $ "{ ModelType . Reference } , but the generic type '{ propertyType . Name } ' does not implement the " +
269
+ $ "{ nameof ( IRelatedTopicBindingModel ) } interface. This is required for references. If this property is not intended " +
270
+ $ "to be mapped as a { ModelType . Reference } then update the definition in the associated " +
271
+ $ "{ nameof ( ContentTypeDescriptor ) } . If this property is not intended to be mapped at all, include the " +
272
+ $ "{ nameof ( DisableMappingAttribute ) } to exclude it from mapping."
267
273
) ;
268
274
}
269
275
@@ -275,12 +281,13 @@ [AllowNull]ContentTypeDescriptor contentTypeDescriptor
275
281
! configuration . AttributeKey . EndsWith ( "Id" , StringComparison . InvariantCulture )
276
282
) {
277
283
throw new InvalidOperationException (
278
- $ "The { property . Name } on the { sourceType . Name } has been determined to be a topic reference, but the generic type " +
279
- $ "{ compositeAttributeKey } does not end in <c>Id</c>. By convention, all topic reference are expected to end " +
280
- $ "in <c>Id</c>. To keep the property name set to { propertyType . Name } , use the { nameof ( AttributeKeyAttribute ) } to " +
281
- $ "specify the name of the topic reference this should map to. If this property is not intended to be mapped at " +
282
- $ "all, include the { nameof ( DisableMappingAttribute ) } . If the { contentTypeDescriptor . Key } defines a topic reference " +
283
- $ "attribute that doesn't follow this convention, then it should be updated."
284
+ $ "The '{ property . Name } ' property on the '{ sourceType . Name } ' class has been determined to be a topic reference, but " +
285
+ $ "the generic type '{ compositeAttributeKey } ' does not end in <c>Id</c>. By convention, all topic reference are " +
286
+ $ "expected to end in <c>Id</c>. To keep the property name set to '{ propertyType . Name } ', use the " +
287
+ $ "{ nameof ( AttributeKeyAttribute ) } to specify the name of the topic reference this should map to. If this property " +
288
+ $ "is not intended to be mapped at all, include the { nameof ( DisableMappingAttribute ) } . If the " +
289
+ $ "'{ contentTypeDescriptor . Key } ' defines a topic reference attribute that doesn't follow this convention, then it " +
290
+ $ "should be updated."
284
291
) ;
285
292
}
286
293
@@ -328,8 +335,9 @@ [AllowNull]Type listType
328
335
\-----------------------------------------------------------------------------------------------------------------------*/
329
336
if ( ! typeof ( IList ) . IsAssignableFrom ( property . PropertyType ) ) {
330
337
throw new InvalidOperationException (
331
- $ "The { property . Name } on the { sourceType . Name } maps to a relationship attribute { attributeDescriptor . Key } , but does" +
332
- $ "not implement { nameof ( IList ) } . Relationships must implement { nameof ( IList ) } or derive from a collection that does."
338
+ $ "The '{ property . Name } ' property on the '{ sourceType . Name } ' class maps to a relationship attribute " +
339
+ $ "'{ attributeDescriptor . Key } ', but does not implement { nameof ( IList ) } . Relationships must implement " +
340
+ $ "{ nameof ( IList ) } or derive from a collection that does."
333
341
) ;
334
342
}
335
343
@@ -338,9 +346,9 @@ [AllowNull]Type listType
338
346
\-----------------------------------------------------------------------------------------------------------------------*/
339
347
if ( ! new [ ] { RelationshipType . Any , RelationshipType . Relationship } . Contains ( configuration . RelationshipType ) ) {
340
348
throw new InvalidOperationException (
341
- $ "The { property . Name } on the { sourceType . Name } maps to a relationship attribute { attributeDescriptor . Key } , but is " +
342
- $ "configured as a { configuration . RelationshipType } . The property should be flagged as either " +
343
- $ "{ nameof ( RelationshipType . Any ) } or { nameof ( RelationshipType . Relationship ) } ."
349
+ $ "The ' { property . Name } ' property on the ' { sourceType . Name } ' class maps to a relationship attribute " +
350
+ $ "' { attributeDescriptor . Key } ', but is configured as a { configuration . RelationshipType } . The property should be " +
351
+ $ "flagged as either { nameof ( RelationshipType . Any ) } or { nameof ( RelationshipType . Relationship ) } ."
344
352
) ;
345
353
}
346
354
@@ -349,11 +357,12 @@ [AllowNull]Type listType
349
357
\-----------------------------------------------------------------------------------------------------------------------*/
350
358
if ( ! typeof ( IRelatedTopicBindingModel ) . IsAssignableFrom ( listType ) ) {
351
359
throw new InvalidOperationException (
352
- $ "The { property . Name } on the { sourceType . Name } has been determined to be a { configuration . RelationshipType } , but " +
353
- $ "the generic type { listType . Name } does not implement the { nameof ( IRelatedTopicBindingModel ) } interface. This is " +
354
- $ "required for binding models. If this collection is not intended to be mapped to { configuration . RelationshipType } " +
355
- $ "then update the definition in the associated { nameof ( ContentTypeDescriptor ) } . If this collection is not intended " +
356
- $ "to be mapped at all, include the { nameof ( DisableMappingAttribute ) } to exclude it from mapping."
360
+ $ "The '{ property . Name } ' property on the '{ sourceType . Name } ' class has been determined to be a " +
361
+ $ "{ configuration . RelationshipType } , but the generic type '{ listType ? . Name } ' does not implement the " +
362
+ $ "{ nameof ( IRelatedTopicBindingModel ) } interface. This is required for binding models. If this collection is not " +
363
+ $ "intended to be mapped as a { configuration . RelationshipType } then update the definition in the associated " +
364
+ $ "{ nameof ( ContentTypeDescriptor ) } . If this collection is not intended to be mapped at all, include the " +
365
+ $ "{ nameof ( DisableMappingAttribute ) } to exclude it from mapping."
357
366
) ;
358
367
}
359
368
0 commit comments