Render a product attribute safely in a Znode 9 Razor view
Render a published product attribute through a small Razor view model, handle empty text, and retain HTML encoding and locale-aware display labels.
In this guide
- published product data
- view-model mapper
- Razor view
- encoded browser text
Keep lookup out of markup
Before rendering, map the selected product's published SurfaceFinish value into ProductFinishViewModel. Resolve an option's localized display label in that mapping. The Razor partial only decides whether there is useful text and renders a definition list.
Save the partial in the custom Znode 9 theme and make ProductFinishViewModel available through its namespace imports or a fully qualified @model name. This is classic ASP.NET MVC Razor on Framework 4.8.
_ProductFinish.cshtml cshtml
@model ProductFinishViewModel
@if (Model != null && !string.IsNullOrWhiteSpace(Model.SurfaceFinish))
{
<dl class="product-specification">
<dt>Surface finish</dt>
<dd>@Model.SurfaceFinish</dd>
</dl>
}
@* Razor HTML-encodes Model.SurfaceFinish by default. *@
A SurfaceFinish value of 'Matte' renders the field label and that value. A null, empty, or whitespace-only value renders no definition list. If the value contains '<script>', Razor encodes it as visible text rather than executing markup.
Define the view model
The view model contains one named property because the partial needs one display value. Populate it in the theme adapter using the current product and locale, then pass that model to the partial. Keep database lookups and SDK response traversal out of the .cshtml file.
ProductFinishViewModel.cs csharp
public sealed class ProductFinishViewModel
{
public string SurfaceFinish { get; set; }
}
Preserve encoding and localization
Use Razor's normal @Model.SurfaceFinish output so encoding remains active. Do not wrap the value in Html.Raw. If the stored value is a code such as matte, resolve its display label before assigning SurfaceFinish.
The sample's 'Surface finish' field label is English text. For a localized theme, obtain that label through the theme's interface-resource mechanism separately from the product option label. Translating one does not translate the other.
Test the empty and hostile cases
Check a product with a normal value, no value, an untranslated value, and a value containing angle brackets. The last case must render as text. Also verify that a saved value reaches the storefront only after the target version's required publication or cache operation.
References and further reading
Bring your next engineering question.
Need help with a safe storefront extension?
Independent guidance from GCG. Znode is a trademark of its owner. Examples use fictional data and are not official platform documentation. Suggest a correction.