ASP.NET Core Rendering SDK
Accessing model data in Views

ASP.NET Core Rendering SDK <br/>Accessing model data in Views

Model-View binding slightly changed in ASP.NET Core SDK in comparison with regular MVC. Previously it was two ways of displaying data from your datasource model when you don’t use mappers like GlassMapper:

  • Using Html-helper @Html.Sitecore().Fields(“Field Name”) or it’s overloaded variations to get field value rendered or field editor displayed when in editing mode.

  • Using direct access to fields collection Model.Item.Fields[“Field Name“] and, probably, converting to a proper field type to get additional built-in functionality. This method not provides editor functionality, but provides more flexibility in markup generation.

Basically, both of ways were saved, but were slightly changed just to follow ASP.NET Core conventions and techniques. Also, properties mapping are going out of the box now. Let’s go thru and check how display different field types.

Prerequisites and general info

For this demonstration let’s create datasource template with different most-used field types and item based on it as well as binding model. Fields are going to have dumb names to simplify understanding. All field classes using in model binding are placed in Sitecore.LayoutService.Client.Response.Model.Fields namespace. Some tag helpers are not generating wrapper tag, just inner text content, so, in examples this lines are appended with wrapper tag to make all options generate same markup (where possible).

Text fields

 

Text fields
Template with text fields

Single-line Text, Multiline Text, RichText Field - these are most using fields from this group. To map this fields to a code model you may use TextField and RichTextField types.

 

[SitecoreComponentField(Name = "Text Field")]
public TextField SingleLineText { get; set; }

[SitecoreComponentField(Name = "Multi Text Field")]
public TextField MultiLineText { get; set; }

[SitecoreComponentField(Name = "Rich Text Field")]
public RichTextField RichText { get; set; }

There are not much functionality provided by this classes - they basically gives you access to Value property of the field. To generate content on the page you can go following ways:

<div asp-for="SingleLineText"></div>
<div><sc-text asp-for="SingleLineText"></sc-text></div>
<div>@Model.SingleLineText?.Value</div>

First two options provide you an editor when you’re in editing mode, when the third one should be wrapped in not-a-null check as before. Here are some notes:

  • Editing option may be disabled by adding editable="false" attribute to a tag - same as aditional property DisableWebEdit:true before.

  • It’s also possible to disable conversion of new lines into html breaks by adding convert-new-lines="false" attribute. This is enabled by default.

  • Direct access to model’s property value without using special tag helpers will result you with raw field content. For example: RichText Field will return escaped html markup that have to be passed thru something like Html.Raw to be properly displayed, and MultiLine Field will return new lines like an actual new line characters (\n) and not html’s break line tag (<br />).

 

Link fields
Template with general link field

Basically there is the only one field out-of-box - General link Field - and it used to create html link to another item or external resource. To map it to a model you’ll use HyperLinkField type.

 

[SitecoreComponentField(Name = "General Link Field")]
public HyperLinkField GeneralLink { get; set; }

It provides pretty same functionality as before (as LinkField in regular Sitecore). To generate content on a page you may use tag helpers or get data pieces out of it:

<a asp-for="GeneralLink"></a>
<sc-link asp-for="GeneralLink"></sc-link>
<a href="@Model.GeneralLink?.Value?.Href" 
   title="@Model.GeneralLink?.Value?.Title"
   class="@Model.GeneralLink?.Value?.Class"
   target="@Model.GeneralLink?.Value?.Target">
     @Model.GeneralLink?.Value?.Text
</a>

Few things to note:

  • Same as text fields, link field provides editable="false" attribute to disable editor.

  • You can append any needed attributes to tag helper to show them in final markup.

    • Once you add title, class and target attributes - their value will be overwritten and used instead of value from datasource.

Image fields

 

Image fields
Template with image field

Again, the only one from the list of available fields. ImageField type is used to map it to a model.

 

[SitecoreComponentField(Name = "Image Field")]
public ImageField Image { get; set; }

And to generate it on page you also have couple of options:

<img asp-for="Image"></img>
<sc-img asp-for="Image"></sc-img>
<img src="@Model.Image.Value.Src"
     alt="@Model.Image.Value.Alt" />

And some notes as well:

  • Editable state may be changed with editable="false" attribute as well.

  • You can pass additional parameters to Image tag helpers to perform server-side resizing of the image using the image-params="new { mw = 100, mh = 50 }" attribute.

    • If you need to resize image outside of tag helper, for example when using as background-image css property value, you can pass same attributes to GetMediaLink method of an ImageField class: @Model.Image?.GetMediaLink(new {mw = 100, mh = 50})

    • All the parameters you pass in the image-params attribute or GetMediaLink must be whitelisted for resizing to occur: 

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/"> 
  <sitecore> 
    <javaScriptServices> 
      <allowedMediaParams> 
        <projectName__1>mw=100,mh=50</projectName__1> 
      </allowedMediaParams> 
    </javaScriptServices> 
  </sitecore> 
</configuration>    

 

Date and Number fields

 

Date and number fields
Template with date and number fields

This two are mostly considered as special versions of text fields. Mapping to a model appears with help of DateField and NumberField types accordingly:

 

[SitecoreComponentField(Name = "Date Field")]
public DateField Date { get; set; }
[SitecoreComponentField(Name = "Number Field")]
public NumberField Number { get; set; }

The difference with text fields is in formatting options, of course.

So, for Date field you can go with following options:

<span asp-for="Date"></span>
<span><sc-date asp-for="Date"></sc-date></span>
<span>@Model.Date?.Value?.ToString()</span>

Notes on date fields:

  • You can use date-format and culture tag helper attributes to set date format and culture. If not set - current will be used. Date-format attribute supports standard .NET date and time format strings.

  • DateField’s Value property type is standard DateTime.

For Number field your options are:

<span asp-for="Number"></span>
<span><sc-number asp-for="Number"></sc-number></span>
<span>@Model.Number?.Value?.ToString()</span>

Notes on number fields:

  • You can use number-format and culture tag helper attributes to format number. Number-format attribute supports standard .NET numeric format strings.

  • NumberField’s Value property type is nullable decimal.

Reference and list fields

There are number of fields that belongs to this group: DropLink Field, DropTree Field, TreeList, TreelistEx, Multilist, etc. All of them are storing one or multiple references to Sitecore items, so, one or more item ID in raw value. For test purposes let’s create DropLink and TreeList as representatives of each group.

 

Reference fields
Template with reference fields

On model side you can map them to ItemLinkField, ItemLinkField<T>, ContentListField and ContentListField<T> types.

 

[SitecoreComponentField(Name = "Droplink Field")]
public ItemLinkField ItemLink { get; set; }
[SitecoreComponentField(Name = "Droplink Field")]
public ItemLinkField<TestRenderingModel> TypedItemLink { get; set; }

[SitecoreComponentField(Name = "Treelist Field")] 
public ContentListField ContentList { get; set; }
[SitecoreComponentField(Name = "Treelist Field")]
public ContentListField<TestRenderingModel> TypedContentList { get; set; }

To read data from selected item you may use ReadField method like below - you have to specify field type and name:

<span>@(Model.ItemLink?.ReadField<TextField>("Single Line Text")?.Value)</span>

In generic version this reading may be done with internal model conversion and using Target property:

<span>@(Model.TypedItemLink?.Target?.SingleLineText?.Value)</span>

ContentListField and it’s generic version in fact is nothing else than collection (List) of ItemLinkFields and it’s generic version accordingly, so you can apply appropriate LINQ methods to iterate thru it and with each item as shown above.