Extracting a JSON object from a serialized string in C# - c#

Assuming I have a string that looks like this ...
string s = "{ \"id\": \"1\", \"name\" : \"Test\" } has other text in the same string";
Is there a way, in C#, to extract the JSON part of the text as its own "token" when splitting the string apart?
The goal is very simple. In a string that contains text, and possibly a JSON object, I just wanted to try and separate the text from the JSON so that I could pass one off to the appropriate facility. There is no deserialization needed, there is no validation needed, and there is no need to turn the JSON text into an object. I just wanted to be able to pull the text out.

When you are dealing with json, use a real json parser like Json.net. Regex is not enough to handle all extreme cases.
For example, suppose a string field which contains [ and you use Garath's answer. Booom.
string s = "{ \"id\": \"1\", \"name\" : \"Test\" }";
var anonymousObject = new { id = 0, name = "" };
anonymousObject = JsonConvert.DeserializeAnonymousType(s, anonymousObject);
Console.WriteLine(anonymousObject.name);
Other Serializer alternatives: JavaScriptSerializer, DataContractJsonSerializer .......

Bellow code should do what you are looking for (I tested it):
string s = "{ \"id\": \"1\", something:{xx:22, yyy: \"3\"}, \"name\" : \"Test\" } has other text in the same string";
var regexp = new Regex("([{].+[}])");
var match = regexp.Match(s);

Related

Passing JSON as a string in the body of the POST request

I need a small help, because I don't know how to solve the below problem.
The requirement is simple, I have to sent the JSON to the server as a string parameter. The server basing on the key finds the mapping, and generically parses the JSON to some objects. That means, that the payload can have a different values and structures, each key has its own mapping - different data structure, number of parameters and so on. So the payload shouldn't be parsed outside the endpoint logic.
I know, that the Swagger sees the payload as a JSON, not as a string, and it tries to parse the data. How can I send the JSON as a string parameter to the endpooint without parsing the parameter? I have to parse it inside of the application, because of the mentioned mappings.
Example JSON:
{
"key": "test",
"payload": "[{"IDNew":1,"NameNew":"t1","DescriptionNew":"t1d", "IntegerValueNew":1, "DecimalValueNew":123.3}]"
}
When I'm trying to send the data in Swagger, I'm getting the below results:
curl -X POST "http://localhost:5110/api/InboundData" -H "accept: */*" -H "Content-Type: application/json-patch+json" -d "{ \"key\": \"test\", \"payload\": \"[{\"IDNew\":1,\"NameNew\":\"t1\",\"DescriptionNew\":\"t1d\", \"IntegerValueNew\":1, \"DecimalValueNew\":123.3}]\"}"
{
"errors": {
"payload": [
"After parsing a value an unexpected character was encountered: I. Path 'payload', line 3, position 17."
]
},
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title": "One or more validation errors occurred.",
"status": 400,
"traceId": "|d952c89f-4e25126d8cdf3697."
}
Data model:
[Required]
[JsonProperty(Required = Required.DisallowNull)]
[MaxLength(100)]
public string Key { get; set; }
[Required]
[JsonProperty(Required = Required.DisallowNull)]
public string Payload { get; set; }
The error clearly suggests that your JSON is not correct. If we analyze the payload property:
{
"key": "test",
"payload": "[{"IDNew":1,"NameNew":"t1","DescriptionNew":"t1d", "IntegerValueNew":1, "DecimalValueNew":123.3}]"
}
It seems you are creating a string object which further contains a JSON as a string. Generally, when you pass an array, you would pass it like this.
{
"key": "test",
"payload": [
{
"IDNew": 1,
"NameNew": "t1",
"DescriptionNew": "t1d",
"IntegerValueNew": 1,
"DecimalValueNew": 123.3
}
]
}
But, since value of the payload property is not properly escaped, which is why it is not properly able to parse it as it has unexpected characters for a string value.
If you strictly want to pass a JSON Array as a string object, you need to properly escape it in order to get it working. For example below is a JSON that contains JSON as a string with properly escaped properties:
{
"key": "test",
"payload": "[{\"IDNew\":1,\"NameNew\":\"t1\",\"DescriptionNew\":\"t1d\", \"IntegerValueNew\":1, \"DecimalValueNew\":123.3}]"
}
This is how you would escape your JSON if you strictly want to pass a JSON object that further contains JSON as string.
Or, perhaps, use single quote (') instead for the nested JSON. For example below is a JSON that contains JSON as a string with a single quotes for the properties:
{
"key": "test",
"payload": "[{'IDNew':1,'NameNew':'t1','DescriptionNew':'t1d', 'IntegerValueNew':1, 'DecimalValueNew':123.3}]"
}
UPDATE
I just wanted to add a suggestion that would be less confusing and would generate an accurate output for the scenario.
It would be nice if you generate the models for your intended JSON string and serialize the model to get a JSON string then do the assignment to payload property.
var payload = new List<payloadSample1>();
payload.Add(new payloadSample1{ IDNew = 1, NameNew = "t1", DescriptionNew = "t1d" });
var payloadStr = JsonConvert.SerializeObject(payload);
// payloadStr would contain your JSON as a string.
In C#, you can also generate dynamic type objects. Use those if your JSON is constantly varying and you find it hectic to create many models for many api requests.
var payload = new List<dynamic>();
payload.Add(new { IDNew = 1, NameNew = "t1", DescriptionNew = "t1d" });
var payloadStr = JsonConvert.SerializeObject(payload);
// And even then, if you have a further JSON object to send:
var payloadParent = new { key = "test", payload = payloadStr };
// send payloadParent as your json.
This is not the cleanest approach because of many reasons one out of those would be, when there is a change in your model, you will have to manually analyze all your dynamic objects and change all the references where you are using it. But, certainly, it will reduce the confusion behind escaping and maintaining the strings.
If you are using JavaScript make the api call, then generate a proper JSON object and then stringify it to get a string.

When deserializing Json string that contains "\" gives Bad Json escape sequence

I have a input field in UI which contains a field Value with "\\test\a\b\c". The Json string in API after serialization has the Value field as below.
{
"ItemKey": "8b603493-3d2d-4903-a054-2abb895ab870",
"ParentKey": "00000000-0000-0000-0000-000000000000",
"Schema": "",
"SchemaTypeName": "",
"Value": "\\\\test\\a\\b\\c",
"ValueDefinition": null
}
When deserializing this string I get the error,
var result = JsonConvert.DeserializeObject<Class>(rootElement);
{"Bad JSON escape sequence: \\M. Path 'sample[0].sample[1].Value', line 1, position 3384."}
I tried double escaping "\" and this error is resolved.
var tempStr = valueReplacement.Replace(#"\\", #"\").Replace(#"//", #"/");
valueReplacement = tempStr.Replace(#"\", #"\\").Replace(#"/", #"//");
{"Value": "\\test\\a\\b\\c"}
But I need the final json that is generated after deserializing to have the value still the same because I need to integrate this with UI.
"Value": "\\test\a\b\c"
Is there any way I can change the value again after deserialization?

Write json object values without { ": , using c#

{
"FirstName" :"Kaustubh",
"LastName" :" Sawant ",
"StartTime" :"01:00:00"
}
I want to get printed
First Name: Kaustubh
Last Name: Sawant
Start time : 01:00:00
This is the demo code written the actual object retrieves more values.
Actual code :
String JsonValue=JsonConvert.SerializsObject(object);
also used Formatting.Indented and tried
Regex.Replace(JsonValue,#"\{},"","").Trim();
and then wrote into file using StreamWriter.
I think you are attacking this from the wrong angle, if this is truly json, you are best to deserialize it using something like json.net, and then building the string up out of the properties.
However, because you insist on doing it via replacement, you can make use of regex
var result = Regex.Replace(input, #"[,{}\"")]", "").Trim();
Console.WriteLine(result);
Output
FirstName :Kaustubh
LastName : Sawant
StartTime :01:00:00
Full Demo Here
Considering json is a string variable containing your input:
var json = #"
{
""FirstName"" :""Kaustubh"",
""LastName"" :"" Sawant "",
""StartTime"" :""01:00:00""
}";
Simple solution relying on standard library:
Console.WriteLine(json.Replace("{", "").Replace("}", "").Replace("\"","").Replace(",", "").Trim());
A solution using Newtonsoft.Json framework for deserializing json string:
var dict = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
foreach (var entry in dict)
{
Console.WriteLine($"{entry.Key}: {entry.Value}");
}

Unexpected character encountered while parsing value: j. Path '', line 0, position 0

t fails to deserialize/prase this json, ive tried multiple combinations with different methods to try and make this work but nothing seems to do it...
The code im using
WebClient wc = new WebClient();
var json = (JObject)JsonConvert.DeserializeObject(wc.DownloadString("http://services.runescape.com/m=website-data/playerDetails.ws?names=[%22" + Username.Replace(" ", "%20") + "%22]&callback=jQuery000000000000000_0000000000&_=0"));
the json its trying to deserialize...
jQuery000000000000000_0000000000([{"isSuffix":true,"recruiting":false,"name":"Sudo Bash","clan":"Linux Overlord","title":"the Troublesome"}]);
In Json specification you can see that [ indicates the begining array of json objects while { indicates beginning of new json object.
Your json string starts with [ so it can contains more json objects ( because it's an array and it contains jQuery000000000000000_0000000000( which is your query string parameter. To get rid of the query string garbage you should find out the scheme of that garbage and then to process json object I would recommend you to deserialize your json string into List<JObject> using JsonConvert.DeserializeObject<T>() method if your json string starts with [ ( use standard type if it is starting with { );
Example :
string url = // url from #Darin Dimitrov answer
string response = wc.DownloadString(url);
// getting rid of the garbage
response = response.Substring(response.IndexOf('(') + 1);
response = response.Substring(0, response.Length - 1);
// should get rid of "jQuery000000000000000_0000000000(" and last occurence of ")"
JObject result = null;
if(response.StartsWith('['))
{
result = JsonConvert.DeserializeObject<List<JObject>>(response)[0];
}
else
{
result = JsonConvert.DeserializeObject<JObject>(response);
}
What you are trying to deserialize is not JSON but rather JSONP (which is JSON wrapped in a function call).
Remove this parameter from your query string:
&callback=jQuery000000000000000_0000000000
and you should be good to go with a properly formatted JSON:
var url = "http://services.runescape.com/m=website-data/playerDetails.ws?names=[%22" + Username.Replace(" ", "%20") + "%22]&_=0";
var json = (JObject)JsonConvert.DeserializeObject(wc.DownloadString(url));

How to parse JSON objects with double quotes in one of its property values

If I have a json string, with one of its property values having a double quote in it, I am not able to parse it.
For example, if my object is { "Name" : "Six \" Pipe" } then the following gives me an error - Unexpected token P.
var str = '{ "Name" : "Six \" Pipe" }';
JSON.parse(str); //error
$.parseJSON(str); //error
The string is formed in a razor view as follows -
var str = new JavaScriptSerializer().Serialize(obj);
And then in JavaScript I am doing
var obj = JSON.parse('#(Html.Raw(str))');
How can I parse such strings?
You should escape the backslashes since in JS it will only \" will be converted to " and will make the JSON incorrect. The blackslash is discarded by javascript.
so the correct string would be-
var str = '{ "Name" : "Six \\" Pipe" }';
JSON.parse(str); //works
Edit:
So, if you want to create a literal backslash in JS, you have to escape it. You can do this while creating this string and double-escaping the key's value. One way to tackle this could be -
To html encode the strings (key values) just like: " instead of \" etc. This seems straight forward to me with .Net. I'm not sure but HttpServerUtility.HtmlEncode could help. Then on the javascript side you could be able to parse straight away- fiddle
I encountered same issue. After spending a lot of time trying to deal with that quotes I came to this solution
#{
var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
var obj = new {name = "\"Name1\""};
var objJson = serializer.Serialize(obj);
}
<script>
var jsObject = #Html.Raw(objJson);
</script>
I use json as js object without any parsing, html result will be like
<script>
var jsObject = {"name":"\"Name1\""} ;
</script>
which is correct JavaScript. Hope it will be helpfull for somebody

Categories

Resources