2

I'm not sure what I'm doing wrong here. The default display template for a model I'm using is not being used.

This code is in my main action view:

@if (Model.EmbeddedMediaModels != null)
{
    foreach (var mediaItem in Model.EmbeddedMediaModels)
    {
        BitmapFigureModel bitmap = mediaItem as BitmapFigureModel;
        if (bitmap != null)
        {
            var mm = ModelMetadata.FromLambdaExpression(p => bitmap, this.ViewData);

            var modelTypeName = mm.ModelType.Name; // = "BitmapFigureModel"

            // Neither resolve the template.

            // Html.DisplayFor(m => bitmap);
            Html.DisplayFor(m => bitmap, modelTypeName);
        }
    }
}

The Model.EmbeddedMediaModels property is a collection of EmbeddedMediaModel base types, at present it just contains one object, a BitmapFigureModel which derives from EmbeddedMediaModel.

It's tempting to think that this is confusing matters, but the ModelMetadata instance retrieved is quite able to see the correct BitmapFigureModel model type.

Besides, even if I specify the model type name in the call to DisplayFor it still doesn't work.

And here's proof that a correctly-named display template partial view is in place.

enter image description here

What am I doing wrong?

4
  • 1
    Out of interest have you tried testing the DisplayFor with a test instance of BitmapFigureModel (e.g. Html.DisplayFor(m => new BitmapFigureModel {/*fill in properties*/})) to see if it's a problem with this specific case or a more general problem with resolving the Display Template? Commented Apr 24, 2014 at 14:56
  • @DaveParsons Dude, this is a good call because its led to this error which tells me I cannot do what I'm trying to (contrary to MVC team-member blog that says I can). I get "Templates can be used only with field access, property access, single-dimension array index, or single-parameter custom indexer expressions." Commented Apr 24, 2014 at 15:09
  • @DaveParsons If you want to post a proper answer, I'll thumb it up and then add my own answer with the error. Commented Apr 24, 2014 at 15:11
  • 1
    I didn't know the answer just helped debug; I wouldn't be putting anything particularly useful into an answer. Just glad it helped you find the issue :) Commented Apr 24, 2014 at 15:18

2 Answers 2

2

Contrary to the advice from Brad Wilson (ASP.NET team):

The expression-based versions are primarily used for pulling values from the model (they are parametrized by the current model, as shown in the example above). They can also be used for pulling values from some source other than the model or ViewData (for example, with an expression like “model => someOtherValue” which ignores the model entirely). This makes them useful in loops.

http://bradwilson.typepad.com/blog/2009/10/aspnet-mvc-2-templates-part-1-introduction.html

It actually seems that its not possible to "ignore the model entirely". In the comments under my question DaveParsons suggests to experiment by just newing-up a model instance and passing it into DisplayFor, this leads to the error:

Templates can be used only with field access, property access, single-dimension array index, or single-parameter custom indexer expressions.

So it appears that I should stop being a smarty-pants and just use Html.Partial as Ehsan Sajjad suggests.

Sign up to request clarification or add additional context in comments.

2 Comments

You should mark your own answer as answered. Good explanation
Thanks, I will do. SO forces a 2 day period before I can mark it, presumably to allow others to jump in with better answers and for the voting to take place.
1

do like this:

@Html.DisplayFor(m => mediaItem.Name)

if you want to load the partial view:

@Html.Partial("~/Views/Shared/DisplayTemplates/BitmapFigureModel.cshtml", mediaItem)

or:

@Html.RenderPartial("~/Views/Shared/DisplayTemplates/BitmapFigureModel.cshtml", mediaItem)

In your BitmapFigureModel.cshtml:

@model BitmapFigureModel

7 Comments

Shouldn't it be just Html.DisplayFor(m => mediaItem)? bitmap is just the casted mediaItem...
If I don't cast the mediaItem then the MediaMetadata sees it as the wrong model type.
Obviously, your first line of code is semantically completely different to my intentions. Are you implying that I cannot use DisplayFor for displaying any arbitrary object, i.e. that it must be a property on the current model?
you are trying to display label for the property or you are trying to load partia view with the inner model
I'm just trying to display the complex object model using its default template.
|

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.