Build JSON Safely - c#
I'm running a project that is returning dynamically build JSON.
Recently I discovered that carriage returns, and double quotes the JSON string invalid (can't be loaded via an AJAX). I'm now replacing the parameter in question, removing any double quotes, and such, but I feel like I'm playing whack-a-mole.
Is there a better way?
In XML, for example, if I'm building a node, I can just call setAttribute( strMyJunkyString ), and it safely creates an attribute that will never break the XML, even if it has special characters, entities, etc.
Is there some sort of MakeStringJSONSafe() function, to remove anything that would break the array ([{}"\r\n])...
Here's a couple examples of a broken strings that my program is creating...
// String built with " included.
var t1 = [{"requestcomment":"Please complete "Education Provided" for all Medications "}];
// String built with returns embedded included.
var t2 = [{"requestcomment":"Please complete
Education Provided
History
Allergies
"}];
Use JSON.NET.
var jsonString = Newtonsoft.Json.JsonConvert.SerializeObject(new { requestcomment = "Please complete \"Education Provided\" for all Medications" });
and...
var jsonString = Newtonsoft.Json.JsonConvert.SerializeObject(new { requestcomment = "Please complete\nEducation Provided\nHistory\nAllergies" });
Related
c# ignoring { in strings
I'm trying to learn c# Json.net and I want to create a JSON multiline string that includes string declarations, but the first curly bracket which is meant to be part of the JSON dictionary is including itself in the declaration. It errors me on the 'name', if anyone can please give me a solution that would be great. here is the code. string Name = "'Name'"; string Is_Airing = "True"; string Genre_One = "'Yes'"; string Genre_Two = "'No'"; string Json_String = $#"{ 'Name': '{Name}', 'Is_Airing': {Is_Airing}, 'Genres': [ '{Genre_One}', '{Genre_Two}' ] }";
If your heart is set on DIY, double up the brackets to escape {{, but you're really [doing a poor job of] reinventing the wheel compared to using a serializer and chucking something like an anonymous or proper type into it: //newtonsoft JsonConvert.SerializeObject(new { Name, //gets name of property from name of variable Is_Airing = MyIsAiringVariableName, //specifies name of property in anonymous type Genres = new []{ Genre_One, Genre_Two } }); 'Name': '{Name}', JSON uses double quotes, by the way.. And typically uses camelCase names. Usign a serializer will ensure better compliance with standard JSON ("be strict in what you send and liberal in what you accept") For more control over how the output JSON appears, you set options on the serializer (such as passing Formatting.Indented as the second argument to SerializeObject), or decorate your properties with attributes The Newtonsoft documentation is quite comprehensive and includes useful samples to get you going: https://www.newtonsoft.com/json/help/html/SerializeObject.htm
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
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"}]
using strings in c#.net
Hi How do I retrieve the number from the following string, {"number":100,"data":[test]} The number could be of any length. I used the following code. but it gives and error message strValue.Substring((strValue.IndexOf(":")+1), (strValue.IndexOf("data"))); the output comes like 100,"data":[ Thanks,
It looks like your input string is JSON. Is it? If so, you should use a proper JSON parser library like JSON.NET
As noted by Jon, your input string seems to be a JSON string which needs to be deserialized. You can write your own deserializer, or use an existing library, such as Json.NET. Here is an example: string json = #"[ { ""Name"": ""Product 1"", ""ExpiryDate"": ""\/Date(978048000000)\/"", ""Price"": 99.95, ""Sizes"": null }, { ""Name"": ""Product 2"", ""ExpiryDate"": ""\/Date(1248998400000)\/"", ""Price"": 12.50, ""Sizes"": null } ]"; List<Product> products = JsonConvert.DeserializeObject<List<Product>>(json);
Your attempt is close. There are two (possibly three issues) I found. Your string has a comma after the number you're looking for. Since your code is searching for the index of "data", your end index will end up one character too far. The second paramter of String.Substring(int, int) is actually a length, not an end index. Strings are immutable in C#. Because of this, none of the member functions on a string actually modify its value. Instead, they return a new value. I don't know if your code example is complete, so you may be assigning the return value of SubString to something, but if you're not, the end result is that strValue remains unchanged. Overall, the result of your current call to string.Substring is returning 100,"data":[tes. (and as far as I can see, it's not storing the result). Try the following code: string justTheNumber = null; // Make sure we get the correct ':' int startIndex = strValue.IndexOf("\"number\":") + 9; // Search for the ',' that comes after "number": int endIndex = strValue.IndexOf(',', startIndex); int length = endIndex - startIndex; // Note, we could potentially get an ArguementOutOfRangeException here. // You'll want to handle cases where startPosition < 0 or length < 0. string justTheNumber = strValue.Substring(startIndex, length); Note: This solution does not handle if "number": is the last entry in the list inside your string, but it should handle every other placement in it. If your strings get more complex, you could try using Regular Expressions to perform your searches.
Parsing JSON spring in that way is very bad practice as everything is hardcoded. Have you though of using 3rd party library for parsing JSON strings, like Newtonsoft JSON.
I guess you needed to use IndexOf(",") istead of IndexOf("data")
Best way to deserialize a long string (response of an external web service)
I am querying a web service that was built by another developer. It returns a result set in a JSON-like format. I get three column values (I already know what the ordinal position of each column means): [["Boston","142","JJK"],["Miami","111","QLA"],["Sacramento","042","PPT"]] In reality, this result set can be thousands of records long. What's the best way to parse this string? I guess a JSON deserializer would be nice, but what is a good one to use in C#/.NET? I'm pretty sure the System.Runtime.Serialization.Json serializer won't work.
Using the built in libraries for asp.net (System.Runtime.Serialization and System.ServiceModel.Web) you can get what you want pretty easily: string[][] parsed = null; var jsonStr = #"[[""Boston"",""142"",""JJK""],[""Miami"",""111"",""QLA""],[""Sacramento"",""042"",""PPT""]]"; using (var ms = new System.IO.MemoryStream(System.Text.Encoding.Default.GetBytes(jsonStr))) { var serializer = new System.Runtime.Serialization.Json.DataContractJsonSerializer(typeof(string[][])); parsed = serializer.ReadObject(ms) as string[][]; } A little more complex example (which was my original answer) First make a dummy class to use for serialization. It just needs one member to hold the result which should be of type string[][]. [DataContract] public class Result { [DataMember(Name="d")] public string[][] d { get; set; } } Then it's as simple as wrapping your result up like so: { "d": /your results/ }. See below for an example: Result parsed = null; var jsonStr = #"[[""Boston"",""142"",""JJK""],[""Miami"",""111"",""QLA""],[""Sacramento"",""042"",""PPT""]]"; using (var ms = new MemoryStream(Encoding.Default.GetBytes(string.Format(#"{{ ""d"": {0} }}", jsonStr)))) { var serializer = new System.Runtime.Serialization.Json.DataContractJsonSerializer(typeof(Result)); parsed = serializer.ReadObject(ms) as Result; }
How about this?
It sounds like you have a pretty simple format that you could write a custom parser for, since you don't always want to wait for it to parse and return the entire thing before it uses it. I would just write a recursive parser that looks for the tokens "[", ",", "\"", and "]" and does the appropriate thing.