3

I'm trying to refactor several views by moving duplicated code into a partial. However I'm getting several errors, implying that the view doesn't understand the Model data that I'm passing through.

This is how I'm calling the partial from the parent view:

@Html.Partial("_HeroBanner", Model);

And this is the line in the partial that's causing problems:

<div class="header-title" @Html.DxaPropertyMarkup(() => @Model.PageDetails.PageTitle)>

The line works fine when it's in the parent view, but when it's in a partial I get this error:

...\_HeroBanner.cshtml(19): error CS1963: An expression tree may not contain a dynamic operation

Am I missing something? I'm very new to .NET so this may be an easy fix. I can supply complete code samples if necessary.

Edit: It works if I specify the same model as the parent uses, but this only works in a specific instance. This is insufficient, as the partial needs to be called from several different parent views, which all use different models. Is this possible?

3
  • Did you also specify an @model <model classname> on top of your partial, just like you had in your original view ? Commented Aug 17, 2017 at 9:59
  • Adding to Haralds comment, and what Model did you specify in your partial view? Commented Aug 17, 2017 at 10:01
  • I've updated the question to clarify. Commented Aug 17, 2017 at 10:12

1 Answer 1

2

I don't think it is possible to create a view which works for several models in DXA, as the model mapping logic can't work then and the view registration will be messed up.

We do however use something similar in DXA with the Teaser Model. Take a look at https://github.com/sdl/dxa-modules/blob/release/1.7/webapp-net/Core/Models/Entity/Teaser.cs

The Teaser Model is basically mapped to the Teaser Schema, but also to Image, Article and Place, and the fields are mapped accordingly.

So for this to work, you must define a Model like the Teaser which will contains a semantic mapping to the different Models you want to use for this partial view.

Examples of usage of the Teaser Model in its view and partial view can be seen here: https://github.com/sdl/dxa-modules/blob/release/1.7/webapp-net/Core/Areas/Core/Views/Entity/Teaser.cshtml and https://github.com/sdl/dxa-modules/blob/release/1.7/webapp-net/Core/Areas/Core/Views/Entity/Partials/Teaser.cshtml

3
  • Thanks Bart - can I ask further? Apologies if this is a silly question. I'm from a PHP MVC background (Laravel specifically), where a view doesn't need to know anything about the data it's displaying - any view can be called from any controller (the mapping may not work correctly, of course, in which case you'll get an error). In other words, views are "dumb". Is this different in DXA? Maybe there's a different approach: my partial only requires a few bits of data, mainly strings and bools. Is there a way to "gather" this data in the parent view(s) and pass it to the partial? Commented Aug 17, 2017 at 13:03
  • @wiiiiilllllll DXA is different specifically in the sense of its automagic model mapping, due to this behaviour we need to have a one to one relation between the view and the model, since we define the view to be used on the CM side for each Template, and the model then comes from the view mapping registry. As mentioned the way to gather your data is by defining a model which can map to the different models you want to use in there which isn't all that much work of you look at it. The views are still dumb themselves, but they are written for a specific model. Commented Aug 17, 2017 at 13:38
  • Understood - thanks. I'll check out the Teaser Model. Commented Aug 17, 2017 at 14:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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