static void WriteResourceProperties(HalResource 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 (HalResource).IsAssignableFrom(property.PropertyType) && property.GetIndexParameters().Length == 0) { var halResource = property.GetValue(resource, null); WriteHalResource((HalResource) halResource, writer, property.Name); } } }
static void WriteHalResource(HalResource 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 (HalResource 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(); }