Json.Net parsing datetime value error - c#

I am trying to convert a json string to a JObject using JObject.Parse, but running into the error "Error parsing positive infinity value. Path 'Modified.Date', line 1, position 52."
Here is the part of json that is throwing the error on -
{ ..., "Modified" : { "Date" : ISODate("2013-02-21T22:23:57.118Z"), "User" : "Admin" }, ...}
Here is the code I am using to do the parse -
var jobj = JObject.Parse(formJson)
Update: The json was generated by using mongodb's .ToJson() extension method, by sending in the following jsonwritersettings it generated json that was parsable by json.net - new JsonWriterSettings { OutputMode = JsonOutputMode.JavaScript };

I think you need to lose the ISODate.
This works:
String MyJson = "{MyDate : \"2013-02-21T22:23:57.118Z\" }";
var x = Newtonsoft.Json.Linq.JObject.Parse(MyJson);

I tried using Regex and convert in C#:
Regex _regex = new Regex(#"\d\d\d\d-\d\d-\d\d");
Match _date = _regex.Match(<Your_Date_String>);
if (_date.Success)
{
var datetime = Convert.ToDateTime(_date.Value);
}

Related

How can I convert these escape sequences back to their original characters?

JsonNode.Parse() seems to convert my < and > to the escape sequences \u003C and \u003E when they appear inside double-quotes "".
How can I convert these escape sequences back to their original characters?
This is my C# code:
using System.Text.Json.Nodes;
Console.WriteLine("JsonNode test");
var testString = "{ \"testString\" : \"<...>\" }";
Console.WriteLine($"{testString}, {testString.Length}");
var jsonNode = JsonNode.Parse(testString);
var jsonString = jsonNode.ToJsonString();
Console.WriteLine($"{jsonString}, {jsonString.Length}");
Output:
JsonNode test
{ "testString" : "<...>" }, 26
{"testString":"\u003C...\u003E"}, 32
I've tried the HtmlDecode and UrlDecode methods, but they are not right for this situation.
The json is still valid, but I usually always recommend to use Neftonsoft.Json since it has much much less problems, but you can use a string Replace as well
var jsonNode = JsonNode.Parse(testString);
var jsonString = jsonNode.ToJsonString().Replace("\\u003C","<").Replace("\\u003E",">");
result
{"testString":"<...>"}
another option is to use UnsafeRelaxedJsonEscaping, but it is not safe in some cases
var options = new JsonSerializerOptions
{
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
WriteIndented = true
};
var jsonString = System.Text.Json.JsonSerializer.Serialize(jsonNode, options);

How To String Format Complex Json Body in C#

i have the following code
var UUID = "ExampleX";
var NumID = "ExampleY";
var Payload = string.Format("{\"API1\":{\"API2\":\"API3\",\"API4\":5},\"API6\":\"{0}\",\"API7\":\"{1}\",\"API8\":\"API8\"}",UUID,NumID);
i'm trying to replace the input for {0} and {1} with UUID and NumID but i kept getting the following Error
Input string was not in a correct format.
i'm still learning how to code any help is appreciated
You could parse the Json String as JObject and then replace the API6 and API7 values. For example,
var json = "{\"API1\":{\"API2\":\"API3\",\"API4\":5},\"API6\":\"{0}\",\"API7\":\"{1}\",\"API8\":\"API8\"}";
var jo = JObject.Parse(json);
jo["API6"] = UUID;
jo["API7"] = NumID;
var Payload = jo.ToString();
Output
{
"API1": {
"API2": "API3",
"API4": 5
},
"API6": "ExampleX",
"API7": "ExampleY",
"API8": "API8"
}
You have to escape the json brackets with double brackets so they are not interpreted as a placeholder:
var Payload = string.Format("{{\"API1\":{{\"API2\":\"API3\",\"API4\":5}},\"API6\":\"{0}\",\"API7\":\"{1}\",\"API8\":\"API8\"}}",UUID,NumID);

How to deserialize string to JObject without scientific notation in C#

I have a string like this:
var str = "{'data': {'someProperty': 0.00001}}";
When I parse it to JObject like that
var jObject = JObject.Parse(str);
My jObject looks like this:
{"data": {"someProperty": 1E-05}}
I need to get rid of scientific notation so that resulting JObject would look like original json.
I managed to do that using later version of Newtonsoft.Json like that:
var serializer = new JsonSerializer { FloatParseHandling = FloatParseHandling.Decimal };
using (System.IO.TextReader tr = new System.IO.StringReader(str)
using (var jsonReader = new JsonTextReader(tr))
{
var jp = serializer.Deserialize(jsonReader);
var jObject = JObject.FromObject(jp);
}
But I need to achieve the same result using Newtonsoft.Json version 3.5 which does not have a FloatParseHandling property. I guess I need to implement a JsonConverter somehow, but I have no idea how to do that, since my real json is much more complex than the one in example and I need to handle all the float values in it the right way.
So, what would be the right way to get a JObject without a scientific notation for float values using Newtonsoft 3.5?
Following produces the object you are looking for
JObject.Load(new JsonTextReader(new StringReader(str)) { FloatParseHandling = FloatParseHandling.Decimal }, null)
taken from here:
EDIT:
JTokenTypes in NewtonSoft v 3.5.8 are limited to Float and Integer (in regards to decimal). There is no decimal type in that version and thus makes it not possilbe to have a decimal value in that JObject.
JTokenTypes from v3 of newtonsoft
None = 0,
Object = 1,
Array = 2,
Constructor = 3,
Property = 4,
Comment = 5,
Integer = 6,
Float = 7,
String = 8,
Boolean = 9,
Null = 10,
Undefined = 11,
Date = 12,
Raw = 13,
Bytes = 14
The right way to do this would be to upgrade the Newtonsoft package :)
Jawad's provided code is not the best solution because it will end up in memory leaks. StringReader and JsonTextReader are both implementing the IDisposable interface and therefore must be disposed if they are not used anmyore.
Safer code would be:
public JObject CustomJObjectLoad(string str)
{
using (var stringReader = new StringReader(str))
{
using (var jsonReader = new JsonTextReader(stringReader) { FloatParseHandling = FloatParseHandling.Decimal })
{
return JObject.Load(jsonReader, null);
}
}
}
You can also create simple POCO object. and make sure someProperty is of type string and then de-serialize the json string
var myObject = Newtonsoft.Json.JsonConvert.DeserializeObject<YourObject>(json)
First, your json isn't valid :)
It should have double quotes:
{"data": {"someProperty": 0.00001}}
But even better, using standard casing, would be:
{"Data": {"SomeProperty": 0.00001}}
And then, we can do this:
var str = "{\"Data\": {\"SomeProperty\": 0.00001}}";
dynamic myObject = JsonConvert.DeserializeObject(str);
var val = myObject.Data.SomeProperty.ToString("0." + new string('#', 339));
val will then be: "0.00001"
(Note: I stole the solution from: Double to string conversion without scientific notation)

Store Hardcoded JSON string to variable

I'm having an issue storing this json string to a variable. It's gotta be something stupid I am missing here
private string someJson = #"{
"ErrorMessage": "",
"ErrorDetails": {
"ErrorID": 111,
"Description": {
"Short": 0,
"Verbose": 20
},
"ErrorDate": ""
}
}";
You have to escape the "'s if you use the # symbol it doesn't allow the \ to be used as an escape after the first ". So the two options are:
don't use the # and use \ to escape the "
string someJson = "{\"ErrorMessage\": \"\",\"ErrorDetails\": {\"ErrorID\": 111,\"Description\":{\"Short\": 0,\"Verbose\": 20},\"ErrorDate\": \"\"}}";
or use double quotes
string someJson =#"{""ErrorMessage"": """",""ErrorDetails"": {""ErrorID"": 111,""Description"": {""Short"": 0,""Verbose"": 20},""ErrorDate"": """"}}";
First things first, I'll throw this out there: It's for this reason in JSON blobs that I like to use single quotes.
But, much depends on how you're going to declare your string variable.
string jsonBlob = #"{ 'Foo': 'Bar' }";
string otherBlob = #"{ ""Foo"": ""Bar"" }";
...This is an ASCII-encoded string, and it should play nicely with single quotes. You can use the double-double-quote escape sequence to escape the doubles, but a single quote setup is cleaner. Note that \" won't work in this case.
string jsonBlob = "{ 'Foo': 'Bar' }";
string otherBlob = "{ \"Foo\": \"Bar\" }";
...This declaration uses C#'s default string encoding, Unicode. Note that you have to use the slash escape sequence with double quotes - double-doubles will not work - but that singles are unaffected.
From this, you can see that single-quote JSON literals are unaffected by the C# string encoding that is being used. This is why I say that single-quotes are better to use in a hardcoded JSON blob than doubles - they're less work, and more readable.
Simple Approach is to copy the JSON to a .json file and read that file in the code
string jsonData = string.Empty;
jsonData = File.ReadAllText(#"\UISettings.json");
Writing JSON inline with c# in strings is a bit clunky because of the double quotes required by the JSON standard which need escaping in c# as shown in the other answers. One elegant workaround is to use c# dynamic and JObject from JSON.Net.
dynamic message = new JObject();
message.ErrorMessage = "";
message.ErrorDetails = new JObject();
message.ErrorDetails.ErrorId = 111;
message.ErrorDetails.Description = new JObject();
message.ErrorDetails.Description.Short = 0;
Console.WriteLine(message.ToString());
// Ouputs:
// {
// "ErrorMessage": "",
// "ErrorDetails": {
// "ErrorID": 111,
// "Description": {
// "Short": 0
// .....
See https://www.newtonsoft.com/json/help/html/CreateJsonDynamic.htm.
I had this same problem I ended up writing an open source online converter that takes a JSON string and spits out the C# excaped string with the double quotes syntax. So
{ "foo":"bar"}
will be escaped into
var jsonString = #"{ ""foo"":""bar""}";
https://json-to-c-sharp.ndolestudio.com
https://github.com/AchoArnold/json-to-c-sharp
Starting from C# 11 supported on .NET 7, it's possible to embed a JSON string without any modification by enclosing it in triple quote characters, a feature called Raw string literal (learn.microsoft.com). Related useful language feature is StringSyntaxAttribute that allows Visual Studio to recognize the string variable is a JSON string and highlight any typos. A sample:
using System.Diagnostics.CodeAnalysis;
using System.Text.Json;
internal class Program
{
[StringSyntax(StringSyntaxAttribute.Json)]
private const string myCountry = """{"Name": "Slovakia", "CountryCode": 421}""";
private static void Main(string[] args)
{
var _ = JsonSerializer.Deserialize<Country>(myCountry);
}
class Country
{
public string Name { get; set; } = default!;
public int CountryCode { get; set; }
}
}
A Put the cart before the horse solution would be to serialize a anonymous class into a string:
var someJson = JsonConvert.SerializeObject(
new
{
ErrorMessage = "",
ErrorDetails = new
{
ErrorID = 111,
Description = new
{
Short = 0,
Verbose = 20
},
ErrorDate = ""
}
});
If you are using Visual Studio, then Select the whole JSON string then crtl+f to find the double quotes in the selection and then replace " with ""

JSON parse exception using System.Json

I get an error while parsing a json string into an object. I am using system.json to parse the json string.
The JSON file: (NOTE: I cannot change the structure of this json file because it is generated)
{
title: "My Title",
log: "",
nid: "1234",
type: "software",
language: "EN",
created: "1364480345",
revision_timestamp: "1366803957",
body: {
und: [
{
value: "abc",
summary: "def"
}
]
}
}
The C# code:
string jsonString = new WebClient().DownloadString(".......MyJson.json"); //For test purpose
var obj = JsonObject.Parse (jsonString); ///<--- At this line the exception is thrown
The Exception:
System.ArgumentException has been thrown.
Invalid JSON string literal format. At line 1, column 2
How to solve this?
Thanks in advance!
You can't. That isn't valid json. Field names must be enclosed in quotes. All json parsing tools will throw when trying to parse that.
You could process it and turn it to valid json before deserializing, but really, you need to correct it API side. No clients will work with that.
How to solve this?
(NOTE: I cannot change the structure of this json file because it is generated)
Easy, use json.Net. it works without any problem with your json
var j = JObject.Parse(jsonString);
You can even use dynamic keyword
dynamic j = JObject.Parse(jsonString);
Console.WriteLine("{0},{1}", j.title, j.body.und[0].value);

Categories