using System; using System.ComponentModel; using System.Linq; namespace Umbraco.Core { /// /// Represents a string-based entity identifier. /// [TypeConverter(typeof(UdiTypeConverter))] public class StringUdi : Udi { /// /// The string part of the identifier. /// public string Id { get; private set; } /// /// Initializes a new instance of the StringUdi class with an entity type and a string id. /// /// The entity type part of the udi. /// The string id part of the udi. public StringUdi(string entityType, string id) : base(entityType, "umb://" + entityType + "/" + EscapeUriString(id)) { Id = id; } /// /// Initializes a new instance of the StringUdi class with a uri value. /// /// The uri value of the udi. public StringUdi(Uri uriValue) : base(uriValue) { Id = Uri.UnescapeDataString(uriValue.AbsolutePath.TrimStart('/')); } private static string EscapeUriString(string s) { // Uri.EscapeUriString preserves / but also [ and ] which is bad // Uri.EscapeDataString does not preserve / which is bad // reserved = : / ? # [ ] @ ! $ & ' ( ) * + , ; = // unreserved = alpha digit - . _ ~ // we want to preserve the / and the unreserved // so... return string.Join("/", s.Split('/').Select(Uri.EscapeDataString)); } /// public override bool IsRoot { get { return Id == string.Empty; } } public StringUdi EnsureClosed() { EnsureNotRoot(); return this; } } }