using System; using System.Collections.Generic; using System.Drawing.Imaging; using System.IO; using System.Net.Http; using System.Net.Http.Headers; using System.Text; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc.Formatters; namespace CustomerDemo.Hypermedia { public class SirenFormatter : OutputFormatter { public SirenFormatter() { SupportedMediaTypes.Add("application/vnd.siren+json"); } protected override bool CanWriteType(Type type) { if (typeof(Siren).IsAssignableFrom(type)) { return base.CanWriteType(type); } return false; } public override Task WriteResponseBodyAsync(OutputFormatterWriteContext context) { var response = context.HttpContext.Response; var s = context.Object as Siren; return Task.Run( () => { var json = ToJson(s); byte[] buf = Encoding.UTF8.GetBytes(json); response.Body.Write(buf, 0, buf.Length); }); } private string ToJson(Siren s) { var sb = new StringBuilder(); sb.Append("{"); SerializeClass(sb, s.Class); sb.Append(","); SerializeProperties(sb, s.Properties); sb.Append(","); SerializeEntities(sb, s.Entities); sb.Append(","); SerializeActions(sb, s.Actions); sb.Append(","); SerializeLinks(sb, s.Links); sb.Append("}"); return sb.ToString(); } private void SerializeLinks(StringBuilder sb, List links) { sb.Append("\"links\":["); for (int i = 0; i < links.Count; i++) { var link = links[i]; sb.Append("{"); sb.Append("\"rel\""); sb.Append(":"); SerializeRelation(sb, link.Relation); sb.Append(","); sb.Append("\"href\":\"").Append(link.Href).Append("\""); if (i < links.Count - 1) { sb.Append(","); } sb.Append("}"); } sb.Append("]"); } private static void SerializeRelation(StringBuilder sb, List relation) { sb.Append("["); for (int j = 0; j < relation.Count; j++) { var rel = relation[j]; sb.Append("\""); sb.Append(rel); sb.Append("\""); if (j < relation.Count - 1) { sb.Append(","); } } sb.Append("]"); } private void SerializeActions(StringBuilder sb, List actions) { sb.Append("\"actions\":["); for (int i = 0; i < actions.Count; i++) { var action = actions[i]; sb.Append("{"); sb.Append("\"name\":\"").Append(action.Name).Append("\","); sb.Append("\"title\":\"").Append(action.Title).Append("\","); sb.Append("\"method\":\"").Append(action.Method).Append("\","); sb.Append("\"href\":\"").Append(action.Href).Append("\","); sb.Append("\"type\":\"").Append(action.Type).Append("\","); sb.Append("\"fields\":").Append(Newtonsoft.Json.JsonConvert.SerializeObject(action.Fields)); sb.Append("}"); if (i < actions.Count - 1) { sb.Append(","); } } sb.Append("]"); } private void SerializeEntities(StringBuilder sb, List entities) { sb.Append("\"entities\":["); for (int i = 0; i < entities.Count; i++) { var entity = entities[i]; sb.Append("{"); if (entity is EmbeddedRepresentation) { SerializeEmbededEntity(sb, entity as EmbeddedRepresentation); } else if (entity is EmbeddedLink) { SerializeEmbededLink(sb, entity as EmbeddedLink); } sb.Append("}"); if (i < entities.Count - 1) { sb.Append(","); } } sb.Append("]"); } private void SerializeEmbededLink(StringBuilder sb, EmbeddedLink entity) { throw new NotImplementedException(); } private void SerializeEmbededEntity(StringBuilder sb, EmbeddedRepresentation entity) { SerializeClass(sb, entity.Class); sb.Append(","); sb.Append("\"rel\""); sb.Append(":"); SerializeRelation(sb, entity.Relation); sb.Append(","); SerializeProperties(sb, entity.Properties); sb.Append(","); SerializeLinks(sb, entity.Links); } private void SerializeProperties(StringBuilder sb, List properties) { sb.Append("\"properties\":{"); for (int i = 0; i < properties.Count; i++) { var property = properties[i]; sb.Append("\""); sb.Append(property.Name); sb.Append("\""); sb.Append(":"); var serializedValue = Newtonsoft.Json.JsonConvert.SerializeObject(property.Value); sb.Append(serializedValue); if (i < properties.Count - 1) { sb.Append(","); } } sb.Append("}"); } private void SerializeClass(StringBuilder sb, List classes) { sb.Append("\"class\":["); for (int i = 0; i < classes.Count; i++) { sb.Append("\"").Append(classes[i]).Append("\""); if (i < classes.Count - 1) { sb.Append(","); } } sb.Append("]"); } } }