serialization - How to send group separator (non printable ascii characters) with RestSharp RestClient from C# -


updated

i have reworked question , included complete working example.

my succinct question now: how come i'm not seeing individual characters of string "\u001d" when use restsharp restclient , pick json requestformat options send simple object server? send output test server, , see 1d when examine output binary editor. expect 5c 75 30 30 31 64 ('\','u','0','0','1','d') , see if use newtonsoft.json serialize same simple object containing string "\u001d". understanding restsharp serialize object .json (if pick options accordingly) , send server deserialization.

using newtonsoft.json; using restsharp; using restsharp.serializers; using system; using system.collections.generic; using system.io;  /// <summary> /// test this, /// 1. first serialize string json , print out json string character array show /// '\' 'u' '0' '0' '1' 'd' show in serialized json string.  put in original string \\001d (double \) use later restsharp. /// 2. expect json string show if use restsharp send object web service because restsharp serializes json /// if it's configured.  ///  make use of http://posttestserver.com/  /// act "server", can examine data on site. copy data on server text file , open binary editor. /// notice there '1d' present between 12 , 34.   /// can perhaps duplicate serialization starting (double \). why should need that? /// notice try both restclient's serializer , try use newtonsoft serializer w/ restclient. /// 3.  tried send serialized string client had not been set json.  unfortunately, on server, shows  /// <string />.  not sure if it's me setting client incorrectly or what's going on. /// </summary> class program {     static void main(string[] args)     {         tank tank1 = new tank();         string string1 = "12\u001d34" + "  " + "56\\u001d78" ; // don't need double \\ serialization, perhaps need them restclient?         tank1.description = string1;// new string(array1);                   tank1.id = 1;          // show can serialize , each character of \u001d shows          jsonserializersettings settings = new jsonserializersettings { referenceloophandling = referenceloophandling.ignore };         string conversion1 = jsonconvert.serializeobject(tank1, formatting.indented, settings);         console.writeline("json serialized string (showing hidden characters");          foreach(char dummychar in conversion1.tochararray())         {             console.write(dummychar + "  ");             //console.write(conversion1.tochararray()[i] + "  ");         }            console.writeline();          // demonstrate straight restclient doesn't work.         restclient client1 = new restclient("http://posttestserver.com/"); // website let's push data @ it.          var request = new restrequest(method.post); // method method.post         request.addheader("content-type", "application/json");         request.addheader("x-acme-api-version", "1");         request.resource = "post.php?dir=david";  // put in unique name can find @ http://posttestserver.com/data/2016/         request.requestformat = dataformat.json;          request.addbody(tank1);          var response = client1.execute(request); // after line, go examine http://posttestserver.com/data/2016/ , find post         // copy text text file , open binary editor.  claim see 1d not / (47) or u (117) or 0 (48) i.e. 1d not \u001d          // try requestclient w/ json serializer....          request.jsonserializer = new jsonserializernewtonsoft();          response = client1.execute(request);          // finally, try sending json serialized stuff restclient has not been set json stufff         restclient client3 = new restclient("http://posttestserver.com/"); // website let's push data @ it.         request.resource = "post.php?dir=david";  // put in unique name can find @ http://posttestserver.com/data/2016/          var request3 = new restrequest(method.put); // method method.put // not sure put here         //request3.addheader("content-type", "application/json"); // not sure use here if         request3.addheader("x-acme-api-version", "1");         request3.resource = "post.php?dir=david";  // put in unique name can find @ http://posttestserver.com/data/2016/         request3.requestformat = dataformat.xml; // not sure use here          request3.addbody(conversion1);          var response3 = client3.execute(request3); // hard evaluate.  shows @ test server <string />      } }  interface itank {     int id { get; set; }     string description { get; set; } } public class tank : itank {     public tank() { }     public string description { get; set; }     public int id { get; set; } }  public class tanks {     public tanks() { }     public ienumerable<tank> group { get; set; } }  public class jsonserializernewtonsoft : iserializer {     private readonly newtonsoft.json.jsonserializer _serializer;      /// <summary>     /// default serializer     /// </summary>     public jsonserializernewtonsoft()     {         contenttype = "application/json";          _serializer = new newtonsoft.json.jsonserializer         {             missingmemberhandling = missingmemberhandling.ignore,             nullvaluehandling = nullvaluehandling.include,             defaultvaluehandling = defaultvaluehandling.include         };     }      /// <summary>     /// default serializer overload allowing custom json.net settings     /// </summary>     public jsonserializernewtonsoft(newtonsoft.json.jsonserializer serializer)     {         contenttype = "application/json";         _serializer = serializer;     }      /// <summary>     /// serialize object json     /// </summary>     /// <param name="obj">object serialize</param>     /// <returns>json string</returns>     public string serialize(object obj)     {         using (var stringwriter = new stringwriter())         {             using (var jsontextwriter = new jsontextwriter(stringwriter))             {                 jsontextwriter.formatting = formatting.indented;                 jsontextwriter.quotechar = '"';                  _serializer.serialize(jsontextwriter, obj);                 var result = stringwriter.tostring();                 return result;             }         }     }      /// <summary>     /// unused json serialization     /// </summary>     public string dateformat { get; set; }      /// <summary>     /// unused json serialization     /// </summary>     public string rootelement { get; set; }      /// <summary>     /// unused json serialization     /// </summary>     public string namespace { get; set; }      /// <summary>     /// content type serialized content     /// </summary>     public string contenttype { get; set; } } 

