skttl
6/19/2018 - 9:22 AM

Models for Nested Content Items to be used with Umbraco ContentService

Models for Nested Content Items to be used with Umbraco ContentService

using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;

namespace Umbraco.Core.Models
{

	public class NestedContent : List<NestedContentItem>
	{
		public string Value
		{
			get
			{
				return JsonConvert.SerializeObject(
					this.Select(item =>
					{
						var dictionary = item.Values;
						dictionary.Add("key", item.Key);
						dictionary.Add("name", item.Name);
						dictionary.Add("ncContentTypeAlias", item.ContentTypeAlias);

						return dictionary;
					}
					)
				);
			}
		}

		public NestedContent()
		{

		}

		public NestedContent(string serializedValue)
		{
			var dictionaryList = JsonConvert.DeserializeObject<List<Dictionary<string, object>>>(serializedValue);

			this.AddRange(dictionaryList.Select(item =>
			{
				if (!item.ContainsKey("name")) throw new MissingFieldException("Item is missing a name");
				if (!item.ContainsKey("key")) throw new MissingFieldException("Item is missing a key");
				if (!item.ContainsKey("ncContentTypeAlias")) throw new MissingFieldException("Item is missing a content type alias");

				var nestedContentItem = new NestedContentItem(item["name"].ToString(), item["ncContentTypeAlias"].ToString(), item["key"].ToString());

				foreach (var key in item.Keys.Except(new string[]{ "name", "key", "ncContentTypeAlias" }))
				{
					nestedContentItem.SetValue(key, item[key]);
				}

				return nestedContentItem;

			}));
		}
	}

	public class NestedContentItem
	{
		/// <summary>
		/// Returns the Guid assigned to the Content during creation. This value is unique, and should never change, even if the content is moved between instances.
		/// </summary>
		public string Key { get; private set; }

		/// <summary>
		/// Gets or Sets the name of the content as a String.
		/// </summary>
		public string Name { get; set; }

		/// <summary>
		/// Returns the alias of the ContentType object representing the DocumentType used by the given Nested Content.
		/// </summary>
		public string ContentTypeAlias { get; set; }

		/// <summary>
		/// Gets the values of the properties on the given Nested Content.
		/// </summary>
		public Dictionary<string, object> Values { get; private set; }

		public NestedContentItem(string name, string contentTypeAlias, string key = null)
		{
			Key = string.IsNullOrEmpty(key) ? Guid.NewGuid().ToString() : key;
			Name = name;
			ContentTypeAlias = contentTypeAlias;
			Values = new Dictionary<string, object>();
		}

		/// <summary>
		/// Gets the value of a Property as an Object.
		/// </summary>
		/// <param name="propertyTypeAlias">The alias of the property</param>
		/// <returns></returns>
		public object GetValue(string propertyTypeAlias)
		{
			return Values.ContainsKey(propertyTypeAlias) ? Values.FirstOrDefault(x => x.Key == propertyTypeAlias).Value : null;
		}

		/// <summary>
		/// Gets the value of a Property as the defined type 'T'.
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="propertyTypeAlias">The alias of the property</param>
		/// <returns></returns>
		public T GetValue<T>(string propertyTypeAlias)
		{
			return Values.ContainsKey(propertyTypeAlias) ? (T)Values.FirstOrDefault(x => x.Key == propertyTypeAlias).Value : default(T);
		}

		/// <summary>
		/// Sets the value of a property by its alias.
		/// </summary>
		/// <param name="propertyTypeAlias">The alias of the property</param>
		/// <param name="value">The value of the property</param>
		public void SetValue(string propertyTypeAlias, object value)
		{
			if (Values.ContainsKey(propertyTypeAlias))
			{
				Values[propertyTypeAlias] = value;
			}
			else
			{
				Values.Add(propertyTypeAlias, value);
			}
		}
		
	}
}