Model binding

Abstract

Overview of the Sitecore ASP.NET Rendering SDK model binding functionality.

The Sitecore Rendering Engine provides ASP.NET model binding support for key objects, properties, and fields returned by the Layout Service in a SitecoreLayoutResponse object.

Model binding is done with IFieldReader and is case sensitive. If a model property is not mapped through attributes, default ASP.NET Model-View-Controller model binding behavior takes over.

The attributes, sources, providers, and so on are located in the Sitecore.AspNet.RenderingEngine.Binding namespace of the RE libraries.

Model properties that implement IField do not require explicit attributes and bind to the current component or current route field of the same name.

The current component, response, or route refer to the corresponding objects in the SitecoreLayoutResponse instance that are available as context information on the HttpContext object. For a given request, the current response and route is the same for all components, but the current component is set dynamically by the placeholder tag helper.

An example Layout Service response:

{
  "sitecore": {
    "context": {                               // context
      "contextproperty1": "",                  // context property
      "contextproperty2": "",                  // context property
      "CustomContextSingleProperty": "",       // custom single context property
      "CustomContextClass": {
        "customcontextprop": "",               // custom context property of custom context class
      },
    },
    "route": {                                 // route
      "routeproperty1": "",                    // route property
      "routeproperty2": "",                    // route property
      "fields": {                              // route fields
        "routefield1": {                       // route field
          "value": ""
        }
      },
      "placeholders": {                        // route placeholders
        "placeholder1": [                      // route placeholder
          {
            "componentproperty1": "",          // component property
            "componentproperty2": "",          // component property
            "fields": {                        // component fields
              "componentfield1": {             // component field
                "value": ""
              }
            }
          }
          ]
        }
    }
  }
}

A matching view model class:

using Sitecore.AspNet.RenderingEngine.Binding;
using Sitecore.AspNet.RenderingEngine.Binding.Attributes;
using Sitecore.LayoutService.Client.Response;
using Sitecore.LayoutService.Client.Response.Model;
using Sitecore.LayoutService.Client.Response.Model.Fields;

public class ComplexComponent
{
  public SitecoreLayoutResponse Response {get; set;}

  public Context Context {get; set;}                            // Bind to "context"

  [SitecoreContextProperty(Name = "contextproperty1")]          // Bind to "contextproperty1". Also binds custom Sitecore "Context" properties.
  public bool ContextProperty1 { get; set; }

  [SitecoreContextProperty(Name = "contextproperty2")]          // Bind to "contextproperty2". Also binds custom Sitecore "Context" properties.
  public bool ContextProperty2 { get; set; }
  
  public ContextExt ContextExt { get; set; }                    // Bind to current Sitecore "Context" and all custom context extensions. Inherits "Context" class.

  [SitecoreContext]                                             // Bind to current Sitecore "Context" and Custom Sitecore Context Properties and objects.
  public CustomContextClass CustomContextClass { get; set; } 

  public Route Route {get; set;}                                // Bind to "route"

  [SitecoreRouteProperty(Name = "routeproperty1")]              // Bind to "routeproperty1"
  public string RouteProperty1 { get; set; }

  [SitecoreRouteProperty(Name = "routeproperty2")]              // Bind to "routeproperty2"
  public string RouteProperty2 { get; set; }

  [SitecoreRouteFields]                                         // Bind to "route"."fields"
  public RouteFields RouteFields { get; set; }

  [SitecoreRouteField(Name = "routefield1")]                    // Bind to "routefield1"
  public TextField RouteField1 { get; set; }
  

  [SitecoreComponentProperty(Name = "componentproperty1")]      // Bind to "componentproperty1"
  public string ComponentProperty1 { get; set; }

  [SitecoreComponentProperty(Name = "componentproperty2")]      // Bind to "componentproperty2"
  public string ComponentProperty2 { get; set; }

  [SitecoreComponentFields]                                     // Bind to "route"."placeholders"
  public ComponentFields ComponentFields { get; set; }

  [SitecoreComponentField(Name = "componentfield1")]            // Bind to "componentfield1"
  public TextField ComponentField1 { get; set; }
}

public class RouteFields
{
  [SitecoreRouteField(Name = "routefield1")]                    // Bind to "routefield1"
  public TextField RouteField1 { get; set; }
}

public class ComponentFields
{
  [SitecoreComponentField(Name = "componentfield1")]            // Bind to "componentfield1"
  public TextField ComponentField1 { get; set; }
}

// A class to extend the current Sitecore "Context" with custom properties
public class ContextExt:Context
{
  public CustomContextClass CustomContextClass { get; set; }
  public string CustomContextSingleProperty { get; set; } 
}

// A class for custom Context properties
public class CustomContextClass
{
  public string CustomContextProp { get; set; }
}

Note

For an example of a context extension, see Extending Context Data Returned by the Layout Service.