first, thank posting minimal, complete, , verifiable example can used reproduce problem; made easier help.

ok, there few things happening here leading results seeing. let's @ them 1 @ time.


first, creating string this:

string string1 = "12\u001d34" + "  " + "56\\u001d78"; 

the number of backslashes use does matter because has same special meaning in c# in json. specifically, notation \uxxxx in c# means, "insert unicode character 4-hexadecimal-digit (utf-16) character code xxxx string". conversely, notation \\ means "insert single \ character string". so, in first part of string, inserting single character 0x001d, group separator control character. in second part of string, inserting 6 characters: \, u, 0, 0, 1 , d. can see difference simple test program dumps out characters hex digits:

public class program {     public static void main()     {         dumpcharsashex("\u001d");   // inserts actual 0x001d character (group separator) string         dumpcharsashex("\\u001d");  // inserts chars '\', 'u', '0', '0', '1', 'd' string     }      private static void dumpcharsashex(string s)     {         if (s != null)         {             (int = 0; < s.length; i++)             {                 int c = s[i];                 console.write(c.tostring("x") + " ");             }         }         console.writeline();     } } 

output:

1d  5c 75 30 30 31 64 

fiddle: https://dotnetfiddle.net/8tjiix


second, there different behavior between json.net , simplejson (the restsharp internal serializer) respect control characters embedded in string. json.net recognizes control characters , converts them proper json escape sequence. (this conversion done javascriptutils.writeescapedjavascriptstring method, in turn calls stringutils.tocharasunicode.) restsharp, on other hand, no such conversion, , passes invisible control character through json unchanged. (you can see in simplejson.escapetojavascriptstring.)
again, simple test program demonstrates difference:

public class program {     public static void main()     {         foo foo = new foo { bar = "\u001d" };          string json = newtonsoft.json.jsonconvert.serializeobject(foo);         console.writeline(json);         dumpcharsashex(json);          string json2 = restsharp.simplejson.serializeobject(foo);         console.writeline(json2);         dumpcharsashex(json2);     }      private static void dumpcharsashex(string s)     {         if (s != null)         {             (int = 0; < s.length; i++)             {                 int c = s[i];                 console.write(c.tostring("x") + " ");             }         }         console.writeline();     } }  public class foo {     public string bar { get; set; }  } 

output:

{"bar":"\u001d"} 7b 22 42 61 72 22 3a 22 5c 75 30 30 31 64 22 7d  {"bar":""} 7b 22 42 61 72 22 3a 22 1d 22 7d 

fiddle: https://dotnetfiddle.net/caxzfq

as can see, in first json, produced json.net, control character in original string converted json character escape notation, coincidentally looks original c# code. when json deserialized on other end, converted control character.

in second json, produced restsharp, control character present (the 1d between 22s) though not visible in json output. should note incorrect behavior according section 9 of json spec (emphasis mine):

a string sequence of unicode code points wrapped quotation marks (u+0022). characters may placed within quotation marks except characters must escaped: quotation mark (u+0022), reverse solidus (u+005c), , control characters u+0000 u+001f.

since control character left in, mangled or reinterpretted in undesirable way during transmission on wire or during deserialization on other end.


third, in code looks trying use json.net substitute serializer restsharp, doesn't seem making difference in results. reason why because have statements out of order.

you doing this:

var request = new restrequest(method.post); ... request.requestformat = dataformat.json; request.addbody(tank1); request.jsonserializer = new jsonserializernewtonsoft(); response = client1.execute(request); 

notice calling addbody before set jsonserializer on request. restrequest.addbody method calls serializer json , adds result body of request; not done restclient.execute. time set alternate json serializer, it's late-- you've used internal serializer add json body of request , alternate serializer never called. reverse order of 2 statements , should work way want.

var request = new restrequest(method.post); ... request.requestformat = dataformat.json; request.jsonserializer = new jsonserializernewtonsoft(); request.addbody(tank1); response = client1.execute(request); 

hope makes sense.


Comments

Popular posts from this blog

php - How to add and update images or image url in Volusion using Volusion API -

javascript - IE9 error '$'is not defined -