C# OpenApi Json String response - c#

I am trying to print a Json String in OpenAPI response body, however all the escaped characters are printed, so it is not easy readable for the user. Ex: `
{\r\n\t"Name": "xxxx",\r\n\t"Version": "V1",\r\n\t"Platform":
"xxxx",\r\n\t"IsPuppetAgentServiceControllerRequired":
true,\r\n\t"AgentUrl":
"http://www.example.com",\r\n\t"Modules":\r\n\t{\r\n\t\t"module1":\r\n\t\t{\r\n\t\t\t"propertyname1":
"value1",\r\n\t\t\t"propertyname2":
"value2",\r\n\t\t\t"propertyname3": "value3"\r\n\t\t}...
I would like to show something like this:
{
Name: xxxxx,
Version: xxxx,
Module1: {
property: value,
property: value ....
The response is dynamically generated, it doesn't follow a predefined structure, so I can not add it to the scheme. Is there any way to achieve this?

If you have a valid Json string from the API as I commented, If your intention is to just print without escape characters then you could you use the Regex.Unescape
string readText = "<Your json String";
string str = Regex.Unescape(readText);
//OUTPUT
{
"Name": "xxxx",
"Version": "V1",
"Platform": "xxxx",
"IsPuppetAgentServiceControllerRequired": true,
"AgentUrl": "http://www.example.com",
"Modules": {
"module1": {
"propertyname": "value"
}
}
}
The get output you mentioned in your question the use JObject using parse method on escaped string as mentioned above code.
var testStr = JObject.Parse(str);
foreach (var pair in testStr)
{
Console.WriteLine("{0}: {1}", pair.Key, pair.Value);
}

You can try something like
EditedText = JsonText.Replace("\n", '\n');
You can use similar methodology to achieve what you are looking for.

Related

Newtonsoft.Json.JsonReaderException: Invalid JavaScript property identifier character: ,

I have this code
var list = new List<long>();
long id = 202;
list.Add(2000);
list.Add(2001);
list.Add(2002);
var stringOfIds = string.Join(",", list);
var paramList = #"{'ProjectId':" + id + ", 'EntityIDsList': " + stringOfIds + "}";
Console.WriteLine(paramList);
var parameters = JsonConvert.DeserializeObject<Dictionary<string, object>>(paramList);
Console.WriteLine(parameters);
for some particular reason, it doesn't Deserialize the object and it crashes. What I'm trying here to do is: transform a list of longs into a string, comma separated -> construct the paramList string and then deserialize it using Newtonsoft.Json. I believe that the error is somewhere in the stringOfIds but couldn't figure it out sadly. Do you know what am I doing wrong and how can I fix it?
Right now your paramList looks like this:
{
"ProjectId": 202,
"EntityIDsList":
2000,
2001,
2002
}
Which is not proper JSON. It should look like this:
{
"ProjectId": 202,
"EntityIDsList": [
2000,
2001,
2002
]
}
So you should change it to:
var paramList = #"{'ProjectId':" + id + ", 'EntityIDsList': [" + stringOfIds + "]}";
Also at this point Console.WriteLine(parameters); won't tell you anything meaningfull, you should probably change it to Console.WriteLine(parameters.ToString());
The string you have, paramList is not a valid JSON. JSON object has keys (and values if they are strings) surrounded with double quotes, not single quotes.
Corrected string with escaped double quotes:
#"{""ProjectId"": " + id + #", ""EntityIDsList"": """ + stringOfIds + #"""}";
If your purpose of writing this string is to convert it to an object, you should directly create an object. Also note that you cant print the objects with Console.WriteLine... you will need to convert this to a string first (JsonConvert.SerializeObject) then print it.
var parameters = new
{
ProjectId = id,
EntityIDsList = stringOfIds
};
Console.WriteLine(JsonConvert.SerializeObject(parameters, Formatting.Indented));
// output:
{
"ProjectId": 202,
"EntityIDsList": "2000,2001,2002"
}
If you want EntityIDList as a list of numbers, change the value of EntityIDsList to list instead of stringOfIds.
var parameters2 = new
{
ProjectId = id,
EntityIDsList = list
};
Console.WriteLine(JsonConvert.SerializeObject(parameters2, Formatting.Indented));
//output:
{
"ProjectId": 202,
"EntityIDsList": [
2000,
2001,
2002
]
}
You have two "problems"
you need to add extra single-quotes around the stringOfIds bit
maybe it's actually what you want, but... this will give you a dictionary with 2 items with keys: "ProjectId" and "EnitityIDsList".
As the list is stringified you may as well use D<string, string> (or dynamic, depending on what you're actually trying to do.
I'm guessing you will want to have a collection of "projects"? So the structure in the question won't work.
[
{ "1": "1001,1002" },
{ "2": "2001,2002" }
]
is the normal json form for a dictionary of items
[
{ "1": [1001,1002] },
{ "2": [2001,2002] }
]
into a D<string,List<int>> would be "better".
Strongly suggest you create classes/records to represent the shapes and serialize those. Rather than string concatenation. If you must, then try to use StringBuilder.
Also, although Newtonsoft will handle single quotes, they're not actually part of the spec. You should escape double-quotes into the string if you actually need to generate json this way.
Maybe this is just a cutdown snippet to demo your actual problem and I'm just stating the obvious :D
Just a load of observations.
The extra quotes is the actual "problem" with your sample code.

Remove single quote characters from specific field inside JSON data

I have this json data string below, which I need to do some cleaning before I can Deserialize into an object in C#. Here's my json string:
{'data':[
{'ID':'01','Name':'Name 1','Description':'abc','Skills':[{'Type':'abc','Technical':'abc','Description':'abc'}],'Status':false,'Inactive':0},
{'ID':'02','Name':'Name 2','Description':'abc','Skills':[{'Type':'abc','Technical':'abc','Description':'abc'}],'Status':false,'Inactive':0},
{'ID':'03','Name':'Name 3','Description':'abc','Skills':[{'Type':'abc','Technical':'abc','Description':'abc'}],'Status':false,'Inactive':1}]}
What I'm trying to do is REMOVE single quote (') character from the following field in the above data:
'Skills':[{'Type':'abc','Technical':'abc','Description':'abc'}]
So what I need to achieve is to have "Skills" field to look like this:
'Skills':[{Type:abc,Technical:abc,Description:abc}]
I designed this Regex patter:
(?<='Skills':\[\{)(.*?)(?=\}\],)
It matches the string below, but I don't know how to exclude single quotes.
'Type':'abc','Technical':'abc','Description':'abc'
Can someone please help?
It's better to modify the source to get pretty formatted JSON, it's not standard JSON format.
if you don't have access to modify the source output, you can use this :
string content = Console.ReadLine();
var matchResult = new Regex("(?<='Skills':).*?}]").Matches(content);
foreach(Match match in matchResult)
{
string matchValueWithoutSingleQuote = match.Value.Replace("'", string.Empty);
content = content.Replace(match.Value, matchValueWithoutSingleQuote);
}
Console.WriteLine(content);
Console.ReadLine();
the output is :
{'data':[
{'ID':'01','Name':'Name 1','Description':'abc','Skills':[{Type:abc,Technical:abc,Description:abc}],'Status':false,'Inactive':0},
{'ID':'02','Name':'Name 2','Description':'abc','Skills':[{Type:abc,Technical:abc,Description:abc}],'Status':false,'Inactive':0},
{'ID':'03','Name':'Name 3','Description':'abc','Skills':[{Type:abc,Technical:abc,Description:abc}],'Status':false,'Inactive':1}]}
Linq version :
string content = Console.ReadLine();
var matchResult = new Regex("(?<='Skills':).*?}]").Matches(content);
var jsonWithNormalizedSkillField = matchResult.Cast<Match>().Select(s => content.Replace(s.Value, s.Value.Replace("'", string.Empty))).FirstOrDefault();
Console.WriteLine(jsonWithNormalizedSkillField);
Console.ReadLine();

Extract only JSON from string in C#

I have a requirement in c# to extract the below JSON error message and read the title element.
I need to remove all the characters in the string and I want only starting from errors
i.e
{
"errors":
[{
"status": "404",
"title": "Not found data",
"detail": "This is a sample line of error detail."
}]
}
Please note that the exception can be anything so I just require to extract the JSON message starting from"errors".
Can you please assist me?
Code
string sb="{465F6CE7-3DF9-4BAF-8DD0-3E116CDAC9E7}0xc0c0167a0System.Net.WebException: There was no endpoint listening at http://TestData/member that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details.
{ "errors": [ { "status": "404", "title": "Not found data","detail": "This is a sample line of error detail." } ] }";
If you're asking how to extract a specific sequence of text from a random string of text, this sounds like a regular expression.
The lazy mans solution:
If you're just looking to read the title, you could just do IndexOf on "title", and then read to the next quotation mark that's not preceded by a backward-slash.
var pattern = #"\{(\s?)\'errors.*";
string sb = "{465F6CE7-3DF9-4BAF-8DD0-3E116CDAC9E7}0xc0c0167a0System.Net.WebException: There was no endpoint listening at http://TestData/member that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details. { 'errors': [ { 'status': '404', 'title': 'Not found data','detail': 'This is a sample line of error detail.' } ] }";
MatchCollection matches = Regex.Matches(sb, pattern);
I have changed the " to ', so just change the pattern to match ".
matches is not an array of all matches matches[0] will give you what you want.
You can use JSON.NET. So, you need to parse your string into JObject i.e.
string sb = #"{ ""errors"": [ { ""status"": ""404"", ""title"": ""Not found data"",""detail"": ""This is a sample line of error detail."" } ] }";
JObject jsonObject = JObject.Parse(sb);
JArray errors = (JArray)jsonObject["errors"];
foreach(var item in errors.Children())
{
int itemStatus = (int)item["status"];
string itemTitle = (string)item["title"];
string itemDetail = (string)item["detail"];
}
So, in this loop you can get what you want i have shown all the elements from the JSON that can be extracted.
Hope this helps you :)

How to read a string that is enclosed in specific tags and replace it with a different string?

I have a string that has multiple places to parse for strings enclosed in <%%> tags and replace it with appropriate values. If it is only one occurence of the tags, I could use IndexOf method to read the string and then use Replace method. How can I do it with multiple occurences of the tags? Thanks for any suggestions.
Example:
Read text1 <%GetName%> Read text2 <%GetID%> Read tex3 <%GetNumber%> and more
The output should be
Read text1 Value1 Read text2 Value2 Read text3 Value3
You could consider using regular expressions - specifically the Regex.Replace method
The regex you would require would be something like:
<%([^%]+)%>
Using a MatchEvaluator, you can replace the whole string with something specific based on the match:
var newText = Regex.Replace(textToCheck, "<%([^%]+)%>", (m) => {
switch (m.Groups[1].Value)
{
case "GetName":
return "New value";
...
}
});
You can use regex and a dictionary to map the values.....
var toReplace = new Dictionary<string, string>()
{
{"GetName", "Value1" },
{"GetID", "Value2" },
{"GetNumber", "Value3" },
};
string input = #"Read text1 <%GetName%> Read text2 <%GetID%> Read tex3 <%GetNumber%> and more";
var output = Regex.Replace(input, #"<%(.+?)%>", m => toReplace[m.Groups[1].Value]);
OUTPUT:
Read text1 Value1 Read text2 Value2 Read tex3 Value3 and more
There's an alternative to regular expressions using a dictionary to map template parameters to values to replace them in a given string template:
public static class StringTemplatingExtensions
{
public static string ParseTemplate(this string template, IDictionary<string, object> valueMap)
{
foreach(var pair in valueMap)
{
template = template.Replace($"<%{pair.Key}%>", pair.Value.ToString());
}
return template;
}
}
So it can be used as follows:
var template = "Read text1 <%GetName%> Read text2 <%GetID%> Read tex3 <%GetNumber%>";
var parsed = template.ParseTemplate(new Dictionary<string, object> {
{ "GetName", "Matías" },
{ "GetID", "114894" },
{ "GetNumber", "282893" }
});
Note that this solution is less flexible than others, because it won't support <% VARIABLE %>, <%VARIABLE %>, but just <%VARIABLE%> (without spaces). BTW, it's a very simple but yet effective way of implementing your requirement and it just works!

Find string between brackets

I'm having a string that could look like this:
{
"acl_gent": {
"cluster": [],
"indices": [{
"names": ["am*"],
"privileges": ["read", "view_index_metadata"],
"query": "{\"match\": {\"ACL\": \"acl_gent\"}}"
}],
"run_as": []
},
"acl_luik": {
"cluster": [],
"indices": [{
"names": ["am*"],
"privileges": ["read", "view_index_metadata"],
"query": "{\"match\": {\"ACL\": \"acl_luik\"}}"
}],
"run_as": []
}
}
and I would like to split it up in to 2 strings, 1 containing the acl_gent and one conaining acl_luik
the string above can contain more then 2 acl's (and I DON'T know what the name will be)
so I started removing the first and last bracketes :
input = input.Substring(1, input.Length - 2);
but then I can't figure out on how to find the right closing bracket to extract the data.
this was the closest I got
private int closer(string input) {
var i = input.IndexOf('}');
Console.WriteLine(string.Format("[DEBUG] Checking: {0}", input.Substring(0, i).Contains('{')));
if (input.Substring(0, i).Contains('{')) {
return i + closer(input.Substring(i)) + 2;
}
return i;
}
What you have there is a JSON string, a common response from a web service, and there are plenty of libraries to parse JSON, the most common one being JSON.NET. With this you could do something like
JObject myJsonObject = JObject.Parse(myResponse)
and retrieve your strings by their key names, such as
JObject aclString = myJsonObject["acl_luik"];
There are plenty of resources online for parsing JSON strings if you wish to go into more detail.
You have 2 options here:
1) Parse as JSON and get the first 2 objects, this is the better one.
2) Parse using Stack as string of tokens to get what you want, like this:
- Remove the first and last { }
- Using stack, add all { you find, and once you find } remove the first { in the stack.
- Once the stack is empty then you get 1 complete object there, save the indeces while you work and it should be easy to substring with start and end.
I ran into the same problem recently. My solution was to deserialize the string to a json object (in my case a JObject using Json.net) and then accessing the individual members and serializing them to separate strings.
using Newtonsoft.Json.Linq;
public void MakeStrings(string json)
{
var jobject = JsonConvert.DeserializeObject<JObject>(json);
string acl_gent = JsonConvert.SerializeObject(jobject["acl_gent"]);
string acl_luik = JsonConvert.SerializeObject(jobject["acl_luik"]);
}

Categories