Line Separator ‘\u2028’ parse incorrect using json.net - c#

static void Main(string[] args)
{
var newLineChar = Char.Parse("\u2028");
var jsonStr = #"{""value"":""some chars " + newLineChar + #"""}";
var jObject = Newtonsoft.Json.Linq.JObject.Parse(jsonStr);
var jsonStrAfterParse = jObject.ToString(Newtonsoft.Json.Formatting.None);
}
I have a JSON string like:
"{\"value\":\"some chars \u2028\"}"
After I try to parse it using Newtonsoft.Json, I got the JSON:
"{\"value\":\"some chars \\u2028\"}"
The Line Separator char '\u2028' was parsed to '\\u2028'. I cannot make sure whether any other chars have the same issue. Can anyone help with this? Thanks.
Pic in immediate window
jsonStr in text visualizer
jsonStrAfterParse in text visualizer

In the comments you established that it's expected behavior, but I thought I'd go into why based on the source code.
Your input string is not valid JSON because of the unescaped control character \u2028, but NewtonSoft.Json is gracefully handling the bad input, and giving correct output of \\u2028 when you ask it to serialize for you.
For the deserialization, it doesn't care that you didn't escape it. It just goes ahead and includes it with your string. No biggie.
But when you ask it to serialize the string for you with .ToString(Newtonsoft.Json.Formatting.None)--which is a Newtonsoft extension method--its job is to give you valid JSON, and by golly, that's what it's going to do, giving you the \\u2028 you see.

Related

how to get json from passed string via command line c#

