Component link in Page Metadata for DXA Application

We have received a requirement to add a component link in page metadata for our DXA application (DXA Version 1.5), but unfortunately it did not work for me. Then I found a very useful blog from Ryan Durkin regarding this issue. (Here is the link for that.) 

 If you have a provision to change the DXA code then the solution provided by Ryan is the best option, but in our case the scenario was bit different.

As our project was already in maintenance phase so it was difficult for us to change the DXA code.

To overcome this situation I have taken the below steps –

  • Created schema and Model for the linked component (For example I have created a Security Message schema)

  • Created one dynamic component template with a dummy view to publish the metadata separately.

  • Created the component (Security Message type) and published it.

  • Also added that component on page metadata field.

  • The tweak I have done on the Page View Model is here,

              I have added a check that if metadata exist then it will give a call to broker and read the component presentation and map data back to Model.

         Page Metadata Model: (In this example code SecurityMessage is my custom Model)

private SecurityMessage message;

[SemanticProperty(PropertyName = "securityMessage")]
public SecurityMessage SecurityMessage { get; set; }

public bool HasSecurityMessage => SecurityMessage != null;

public SecurityMessage Message
{
get
{
if (HasSecurityMessage)
{
SecurityMessage model = provider.GetSecurityMessage(SecurityMessage.Id);
return model;
}
return message;
}
set { message = value; }
}

 

          Broker Query:


/// <summary>
/// Read and Return the Security message
/// </summary>
/// <param name="securityMessageId"></param>
/// <returns></returns>
public SecurityMessage GetSecurityMessage(string securityMessageId)
{
try
{
string presentationId = securityMessageId + "-" + SiteLabelConfiguration.TcmUriOfDynamicTemplateForMetadata;
SecurityMessage model = ContentProvider.GetEntityModel(presentationId, WebRequestContext.Localization) as SecurityMessage;
return model;
}
catch (Exception ex)
{
throw new DxaException("Error while getting Dynamic Tile Component", ex);
}

}

That's it.. (Link for full code)