Accessing custom image properies in Templates via ModelsBuidler

I added a custom property “umbracoAltText” to the image media data type as a text string and am now trying to access it in my templates via the Model. I tried @Model.ImagePropertyName.umbracoAltText but it is not recognized, in fact none of the “label” properties like width or height are.

I saw the docs page at Rendering Media | CMS 17.latest (LTS) | Umbraco Documentation where they cast the image to an Umbraco.Media type but I was hoping there might be some way to access the properties from within the model and not have to cast as will be really annoying to have to cast lots of images on a single page.

Hi @Eaglef90

The media property will be of type MediaWithCrops:

To get the underlying image, you will need to do something like this:

var image = Model.MyImageProperty.Content as Image;

if (image != null)
{
    var altText = image.UmbracoAltText;
}

You could create an extension method if you want to avoid doing this in multiple places.

Justin

Also, you can directly do this but it would bypass the strongly typed models.

@Model.MyImageProperty?.Value<string>("umbracoAltText")

So I do have to cast each image, very annoying if the page has say 10 images in it then I have to cast every single image. I guess for ease of usage I will have to use the Value command. Would I be correct that if an editor forgets to add a value to the property calling it like in your example would simply print out nothing or would it fail and error out?

You can create an extensions method, something like this:

public static string? AltText(this MediaWithCrops? media)
{
    if (media?.Content is not Image image)
    {
        return null;
    }

    return string.IsNullOrWhiteSpace(image.UmbracoAltText)
        ? image.Name
        : image.UmbracoAltText;
}

Then just call:

@Model.MyImageProperty.AltText()

Justin

Sorry for this stupidity but I have never heard of an “extensions method” doing a bit of digging it seems like this is a c# file I create with your example code and I can get away with just adding an @using statement in the ViewImports.cshtml file. Is that correct or is there something I need to do to get Umbraco to wire it up?

Hi @Eaglef90

Yes, it’s a C# thing - you add it into a static class and add the namespace to your view and you can use it.

There are plenty of examples online.

Justin

nicer to add that extension method as @justin-nevitech says.. but you can also define functions in views (though not recommended with separation of concerns in MVC)

@functions {
    void AltText(MediaWithCrops? media)
    {
         ....
   }
}

you could also have a centralised partial view for all your image rendering..

<partial name="imagewithAltText" model="Image">

or indeed a view component (more boilerplate to create)… if you needed to do something procedurally with it. or easily pass multiple params (though you can pass a view-data model into a partial too)
<partial name="blockgrid/bs_area" model="area" view-data='new ViewDataDictionary(ViewData) { { "bsBreakpointCols", bsBreakpointCols } }' />

<vc:my-view-component model="Model" offer-guid='Model.Parent()?.Key' />

All depends on your use case and preference.

I got this setup and it works perfectly. Thank you very much for the help