I'm doing that for a reason. This is what i need for the next step of my application. I'm creating Visual Studio Extension and i need that for communication between plugin and proj.
I pass json string as argument of command line in visual studio.
When i load that string from the console it's devoid of certain json characters, making it impossible to deserialize.
What i paste as arg to console is:
{"lastModifiedDate":"2020-07-13T08:06:01Z","model":{"softwareSystems":[{"containers":[{"components":[{"location":0,"relationships":[{"sourceId":9,"destinationId":11,"technology":"","id":14,"name":null,"description":"","tags":"Relationship","tagsList":[]}],"id":9,"name":"system1 container1 component1","description":"","tags":"Element,Component","tagsList":[]},{"location":0,"relationships":[{"sourceId":10,"destinationId":9,"technology":"","id":16,"name":null,"description":"","tags":"Relationship","tagsList":[]}],"id":10,"name":"system1 container1 component2","description":"","tags":"Element,Component","tagsList":[]}],"location":0,"relationships":[{"sourceId":5,"destinationId":8,"technology":"","id":13,"name":null,"description":"","tags":"Relationship","tagsList":[]}],"id":5,"name":"system1 container1","description":"","tags":"Element,Container","tagsList":[]},{"components":[{"location":0,"relationships":[],"id":11,"name":"system2 container1 component1","description":"","tags":"Element,Component","tagsList":[]}],"location":0,"relationships":[{"sourceId":6,"destinationId":5,"technology":"","id":15,"name":null,"description":"","tags":"Relationship","tagsList":[]}],"id":6,"name":"system1 container2","description":"","tags":"Element,Container","tagsList":[]}],"location":0,"relationships":[{"sourceId":2,"destinationId":4,"technology":"","id":12,"name":null,"description":"","tags":"Relationship","tagsList":[]},{"sourceId":2,"destinationId":7,"technology":"","id":20,"name":null,"description":"","tags":"Relationship","tagsList":[]}],"id":2,"name":"Software System1","description":"My software system.","tags":"Element,Software System","tagsList":[]},{"containers":[{"components":[],"location":0,"relationships":[{"sourceId":7,"destinationId":6,"technology":"","id":17,"name":null,"description":"","tags":"Relationship","tagsList":[]}],"id":7,"name":"system2 container2","description":"","tags":"Element,Container","tagsList":[]},{"components":[],"location":0,"relationships":[{"sourceId":8,"destinationId":7,"technology":"","id":21,"name":null,"description":"","tags":"Relationship","tagsList":[]}],"id":8,"name":"system2 container1","description":"","tags":"Element,Container","tagsList":[]}],"location":0,"relationships":[],"id":4,"name":"Software System2","description":"","tags":"Element,Software System","tagsList":[]}],"people":[{"location":0,"relationships":[{"sourceId":1,"destinationId":2,"technology":"","id":3,"name":null,"description":"Uses","tags":"Relationship,Synchronous","tagsList":[]},{"sourceId":1,"destinationId":9,"technology":"","id":18,"name":null,"description":"","tags":"Relationship","tagsList":[]},{"sourceId":1,"destinationId":5,"technology":"","id":19,"name":null,"description":"","tags":"Relationship","tagsList":[]}],"id":1,"name":"User","description":"A user of my software system.","tags":"Element,Person","tagsList":[]}],"lastId":0},"views":{"systemContextViews":[{"softwareSystemId":2,"description":"An example of a System Context diagram.","configuration":{"styles":null},"elements":[{"id":4,"x":305,"y":300},{"id":1,"x":1255,"y":-5},{"id":2,"x":1190,"y":935}],"relationships":[{"id":3},{"id":12}]}],"containerViews":[{"softwareSystemId":2,"description":"","elements":[{"id":5,"x":110,"y":215},{"id":6,"x":1875,"y":715}],"relationships":[{"id":15}]},{"softwareSystemId":4,"description":"","elements":[{"id":8,"x":175,"y":224},{"id":7,"x":1845,"y":720}],"relationships":[{"id":21}]}],"componentViews":[{"containerId":5,"description":"","elements":[{"id":9,"x":120,"y":80},{"id":10,"x":1880,"y":1105},{"id":11,"x":130,"y":1000},{"id":1,"x":1760,"y":120}],"relationships":[{"id":14},{"id":16},{"id":18}]}]},"id":0,"name":"Demo workspace","description":"A demo workspace.","tags":"ElementBase,Workspace","tagsList":[]}
and from the console i get
"{lastModifiedDate:2020-07-13T08:06:01Z,model:{softwareSystems:[{containers:[{components:[{location:0,relationships:[{sourceId:9,destinationId:11,technology:,id:14,name:null,description:,tags:Relationship,tagsList:[]}],id:9,name:system1 container1 component1,description:,tags:Element,Component,tagsList:[]},{location:0,relationships:[{sourceId:10,destinationId:9,technology:,id:16,name:null,description:,tags:Relationship,tagsList:[]}],id:10,name:system1 container1 component2,description:,tags:Element,Component,tagsList:[]}],location:0,relationships:[{sourceId:5,destinationId:8,technology:,id:13,name:null,description:,tags:Relationship,tagsList:[]}],id:5,name:system1 container1,description:,tags:Element,Container,tagsList:[]},{components:[{location:0,relationships:[],id:11,name:system2 container1 component1,description:,tags:Element,Component,tagsList:[]}],location:0,relationships:[{sourceId:6,destinationId:5,technology:,id:15,name:null,description:,tags:Relationship,tagsList:[]}],id:6,name:system1 container2,description:,tags:Element,Container,tagsList:[]}],location:0,relationships:[{sourceId:2,destinationId:4,technology:,id:12,name:null,description:,tags:Relationship,tagsList:[]},{sourceId:2,destinationId:7,technology:,id:20,name:null,description:,tags:Relationship,tagsList:[]}],id:2,name:Software System1,description:My software system.,tags:Element,Software System,tagsList:[]},{containers:[{components:[],location:0,relationships:[{sourceId:7,destinationId:6,technology:,id:17,name:null,description:,tags:Relationship,tagsList:[]}],id:7,name:system2 container2,description:,tags:Element,Container,tagsList:[]},{components:[],location:0,relationships:[{sourceId:8,destinationId:7,technology:,id:21,name:null,description:,tags:Relationship,tagsList:[]}],id:8,name:system2 container1,description:,tags:Element,Container,tagsList:[]}],location:0,relationships:[],id:4,name:Software System2,description:,tags:Element,Software System,tagsList:[]}],people:[{location:0,relationships:[{sourceId:1,destinationId:2,technology:,id:3,name:null,description:Uses,tags:Relationship,Synchronous,tagsList:[]},{sourceId:1,destinationId:9,technology:,id:18,name:null,description:,tags:Relationship,tagsList:[]},{sourceId:1,destinationId:5,technology:,id:19,name:null,description:,tags:Relationship,tagsList:[]}],id:1,name:User,description:A user of my software system.,tags:Element,Person,tagsList:[]}],lastId:0},views:{systemContextViews:[{softwareSystemId:2,description:An example of a System Context diagram.,configuration:{styles:null},elements:[{id:4,x:305,y:300},{id:1,x:1255,y:-5},{id:2,x:1190,y:935}],relationships:[{id:3},{id:12}]}],containerViews:[{softwareSystemId:2,description:,elements:[{id:5,x:110,y:215},{id:6,x:1875,y:715}],relationships:[{id:15}]},{softwareSystemId:4,description:,elements:[{id:8,x:175,y:224},{id:7,x:1845,y:720}],relationships:[{id:21}]}],componentViews:[{containerId:5,description:,elements:[{id:9,x:120,y:80},{id:10,x:1880,y:1105},{id:11,x:130,y:1000},{id:1,x:1760,y:120}],relationships:[{id:14},{id:16},{id:18}]}]},id:0,name:Demo workspace,description:A demo workspace.,tags:ElementBase,Workspace,tagsList:[]}"
As you can see "{", double quotes are missing.
How i'm getting strings from console:
string[] commandLineArgs = Environment.GetCommandLineArgs();
I would need method which can convert to the same form because strings will be different
Do you know how to solve my problem?
c:\> myapp.exe "{\"asdf\":\"x yz\", \"xyz\": 3}"
worked for me (on Win10, can't test other versions right now).
Escape all doublequotes that belong to the JSON string with a \. Then enclose the whole json object with double-quotes to enclose the whitespaces, such that the string is not split upon multiple parameters.
EDIT
As an alternative, if you are in charge of creating and receiving the json string, you could use a more "CMD-friendly" format, for instance Base64. This way, you won't have to deal with spaces, quotes or other special characters on the command line
on the generating side:
var someobject = new {key1 = "value1", key2 = 3};
var json = Newtonsoft.Json.JsonConvert.SerializeObject(someobject);
var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(plainText);
var base64 = System.Convert.ToBase64String(plainTextBytes);
// base64 will look something like
// eyJrZXkxIjogInZhbHVlMSIsICJrZXkyIjogM30=
// depending on the formatting of the serialization
then pass that base64 as parameter on your commandline.
C:\>someapp.exe eyJrZXkxIjogInZhbHVlMSIsICJrZXkyIjogM30=
And on the receiving side do
var base64 = Environment.GetCommandlineArgs()[1];
var base64EncodedBytes = System.Convert.FromBase64String(base64);
var json = System.Text.Encoding.UTF8.GetString(base64EncodedBytes);
var someObject = Newtonsoft.Json.JsonConvert.DeserializeObject(json);
to escape double quotation ("), use it twice. so when you pass "" to command it will received as ".
for example pass data as:
ConsoleAppTest.exe "{""lastModifiedDate"":""2020-07-13T08:06:01Z"",""model"":""softwareSystems""}"
please refer to following similar answers:
Escape double quotes in parameter

Regular Expressions C#: Clean bad Json string

I get an answer from the server in the form of such JSON:
var zohozoho_atliview92 = {\"Itinerary\":[
{\"Client_Email\":\"garymc\",
\"Client_Name\":\"Gary\",
\"NT_Number\":\"NT-1237\",\"Number_of_Nights\":7,
\"ID\":\"24297940\",
\"Itinerary_Name\":\"Icelandnights\",
\"Tour_Template_Name\":\"Iceland FireDrive\",
\"Departure_Date\":\"2018-07-04\"}
]};
I need to remove this: var zohozoho_atliview92 = {\"Itinerary\":[ and delete last 3 characters ]}; to Deserialize it in my object.
How can i make it using Regular Expressions? Or is there a better variant?
is there a better variant?
Yes you can parse your json escaped string to JObject.
And then you can access any key/value pair from json with Querying JSON with LINQ
Or you can map your JObject to your custom type by using var result = jObject.ToObject<T>();
class Program
{
static void Main(string[] args)
{
var zohozoho_atliview92 = "{\"Itinerary\":[ {\"Client_Email\":\"garymc\", \"Client_Name\":\"Gary\", \"NT_Number\":\"NT-1237\",\"Number_of_Nights\":7, \"ID\":\"24297940\", \"Itinerary_Name\":\"Icelandnights\", \"Tour_Template_Name\":\"Iceland FireDrive\", \"Departure_Date\":\"2018-07-04\"}]}";
JObject jObject = JObject.Parse(zohozoho_atliview92);
Console.WriteLine(jObject);
Console.ReadLine();
}
}
Output:
This is not JSON, it's Javascript (wich object declaration is JSON).
Regular expressions are slow, I would advise you to use Substring
var start=inputString.IndexOf("[");
var end=("]");
var json=inputString.Substring(start, end-start);
There might be some of by one errors, test and correct.
It would be even faster but weaker to hardcode start.

Data at the root level is invalid - XML parsing

I am very new to programming and not sure where I am going wrong. I have read the other threads with similar error, but I think my problem is even basic.
I get a string generated which contains XML, but it doesnt start with an XML. When I try to parse that string I get the above error.
Is there a way of getting rid of the text and save the text from where the XML starts?
My string:
{"Id":"6a76f781-f592-4320-a116-6ab289505423","Name":"Test - A","AttachmentRequired":false,"FormXml":"
<?xml version=\"1.0\" encoding=\"utf-16\"?>
The easiest way would be to use a JSON parser like Newtonsoft:
public class Data
{
public string Id;
public string Name;
public bool AttachmentRequired;
public string FormXml;
}
var o = JsonConvert.DeserializeObject<Data>(json);
var xml = o.FormXml;
Here is the Nuget package to Newtonsoft which I demonstrated above:
https://www.nuget.org/packages/Newtonsoft.Json/
If you absolutely can't use an external library to transform it into a CLR object, here is how you would do it through string manipulation:
var str = #"{ ""Id"":""6a76f781-f592-4320-a116-6ab289505423"",""Name"":""Test - A"",""AttachmentRequired"":false,""FormXml"":""<?xml version=\""1.0\"" encoding=\""utf-16\""?>""}";
var parts = str.Split(':');
var last = parts[parts.Length -1];
var xml = last.Replace("}","").Replace("\"<","<").Replace(">\"",">");
your string appears to be in json format and xml part of it is a field value for "formxml". screenshot
Easy way is to deserialize the string into object using newtonsoft json, and then parse the value of formxml to your object.
JsonConvert.DeserializeObject<YourClass>(yourstring);

Deserialize JSON array into string array

Say I have a string representing an array of objects in JSON form:
string s = "[{\"name\":\"Person1\"},{\"name\":\"Person2\"}]";
What I want is an array of strings, each string being the string representation of a JSON object - NOT the object itself. It should look something like this:
string[] s = new string[]
{
"{\"name\":\"Person1\"}",
"{\"name\":\"Person2\"}"
};
1) Almost every search I attempt pulls up millions of results on how to simply deserialize a JSON string using (eg) Json.NET. This is not what I want to do.
2) I have tried building a class representing the objects to temporarily loop through a deserialize/serialize mapping each to a string in an array, but the schema for the objects is variable (hence why I only need a string representation).
3) I have attempted a few regex to try and do this, but my JSON string can contain fields that contain JSON strings as their value (icky, but out of my control) and so nested character escaping etc drove me partially mad before I decided to beg for help here.
Surely this should be simple? Anybody got any pointers?
You'll need to deserialize it, and then serialize each object independently.
For example (using Newtonsoft.Json):
string json = "[{\"name\":\"Person1\"},{\"name\":\"Person2\"}]";
var objects = JsonConvert.DeserializeObject<List<object>>(json);
var result = objects.Select(obj => JsonConvert.SerializeObject(obj)).ToArray();
Yields (as a string[]):
{"name":"Person1"}
{"name":"Person2"}
If you try to avoid deserializing and serializing, you're almost certain to run into an edge case that will break your code.
string s = "[{\"name\":\"Person1\"},{\"name\":\"Person2\"}]";
var Json = JsonConvert.DeserializeObject<List<object>>(s);
string[] Jsonn = Json.Select(x => x.ToString()).ToArray();
[] Jsonn returns string array instead of object array with JObject formatted.
Hope this one help you.
Why don't you just use this
string s = "[{\"name\":\"Person1\"},{\"name\":\"Person2\"}]";
string[] t = s.Split(',');
I tried it. It simply gives you string array as you want it....

Parsing a simple Json string

I have gotten a Json string to parse before that was an array of objects much longer than just a simple string, which makes me think that I'm doing something wrong with the formatting.
Here is word for word what our webservice is outputting as the json string:
{"news":"What is Legal/Awesome Dre"}
the first part is simply what I named the string in the application (news) and the second part is the string that will be changing as the song does which is why I would like to pull in a simple string of it.
When I run the app I'm getting a parse error at these lines:
Console.Out.Writeline (content);
news = JsonConvert.DeserializeObject(content);
The application output will show the Json string as it is on the website, but I get an error right after that's telling me Invalid Token: startPath... which last time meant that my Json string was formatted wrong for how I need to grab the data.
Anyone can help me with this?
(P.S. I am working in Xamarin Studio (mono for android) using C#, if that makes any difference)
The problem is that your serialized JSON object isn't a string, it's an object with the string value you want at the "news" property/key/name. This is a simple way to get the string:
dynamic jsonObj = JsonConvert.DeserializeObject(content);
string news = jsonObj.news;
Or you can use an anonymous type:
var jsonObj = JsonConvert.DeserializeAnonymousType(content, new { news = "" });
string news = jsonObj.news;
Or create a type with a string News property:
MyNewsType jsonObj = JsonConvert.DeserializeObject<MyNewsType>(content);
string news = jsonObj.News;
These all work in the following way:
var content = #"{""news"":""What is Legal/Awesome Dre""}";
// above code
Console.WriteLine(news); // prints "What is Legal/Awesome Dre"
Try to put square bracket in your JSON:
[{"news":"What is Legal/Awesome Dre"}]

Categories

Resources