Advertisement
Looooooka

Custom Json.NET ClientMessageFormatter

Oct 29th, 2013
722
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 21.83 KB | None | 0 0
  1. using Newtonsoft.Json;
  2. using Newtonsoft.Json.Linq;
  3. using Onyx.Payments.Models;
  4. using System;
  5. using System.Diagnostics;
  6. using System.IO;
  7. using System.Net;
  8. using System.Reflection;
  9. using System.Runtime.Serialization;
  10. using System.Runtime.Serialization.Json;
  11. using System.ServiceModel;
  12. using System.ServiceModel.Channels;
  13. using System.ServiceModel.Description;
  14. using System.ServiceModel.Dispatcher;
  15. using System.ServiceModel.Web;
  16. using System.Text;
  17. using System.Text.RegularExpressions;
  18. using System.Xml;
  19. using System.Linq;
  20. using System.Collections.Generic;
  21.  
  22. namespace JsonNetMessageFormatter
  23. {
  24.  
  25.     class NewtonsoftJsonClientFormatter : IClientMessageFormatter
  26.     {
  27.         OperationDescription operation;
  28.         Uri operationUri;
  29.         public NewtonsoftJsonClientFormatter(OperationDescription operation, ServiceEndpoint endpoint, JsonSerializerSettings settings)
  30.         {
  31.             this.JsonSettings = settings;
  32.             this.operation = operation;
  33.             string endpointAddress = endpoint.Address.Uri.ToString();
  34.             if (!endpointAddress.EndsWith("/"))
  35.             {
  36.                 endpointAddress = endpointAddress + "/";
  37.             }
  38.             WebInvokeAttribute wia = operation.Behaviors.Find<WebInvokeAttribute>();
  39.             if (wia != null && !String.IsNullOrEmpty(wia.UriTemplate))
  40.             {
  41.                 this.operationUri = new Uri(endpointAddress + wia.UriTemplate);
  42.             }
  43.             else
  44.             {
  45.                 this.operationUri = new Uri(endpointAddress + operation.Name);
  46.             }
  47.         }
  48.  
  49.         public object DeserializeReply(Message message, object[] parameters)
  50.         {
  51.             object bodyFormatProperty;
  52.             if (!message.Properties.TryGetValue(WebBodyFormatMessageProperty.Name, out bodyFormatProperty) ||
  53.                 ((bodyFormatProperty as WebBodyFormatMessageProperty).Format != WebContentFormat.Json))
  54.             {
  55.                 throw new InvalidOperationException("Incoming messages must have a body format of Raw. Is a ContentTypeMapper set on the WebHttpBinding?");
  56.             }
  57.  
  58.             Newtonsoft.Json.JsonSerializer serializer = new Newtonsoft.Json.JsonSerializer();
  59.             this.SetupSerializer(serializer);
  60.             serializer.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
  61.             MessageBuffer buffer = message.CreateBufferedCopy(Int32.MaxValue);
  62.             XmlDictionaryReader reader = buffer.CreateMessage().GetReaderAtBodyContents();
  63.             XmlDocument request = new XmlDocument();
  64.             request.LoadXml(reader.ReadOuterXml());
  65.  
  66.             string jsonText = String.Empty;// JsonConvert.SerializeXmlNode(request.DocumentElement);
  67.             var sbuilder = new StringBuilder();
  68.             using (var swriter = new StringWriter(sbuilder))
  69.             {
  70.                 using (var jwriter = new JsonTextWriter(swriter))
  71.                 {
  72.                     serializer.Serialize(jwriter, request.DocumentElement);
  73.                     jwriter.Flush();
  74.                     jwriter.Close();
  75.                     jsonText = sbuilder.ToString();
  76.                 }
  77.             }
  78.  
  79.             Newtonsoft.Json.Linq.JObject jobject = null;
  80.             using (var sreader = new StringReader(jsonText))
  81.             {
  82.                 using (var jreader = new JsonTextReader(sreader))
  83.                 {
  84.                     serializer.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
  85.                     jobject = serializer.Deserialize<Newtonsoft.Json.Linq.JObject>(jreader);
  86.                 }
  87.             }
  88.  
  89.             //var jobject = JsonConvert.DeserializeObject<Newtonsoft.Json.Linq.JObject>(jsonText);
  90.  
  91.  
  92.             StringBuilder sb = new StringBuilder();
  93.             using (StringWriter sw = new StringWriter(sb))
  94.             {
  95.                 using (JsonWriter jsonWriter = new JsonTextWriter(sw))
  96.                 {
  97.                     this.SetupWriter(jsonWriter);
  98.                     jsonWriter.DateTimeZoneHandling = DateTimeZoneHandling.Local;
  99.  
  100.                     // var cobject = ToObject(jobject);
  101.  
  102.                     //Dictionary<string, object> list = cobject as Dictionary<string, object>;
  103.  
  104.                     WriteDetails(jobject, jsonWriter);
  105.                     jsonWriter.Flush();
  106.                     jsonWriter.Close();
  107.                 }
  108.             }
  109.  
  110.             jsonText = sb.ToString();
  111.             if (operation.Messages.Count > 1 && operation.Messages[1].Body != null && operation.Messages[1].Body.ReturnValue != null && operation.Messages[1].Body.ReturnValue.Type != null)
  112.             {
  113.                 using (var sreader = new StringReader(jsonText))
  114.                 {
  115.                     using (var jreader = new JsonTextReader(sreader))
  116.                     {
  117.                         serializer.DateTimeZoneHandling = DateTimeZoneHandling.Local;
  118.                         var deserializedObjectFromType = serializer.Deserialize(jreader, operation.Messages[1].Body.ReturnValue.Type.UnderlyingSystemType);
  119.                         return deserializedObjectFromType;
  120.                     }
  121.                 }
  122.             }
  123.             else
  124.             {
  125.                 using (var sreader = new StringReader(jsonText))
  126.                 {
  127.                     using (var jreader = new JsonTextReader(sreader))
  128.                     {
  129.                         serializer.DateTimeZoneHandling = DateTimeZoneHandling.Local;
  130.                         var deserializedObject = serializer.Deserialize(jreader);
  131.                         return deserializedObject;
  132.                     }
  133.                 }
  134.             }
  135.  
  136.  
  137.         }
  138.         private static Dictionary<string, object> ToArrayObject(JToken token)
  139.         {
  140.             Dictionary<string, object> citem = new Dictionary<string, object>();
  141.             Dictionary<string, object> dict = new Dictionary<string, object>();
  142.             var tlist = token.Values().ToList();
  143.             int citemIndex = 0;
  144.             int dictIndex = 0;
  145.             while (tlist.FindIndex(cc => cc as JProperty != null && (cc as JProperty).Name == "@type" && (cc as JProperty).Value.ToString() == "object") > -1)
  146.             {
  147.                 citem = new Dictionary<string, object>();
  148.                 var cindex = tlist.FindIndex(cc => cc as JProperty != null && (cc as JProperty).Name == "@type" && (cc as JProperty).Value.ToString() == "object");
  149.                 var nindex = tlist.FindIndex(cindex + 1, cc => cc as JProperty != null && (cc as JProperty).Name == "@type" && (cc as JProperty).Value.ToString() == "object");
  150.                 if (nindex < 0)
  151.                 {
  152.                     nindex = tlist.Count();
  153.                 }
  154.                 citemIndex = 0;
  155.                 for (int x = cindex + 1; x < nindex; x++)
  156.                 {
  157.                     var ctype = tlist[x] as JProperty;
  158.  
  159.                     var currentItem = ctype.Values().Where(cc => cc as JProperty != null && (cc as JProperty).Name == "@type").Select(cc => cc as JProperty).FirstOrDefault();
  160.                     //citem.Add(tlist[x]);
  161.                     if (currentItem != null && currentItem.Value.ToString() == "array")
  162.                     {
  163.                         citem.Add(String.Format("Item{0}", citemIndex), ToArrayObject(tlist[x]));
  164.                     }
  165.                     else if (ctype != null)
  166.                     {
  167.                         var val = ctype.Values().Where(cc => cc as JProperty != null && (cc as JProperty).Name != "@type").Select(cc => cc as JProperty).FirstOrDefault();
  168.                         citem.Add(ctype.Name, val.Value);
  169.                     }
  170.                     citemIndex += 1;
  171.                 }
  172.                 tlist.RemoveRange(cindex, nindex);
  173.                 dict.Add(String.Format("Item{0}", dictIndex), citem);
  174.                 dictIndex += 1;
  175.             }
  176.             if (dict != null && dict.Count != 0)
  177.             {
  178.                 return dict;
  179.             }
  180.             else
  181.             {
  182.                 dict = new Dictionary<string, object>();
  183.                 dictIndex = 0;
  184.                 foreach (var value in tlist)
  185.                 {
  186.                     dict.Add(String.Format("Item{0}", dictIndex), ToObject(value));
  187.                     dictIndex += 1;
  188.                 }
  189.                 return dict;
  190.             }
  191.         }
  192.  
  193.         private static object ToObject(JToken token)
  194.         {
  195.             if (token.Type == JTokenType.Object)
  196.             {
  197.                 Dictionary<string, object> dict = new Dictionary<string, object>();
  198.                 foreach (JProperty prop in ((JObject)token).Properties())
  199.                 {
  200.                     dict.Add(prop.Name, ToObject(prop.Value));
  201.                 }
  202.                 return dict;
  203.             }
  204.             else if (token.Type == JTokenType.Array)
  205.             {
  206.                 return ToArrayObject(token);
  207.             }
  208.             else if (token.Type == JTokenType.Property)
  209.             {
  210.                 Dictionary<string, object> dict = new Dictionary<string, object>();
  211.                 var obj = (((JProperty)token).Value as JObject);
  212.                 if (obj != null)
  213.                 {
  214.                     var result = ToObject(obj);
  215.                     return result;
  216.                 }
  217.                 else
  218.                 {
  219.                     return ((JProperty)token).Value.ToString();
  220.                 }
  221.             }
  222.             else
  223.             {
  224.                 return ((JValue)token).Value;
  225.             }
  226.         }
  227.         public String GetItemType(Dictionary<string, object> dict)
  228.         {
  229.             if (dict.ContainsKey("@type"))
  230.             {
  231.                 return dict["@type"].ToString();
  232.             }
  233.             return "";
  234.         }
  235.         public class ItemInfo
  236.         {
  237.             public String Name { get; set; }
  238.             public String Type { get; set; }
  239.             public List<JToken> Values { get; set; }
  240.             public JToken Value { get; set; }
  241.         }
  242.         public String GetPropertyInfo(JToken node)
  243.         {
  244.             return string.Empty;
  245.         }
  246.         public ItemInfo GetItemInfo(JToken node)
  247.         {
  248.             var answer = new ItemInfo();
  249.             JProperty jproperty = node as JProperty;
  250.             IEnumerable<JToken> nodes = null;
  251.             var jObject = node as JObject;
  252.             Boolean parse = true;
  253.             if (jproperty == null)
  254.             {
  255.                 var typenode = node.Where(cn => (cn as JProperty) != null && (cn as JProperty).Name == "@type").Select(cn => cn as JProperty).FirstOrDefault();
  256.                 if (node.FirstOrDefault(cn => (cn as JProperty) != null && (cn as JProperty).Name == "@type") != null)
  257.                 {
  258.                     answer.Type = typenode.Value.ToString();
  259.                     answer.Values = node.Where(cn => (cn as JProperty) != null && (cn as JProperty).Name != "@type").Select(cn => cn as JToken).ToList();
  260.                     parse = false;
  261.                 }
  262.                 else
  263.                 {
  264.                     var fnode = node.First as JProperty;
  265.  
  266.                     if (fnode != null)
  267.                     {
  268.                         answer.Name = fnode.Name;
  269.                     }
  270.                     var cnodes = node.Values().Where(cn => cn as JToken != null).Select(ccn => ccn as JToken);
  271.                     nodes = cnodes.Values();
  272.                 }
  273.  
  274.             }
  275.             else
  276.             {
  277.                 var cnodes = jproperty.Values().ToList();
  278.  
  279.                 answer.Name = jproperty.Name;
  280.                 nodes = cnodes.Where(cn => cn as JProperty != null).Select(cn => cn as JProperty);
  281.             }
  282.             if (parse)
  283.             {
  284.                 var typeProperty = nodes.Where(cn => cn as JProperty != null && (cn as JProperty).Name == "@type").Select(ccn => (ccn as JProperty)).FirstOrDefault();
  285.                 var values = nodes.Where(cn => cn as JProperty != null && (cn as JProperty).Name != "@type").Select(ccn => (ccn as JToken)).ToList();
  286.                 if (typeProperty != null)
  287.                 {
  288.                     answer.Type = typeProperty.Value.ToString();
  289.                 }
  290.                 else
  291.                 {
  292.                     answer.Type = String.Empty;
  293.                 }
  294.                 answer.Values = values;
  295.             }
  296.             if (answer.Type != "object" && answer.Type != "array" && answer.Type != "null" && answer.Values != null && answer.Values.Count != 0)
  297.             {
  298.                 answer.Value = answer.Values[0];
  299.                 if (answer.Value as JProperty != null)
  300.                 {
  301.                     answer.Value = (answer.Value as JProperty).Value;
  302.                 }
  303.             }
  304.             if (answer.Type == "array")
  305.             {
  306.                 jproperty = answer.Values[0] as JProperty;
  307.                 answer.Values = jproperty.Values().ToList();
  308.             }
  309.  
  310.  
  311.             return answer;
  312.         }
  313.         public void WriteDetails(JObject node, JsonWriter jsonWriter)
  314.         {
  315.  
  316.             var info = GetItemInfo(node);
  317.             info.Name = String.Empty;
  318.             switch (info.Type)
  319.             {
  320.                 case "array":
  321.                     WriteArray(info, jsonWriter);
  322.                     break;
  323.                 case "object":
  324.                     WriteObject(info, jsonWriter);
  325.                     break;
  326.                 default:
  327.                     jsonWriter.WriteStartObject();
  328.                     WritePropertyValue(info.Name, info.Value, jsonWriter);
  329.                     jsonWriter.WriteEndObject();
  330.                     break;
  331.             }
  332.         }
  333.  
  334.         public void WriteArray(ItemInfo info, JsonWriter jsonWriter)
  335.         {
  336.             if (!String.IsNullOrEmpty(info.Name))
  337.             {
  338.                 jsonWriter.WritePropertyName(info.Name);
  339.             }
  340.             jsonWriter.WriteStartArray();
  341.             foreach (var item in info.Values)
  342.             {
  343.                 var cinfo = GetItemInfo(item);
  344.                 switch (cinfo.Type)
  345.                 {
  346.                     case "object":
  347.                         WriteObject(cinfo, jsonWriter);
  348.                         break;
  349.                     case "array":
  350.                         WriteArray(cinfo, jsonWriter);
  351.                         break;
  352.                     default:
  353.                         jsonWriter.WriteStartObject();
  354.                         WritePropertyValue(cinfo.Name, cinfo.Value, jsonWriter);
  355.                         jsonWriter.WriteEndObject();
  356.                         break;
  357.                 }
  358.             }
  359.             jsonWriter.WriteEndArray();
  360.         }
  361.         public void WriteObject(ItemInfo info, JsonWriter jsonWriter)
  362.         {
  363.             ItemInfo cinfo = null;
  364.             if (!String.IsNullOrEmpty(info.Name))
  365.             {
  366.                 jsonWriter.WritePropertyName(info.Name);
  367.             }
  368.             jsonWriter.WriteStartObject();
  369.             foreach (var item in info.Values)
  370.             {
  371.                 cinfo = GetItemInfo(item);
  372.                 switch (cinfo.Type)
  373.                 {
  374.                     case "object":
  375.                         WriteObject(cinfo, jsonWriter);
  376.                         break;
  377.                     case "array":
  378.                         WriteArray(cinfo, jsonWriter);
  379.                         break;
  380.                     default:
  381.                         WritePropertyValue(cinfo.Name, cinfo.Value, jsonWriter);
  382.                         break;
  383.                 }
  384.                 //jsonWriter.WritePropertyName(item.);
  385.                 //jsonWriter.WriteValue(item.Value);
  386.             }
  387.             jsonWriter.WriteEndObject();
  388.         }
  389.         public void WritePropertyValue(String propertyName, Object value, JsonWriter jsonWriter)
  390.         {
  391.             jsonWriter.WritePropertyName(propertyName);
  392.             if (value == null || (value != null && !String.IsNullOrEmpty(value.ToString())))
  393.             {
  394.                 jsonWriter.WriteValue(value);
  395.             }
  396.             else
  397.             {
  398.                 jsonWriter.WriteNull();
  399.             }
  400.         }
  401.  
  402.         private JsonSerializerSettings _JsonSettings;
  403.         JsonSerializerSettings JsonSettings
  404.         {
  405.             get
  406.             {
  407.                 var s = this._JsonSettings;
  408.                 if (s == null)
  409.                 {
  410.                     return JsonConvert.DefaultSettings();
  411.                 }
  412.                 return s;
  413.             }
  414.             set
  415.             {
  416.                 this._JsonSettings = value;
  417.             }
  418.         }
  419.         public void SetupSerializer(JsonSerializer serializer)
  420.         {
  421.  
  422.             var settings = this.JsonSettings;
  423.             if (settings != null)
  424.             {
  425.                 settings.Converters.ToList().ForEach(ci => serializer.Converters.Add(ci));
  426.                 serializer.Formatting = settings.Formatting;
  427.                 serializer.DateTimeZoneHandling = settings.DateTimeZoneHandling;
  428.                 serializer.DateFormatString = settings.DateFormatString;
  429.                 serializer.DateFormatHandling = settings.DateFormatHandling;
  430.                 serializer.FloatFormatHandling = settings.FloatFormatHandling;
  431.                 serializer.FloatParseHandling = settings.FloatParseHandling;
  432.                 serializer.StringEscapeHandling = settings.StringEscapeHandling;
  433.                 serializer.Culture = settings.Culture;
  434.                 serializer.CheckAdditionalContent = settings.CheckAdditionalContent;
  435.                 serializer.ConstructorHandling = settings.ConstructorHandling;
  436.                 serializer.Context = settings.Context;
  437.                 serializer.ContractResolver = settings.ContractResolver;
  438.                 serializer.DefaultValueHandling = settings.DefaultValueHandling;
  439.                 serializer.MaxDepth = settings.MaxDepth;
  440.                 serializer.MissingMemberHandling = settings.MissingMemberHandling;
  441.                 serializer.NullValueHandling = settings.NullValueHandling;
  442.                 serializer.ObjectCreationHandling = settings.ObjectCreationHandling;
  443.                 serializer.PreserveReferencesHandling = settings.PreserveReferencesHandling;
  444.                 serializer.ReferenceLoopHandling = settings.ReferenceLoopHandling;
  445.                 if (settings.ReferenceResolver != null)
  446.                 {
  447.                     serializer.ReferenceResolver = settings.ReferenceResolver;
  448.                 }
  449.                 serializer.StringEscapeHandling = settings.StringEscapeHandling;
  450.                 serializer.TraceWriter = settings.TraceWriter;
  451.                 serializer.TypeNameAssemblyFormat = settings.TypeNameAssemblyFormat;
  452.                 serializer.TypeNameHandling = settings.TypeNameHandling;
  453.             }
  454.         }
  455.         public void SetupWriter(JsonWriter writer)
  456.         {
  457.             var settings = this.JsonSettings;
  458.             if (settings != null)
  459.             {
  460.                 writer.Formatting = settings.Formatting;
  461.                 writer.DateTimeZoneHandling = settings.DateTimeZoneHandling;
  462.                 writer.DateFormatString = settings.DateFormatString;
  463.                 writer.DateFormatHandling = settings.DateFormatHandling;
  464.                 writer.FloatFormatHandling = settings.FloatFormatHandling;
  465.                 writer.StringEscapeHandling = settings.StringEscapeHandling;
  466.                 writer.Culture = settings.Culture;
  467.                 writer.StringEscapeHandling = settings.StringEscapeHandling;
  468.             }
  469.  
  470.         }
  471.         public Message SerializeRequest(MessageVersion messageVersion, object[] parameters)
  472.         {
  473.             byte[] body;
  474.             Newtonsoft.Json.JsonSerializer serializer = new Newtonsoft.Json.JsonSerializer();
  475.             #region mysettings
  476.             this.SetupSerializer(serializer);
  477.             //serializer.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
  478.             #endregion
  479.             using (MemoryStream ms = new MemoryStream())
  480.             {
  481.                 using (StreamWriter sw = new StreamWriter(ms, Encoding.UTF8))
  482.                 {
  483.                     using (Newtonsoft.Json.JsonWriter writer = new Newtonsoft.Json.JsonTextWriter(sw))
  484.                     {
  485.                         #region mysettings
  486.                         SetupWriter(writer);
  487.                         writer.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
  488.                         #endregion
  489.  
  490.  
  491.  
  492.                         //writer.Formatting = Newtonsoft.Json.Formatting.Indented;
  493.                         if (parameters.Length == 1)
  494.                         {
  495.                             // Single parameter, assuming bare
  496.                             serializer.Serialize(sw, parameters[0]);
  497.                         }
  498.                         else
  499.                         {
  500.                             writer.WriteStartObject();
  501.                             for (int i = 0; i < this.operation.Messages[0].Body.Parts.Count; i++)
  502.                             {
  503.                                 writer.WritePropertyName(this.operation.Messages[0].Body.Parts[i].Name);
  504.                                 serializer.Serialize(writer, parameters[i]);
  505.                             }
  506.  
  507.                             writer.WriteEndObject();
  508.                         }
  509.  
  510.                         writer.Flush();
  511.                         sw.Flush();
  512.                         body = ms.ToArray();
  513.                     }
  514.                 }
  515.             }
  516.  
  517.             Message requestMessage = Message.CreateMessage(messageVersion, operation.Messages[0].Action, new RawBodyWriter(body));
  518.             requestMessage.Headers.To = operationUri;
  519.             requestMessage.Properties.Add(WebBodyFormatMessageProperty.Name, new WebBodyFormatMessageProperty(WebContentFormat.Raw));
  520.             HttpRequestMessageProperty reqProp = new HttpRequestMessageProperty();
  521.             reqProp.Headers[HttpRequestHeader.ContentType] = "application/json";
  522.             requestMessage.Properties.Add(HttpRequestMessageProperty.Name, reqProp);
  523.             return requestMessage;
  524.         }
  525.     }
  526. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement