@@ -87,10 +87,12 @@ static internal class BindingModelValidator {
8787 /// <param name="contentTypeDescriptor">
8888 /// The <see cref="ContentTypeDescriptor"/> object against which to validate the model.
8989 /// </param>
90+ /// <param name="attributePrefix">The prefix to apply to the attributes.</param>
9091 static internal void ValidateModel (
9192 [ AllowNull ] Type sourceType ,
9293 [ AllowNull ] MemberInfoCollection < PropertyInfo > properties ,
93- [ AllowNull ] ContentTypeDescriptor contentTypeDescriptor
94+ [ AllowNull ] ContentTypeDescriptor contentTypeDescriptor ,
95+ [ AllowNull ] string attributePrefix = ""
9496 ) {
9597
9698 /*------------------------------------------------------------------------------------------------------------------------
@@ -111,7 +113,7 @@ [AllowNull]ContentTypeDescriptor contentTypeDescriptor
111113 | Validate
112114 \-----------------------------------------------------------------------------------------------------------------------*/
113115 foreach ( var property in properties ) {
114- ValidateProperty ( sourceType , property , contentTypeDescriptor ) ;
116+ ValidateProperty ( sourceType , property , contentTypeDescriptor , attributePrefix ) ;
115117 }
116118
117119 /*------------------------------------------------------------------------------------------------------------------------
@@ -139,10 +141,12 @@ [AllowNull]ContentTypeDescriptor contentTypeDescriptor
139141 /// <param name="contentTypeDescriptor">
140142 /// The <see cref="ContentTypeDescriptor"/> object against which to validate the model.
141143 /// </param>
144+ /// <param name="attributePrefix">The prefix to apply to the attributes.</param>
142145 static internal void ValidateProperty (
143146 [ AllowNull ] Type sourceType ,
144147 [ AllowNull ] PropertyInfo property ,
145- [ AllowNull ] ContentTypeDescriptor contentTypeDescriptor
148+ [ AllowNull ] ContentTypeDescriptor contentTypeDescriptor ,
149+ [ AllowNull ] string attributePrefix = ""
146150 ) {
147151
148152 /*------------------------------------------------------------------------------------------------------------------------
@@ -156,7 +160,7 @@ [AllowNull]ContentTypeDescriptor contentTypeDescriptor
156160 | Define variables
157161 \-----------------------------------------------------------------------------------------------------------------------*/
158162 var propertyType = property . PropertyType ;
159- var configuration = new PropertyConfiguration ( property ) ;
163+ var configuration = new PropertyConfiguration ( property , attributePrefix ) ;
160164 var compositeAttributeKey = configuration . AttributeKey ;
161165 var attributeDescriptor = contentTypeDescriptor . AttributeDescriptors . GetTopic ( compositeAttributeKey ) ;
162166 var childRelationships = new [ ] { RelationshipType . Children , RelationshipType . NestedTopics } ;
@@ -178,7 +182,8 @@ [AllowNull]ContentTypeDescriptor contentTypeDescriptor
178182 ValidateModel (
179183 propertyType ,
180184 childProperties ,
181- contentTypeDescriptor
185+ contentTypeDescriptor ,
186+ configuration . AttributePrefix
182187 ) ;
183188 return ;
184189 }
@@ -219,9 +224,9 @@ [AllowNull]ContentTypeDescriptor contentTypeDescriptor
219224 \-----------------------------------------------------------------------------------------------------------------------*/
220225 if ( attributeDescriptor == null ) {
221226 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 " +
223228 $ "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 " +
225230 $ "{ nameof ( ReverseTopicMappingService ) } , then it should be decorated with { nameof ( DisableMappingAttribute ) } ."
226231 ) ;
227232 }
@@ -242,12 +247,12 @@ [AllowNull]ContentTypeDescriptor contentTypeDescriptor
242247 listType != null
243248 ) {
244249 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."
251256 ) ;
252257 }
253258
@@ -259,11 +264,12 @@ [AllowNull]ContentTypeDescriptor contentTypeDescriptor
259264 ! typeof ( IRelatedTopicBindingModel ) . IsAssignableFrom ( propertyType )
260265 ) {
261266 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."
267273 ) ;
268274 }
269275
@@ -275,12 +281,13 @@ [AllowNull]ContentTypeDescriptor contentTypeDescriptor
275281 ! configuration . AttributeKey . EndsWith ( "Id" , StringComparison . InvariantCulture )
276282 ) {
277283 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."
284291 ) ;
285292 }
286293
@@ -328,8 +335,9 @@ [AllowNull]Type listType
328335 \-----------------------------------------------------------------------------------------------------------------------*/
329336 if ( ! typeof ( IList ) . IsAssignableFrom ( property . PropertyType ) ) {
330337 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."
333341 ) ;
334342 }
335343
@@ -338,9 +346,9 @@ [AllowNull]Type listType
338346 \-----------------------------------------------------------------------------------------------------------------------*/
339347 if ( ! new [ ] { RelationshipType . Any , RelationshipType . Relationship } . Contains ( configuration . RelationshipType ) ) {
340348 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 ) } ."
344352 ) ;
345353 }
346354
@@ -349,11 +357,12 @@ [AllowNull]Type listType
349357 \-----------------------------------------------------------------------------------------------------------------------*/
350358 if ( ! typeof ( IRelatedTopicBindingModel ) . IsAssignableFrom ( listType ) ) {
351359 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."
357366 ) ;
358367 }
359368
0 commit comments