Sharing and Combining Content Data

The RedirectPropertySourceAttribute provides a powerful mechanism for collating data from different sources, and conversely, sharing values across content items.  Essentially when attached to a class, it tells the Collator when reading data of that type, to get one or more content items in addition to the main one and combine their data fields.  When writing it splits out those data fields and saves them in the appropriate other content items.  The parameters of the RedirectPropertySourceAttribute are explained below:

  • PropertyPath: a comma separated list of property paths on the class which are redirected, i.e. retrieved from the source record e.g. "HeaderData.Sponsors, HeaderData.Year"
  • ContentType: the content type of the source content record (defaults to same type as this record)
  • SourceDescriptor: a transformation of the address path of the current content item into the address path of the source content item.  Defaults to "", which means the source is always the same special content item record with an empty path. "{0}" would mean the source had the same path as the current content item.
  • ReadOnly: changes in the current content item are not written back to the source if this is set to true (defaults to false)

Sharing Data

The scenario where you want to have certain values on a content item shared between all content items can be supported like this:

...
  routes.AddDataRoute<TestContent>("test", "test/{_0}", new { controller = "Test", action = "Index" });
...
[RedirectPropertySource("SharedValue")]
public class TestContent : BaseContent
{
  [Summary]
  public string Title { get; set; }
  public string SharedValue { get; set; }
}

All the address paths for TestContent items are mapped to one shared content item on path "".  This item holds the shared value of the SharedValue string. Any time this value is updated while editing a TestContent item, it is written to the shared content item on path "".  Then the next time any TestContent item is read, it will get the updated value.

Combining Data

The scenario where you want a content item to combine data from two sources, for instance you may want to display an order item record in a presentation where you want to content manage the static text items which don't vary from order item to order item.  In this case you could do this:

[Table("OrderItems"), NonComposite]
public class OrderItem
{
	[Key, DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
	public int Id { get; set; }
 
    [AddressComponent("_0")]
	public string OrderCode { get; set; }
 
	public DateTime OrderDate { get; set; }
 
	public int CustomerId { get; set; }
 
	[AlwaysInclude]
    public Customer Customer { get; set; }
}
 
[Serializable]
public class OrderDisplayContent : BaseContent
{
	public string OrderCode { get; set; }
 
	public string Heading { get; set; }
	public MinHtml OrderText { get; set; }
	public MinHtml OurDetails { get; set; }
 
	public OrderDisplayContent()
	{
		OrderText = new MinHtml();
		OurDetails = new MinHtml();
	}
}
 
[Serializable]
[RedirectPropertySource("Item", ContentType = typeof(OrderItem), SourceDescriptor = "{0}")]
[RedirectPropertySource("Display", ContentType = typeof(OrderDisplayContent)]
public class OrderContent : BaseContent
{
	public OrderItem Item { get; set; }
	public OrderDisplayContent Display { get; set; }
 
	public OrderContent()
	{
		Item = new OrderItem();
		Display = new OrderDisplayContent();
	}
}

OrderItem would be set up to work with the Basic persistence model, linking to the OrderItem table in the database.  OrderDisplayContent would be a single content item (i.e. no path variable in its route).  OrderContent would be set up to work with the Content persistence model, with a route with one variable which would be the order code.  It would automatically bring in the display details shared across all orders, and the order record itself.