3

I have the following 3 Schemas:

  1. Schema title LinkedSchema
    root element name: LinkedSchema
    1 text field: "txtField"

  2. Schema title LinkedSchema2
    root element name: LinkedSchema2
    1 number field: numField

  3. Schema title TestLinkContainer
    root element name: TestLinkContainer
    1 multivalue Component link field: components with allowed schemas of 1. and 2.

They all have the core namespace ("http://www.sdl.com/web/schemas/core")

I have the following models:

[SemanticEntity(CoreVocabulary, EntityName = "LinkedSchema")]
public partial class LinkedSchemaModel : EntityModel
{
    [SemanticProperty("txtField")]
    public string Text { get; set; }
}


[SemanticEntity(CoreVocabulary, EntityName = "LinkedSchema2")]
public partial class LinkedSchemaModel2 : EntityModel
{
    [SemanticProperty("numField")]
    public double Number { get; set; }
}


[SemanticEntity(CoreVocabulary, "TestLinkContainer")]
public partial class TestLinkContainer : EntityModel
{
    [SemanticProperty("components")]
    public List<EntityModel> Comps { get; set; }
}

SDLWebAreaRegistration:

RegisterViewModel("TestLinkContainer", typeof(TestLinkContainer));
RegisterViewModel(typeof(LinkedSchemaModel));
RegisterViewModel(typeof(LinkedSchemaModel2));

When accessing a page which has a CT which is linked to 'TestLinkContainer' entity view, I get the following error in the browser:

A problem occurred while rendering this section
Unable to map field 'components' to property of type 'Sdl.Web.Common.Models.EntityModel'.
Cannot map a Component to type 'Sdl.Web.Common.Models.EntityModel'. The type must be String or a subclass of EntityModel.

Error from the log file:

ERROR - Unable to map field 'components' to property of type 'Sdl.Web.Common.Models.EntityModel'.
Sdl.Web.Common.DxaException: Unable to map field 'components' to property of type 'Sdl.Web.Common.Models.EntityModel'. ---> Sdl.Web.Common.DxaException: Cannot map a Component to type 'Sdl.Web.Common.Models.EntityModel'. The type must be String or a subclass of EntityModel.
   at Sdl.Web.Tridion.Mapping.DefaultModelBuilder.MapComponent(IComponent component, Type modelType, Localization localization)
   at Sdl.Web.Tridion.Mapping.DefaultModelBuilder.MapFieldValues(IField field, Type modelType, Boolean multival, MappingData mapData)
   --- End of inner exception stack trace ---
   at Sdl.Web.Tridion.Mapping.DefaultModelBuilder.MapFieldValues(IField field, Type modelType, Boolean multival, MappingData mapData)
   at Sdl.Web.Tridion.Mapping.DefaultModelBuilder.CreateViewModel(MappingData mappingData)
   at Sdl.Web.Tridion.Mapping.DefaultModelBuilder.BuildEntityModel(EntityModel& entityModel, IComponent component, Type baseModelType, Localization localization)
   at Sdl.Web.Tridion.Mapping.DefaultModelBuilder.BuildEntityModel(EntityModel& entityModel, IComponentPresentation cp, Localization localization)
   at Sdl.Web.Tridion.Mapping.ModelBuilderPipeline.CreateEntityModel(IComponentPresentation cp, Localization localization)
   at Sdl.Web.Tridion.Mapping.DefaultModelBuilder.BuildPageModel(PageModel& pageModel, IPage page, IEnumerable`1 includes, Localization localization)

What am I doing wrong? I have read through a couple of related questions, namely:
How to map Model for a Schema, which has multiple value Component link field with multiple allowed Schemas?
Creating custom Media Items in DXA 1.1
How to map PascalCasing schema field to TRI Model Property

and in Rick's answers he states

"ensure you have a proper semantic mappings to the Schemas on type level"

but what exactly qualifies as "proper semantic mapping"? Is it just a mapping of fields (SemanticProperty("fieldName"), or does it have to be in a specific format, semantic entity + semantic property using the prefixes etc. Does this issue have to do anything with "Specifying semantics on Schemas"?

"if no semantic mapping can be resolved, a warning will be logged and the model mapping will fallback to the type of the property, which will result in the mentioned error if the property type is abstract. So: set the log level to WARNING (or DEBUG) and check whether you see such a warning. Then check the semantic mapping of your View Model type."

There is no such warning present.

Thank you in advance.

4

There is only one "problem" in your implementation, which the error message is pointing out: The type must be String or a subclass of EntityModel.

In your case, you are using class EntityModel itself. Admittedly, this shouldn't be an issue in your implementation, since through semantic mapping it would always resolve a subclass anyways, so the check might be considered a bit too strict.

On the other hand, you could argue that use of List<EntityModel> is a bit too loosely typed; you don't really want to allow any Entity Model, right?

So, the trick is to ensure you create your own (abstract) base class for all Entity Model types you do expect. The base class should inherit from EntityModel and the expected concrete types should inherit from the base class instead of from EntityModel directly.

Finally, you use List<MyBaseClass> instead of List<EntityModel>.

  • Thanks Rick, helpful as always. Tested and confirmed working. One follow-up question though, for this to work should all the involved models be decorated with the semantic entity/property attributes? – Atila Sos Oct 10 '16 at 9:16
  • No, the SemanticEntity/Property attributes are not needed per se. Entity mapping can be done implicitly if your class name matches the root element name of your Schema. Property mapping can be done implicitly if the property name matches the field name (camel cased). – Rick Pannekoek Oct 10 '16 at 17:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.