static void SetProperties(Type type, XElement xml, Resource resource) { foreach (var property in type.GetPublicInstanceProperties()) { if (property.IsValidBasicType()) { type.SetPropertyValue(property.Name, xml.Element(property.Name), resource); } else if (typeof(Resource).IsAssignableFrom(property.PropertyType) && property.GetIndexParameters().Length == 0) { var resourceXml = xml.Elements("resource").SingleOrDefault(x => x.Attribute("name").Value == property.Name); var halResource = ReadHalResource(property.PropertyType, resourceXml); property.SetValue(resource, halResource, null); } } }
static void WriteHalResource(Resource resource, XmlWriter writer, string propertyName = null) { if (resource == null) { return; } // First write the well-known HAL properties writer.WriteStartElement("resource"); writer.WriteAttributeString("rel", resource.Rel); writer.WriteAttributeString("href", resource.Href); if (resource.LinkName != null || propertyName != null) { writer.WriteAttributeString("name", resource.LinkName = resource.LinkName ?? propertyName); } // Second, determine if resource is of Generic Resource List Type , list out all the items if (resource.GetType().IsGenericResourceList()) { var propertyValue = resource as IEnumerable; foreach (Resource item in propertyValue) { WriteHalResource(item, writer); } } //Third write out the links of the resource foreach (var link in resource.Links) { writer.WriteStartElement("link"); writer.WriteAttributeString("rel", link.Rel); writer.WriteAttributeString("href", link.Href); writer.WriteEndElement(); } // Fourth, write the rest of the properties WriteResourceProperties(resource, writer); writer.WriteEndElement(); }
static void WriteResourceProperties(Resource resource, XmlWriter writer) { // Only simple type and nested ApiResource type will be handled : for any other type, exception will be thrown // including List<ApiResource> as representation of List would require properties rel, href and linkname // To overcome the issue, use "ResourceList<T>" foreach (var property in resource.GetType().GetPublicInstanceProperties()) { if (property.IsValidBasicType()) { var propertyString = GetPropertyString(property, resource); if (propertyString != null) { writer.WriteElementString(property.Name, propertyString); } } else if (typeof (Resource).IsAssignableFrom(property.PropertyType) && property.GetIndexParameters().Length == 0) { var halResource = property.GetValue(resource, null); WriteHalResource((Resource) halResource, writer, property.Name); } } }
static void CreateSelfHypermedia(Type type, XElement xml, Resource resource) { type.GetProperty("Rel").SetValue(resource, xml.Attribute("rel").Value, null); type.SetPropertyValue("Href", xml.Attribute("href"), resource); type.SetPropertyValue("LinkName", xml.Attribute("name"), resource); }