How to handle bad Json response in C# using JsonConvert - c#

I am using a web service to get response and found the Json is not in the right format. Please see the below sample.
The Object structure is :
public class Action
{
public string serialNumber { get; set; }
public string method1 { get; set; }
public string recipient1 { get; set; }
public string notifyon1 { get; set; }
}
We having a field "recipient1" which has value "1#test.com,2#test.com,3#test.com" then the api response the json as below.
Bad json response :
{"serialNumber": "2471",
"method1": "email",
"recipient1": "1#test.com",
"2#test.com": "",
"3#test.com": "",
"notifyon1": "warning",
"critical": ""}
Which is supposed to be :
{"serialNumber": "2471",
"method1": "email",
"recipient1": "1#test.com,2#test.com,3#test.com",
"notifyon1": "warning,critical"}
First I was trying to using regex to convert these emails values to the right field. But then I found it is happened for all the value which include comma "," . Such as ”Notifyon1“ in the above sample.
Now I am thinking if there is any way I can do parse the json, when it find "2#test.com" then check the Object, if it is not a property then put it as a value into previous field "recipient1".
Thanks for all your help.

This will work regardless of empty values in the properties.
using Newtonsoft.Json;
private Action HandleBadJson(string badJson)
{
Dictionary<string, string> dictionary = JsonConvert.DeserializeObject<Dictionary<string, string>>(badJson);
Action act = new Action();
List<string> propertyNames = act.GetType().GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance).Select(p => p.Name).ToList();
string currentProperty = "";
foreach (var keyValPair in dictionary)
{
if (propertyNames.Contains(keyValPair.Key))
{
currentProperty = keyValPair.Key;
act.GetType().GetProperty(currentProperty).SetValue(act, keyValPair.Value);
continue;
}
else
{
var currentValue = act.GetType().GetProperty(currentProperty).GetValue(act, null);
string value = currentValue + "," + keyValPair.Key;
value = value.Trim(',');
act.GetType().GetProperty(currentProperty).SetValue(act, value);
}
}
return act;
}

Related

Extract value for key from json c#

I have the following Json (is a file attached to the project):
{
"Errors": {
"NoCountry": {
"MSG": "The CountryCode field is required.",
"Description": "Error encountered when Country parameter is missing from the request"
},
"NoLOI": {
"MSG": "Validation failed: \r\n -- LengthOfInterview cannot be empty"
"Description": "Error encountered when LOI parameter is missing from the request"
}
}
}
I need to extract the values for e.g. Errors.NoCompletes.MSG in order to use it in an assert to compare it with an output that i get from the API.
Till now i tried to create a dictionary that looks like this:
public class ErrorsDictionary
{
public string MSG;
public string Description;
}
public class DicRoot
{
public Dictionary<string, ErrorsDictionary> Errors { set; get; }
}
And use it like this:
DicRoot Json = JsonConvert.DeserializeObject<DicRoot>(File.ReadAllText(#"c:\users\banu_\source\repos\TestJsonLib\TestJsonLib\Json\ErrorMSG.json"));
foreach (var f in Json.Errors)
{
Console.WriteLine("Nume={0} Mesaj={1} Description={2}",f.Key, f.Value.MSG, f.Value.Description);
}
The problem is that i cannot figure out, how can i extract a specific value, like what i said above for Errors.NoLOI.MSG, in order to be able to use it in an assert like Assert.Equals(ex, MyParam);
You can also use JsonPath, anonymous types and string interpolation if you like:
JObject obj = JObject.Parse(json);
var errors = obj
.SelectTokens("$.Errors.*")
.ToDictionary(
e => ((JProperty)e.Parent).Name,
e => new { Msg = e["MSG"], Descr = e["Description"] });
foreach (var e in errors)
{
Console.WriteLine($"Nume={e.Key} Mesaj={e.Value.Msg} Description={e.Value.Descr}");
}
I think what you are asking for is this?
DicRoot dict = JsonConvert.DeserializeObject<DicRoot>(File.ReadAllText("foo.json"));
string msg = dict["NoLOI"].MSG;
I know this looks like a bit working around. However, it's working.
class Program
{
static void Main(string[] args)
{
string json = "{\"Errors\": {\"NoCountry\": {\"MSG\": \"The CountryCode field is required.\",\"Description\": \"Error encountered when Country parameter is missing from the request\"},\"NoLOI\": {\"MSG\": \"Validation failed: \r\n -- LengthOfInterview cannot be empty\", \"Description\": \"Error encountered when LOI parameter is missing from the request\"},}}";
var Json = JsonConvert.DeserializeObject<ErrorsClass>(json);
var obj = JsonConvert.DeserializeObject<Dictionary<string, ErrorsDictionary>>(Json.Errors.ToString());
foreach (var f in obj)
{
Console.WriteLine("Nume={0} Mesaj={1} Description={2}", f.Key, f.Value.MSG, f.Value.Description);
}
Console.Read();
}
}
public class ErrorsDictionary
{
public string MSG { get; set; }
public string Description { get; set; }
}
public class DicRoot
{
public Dictionary<string, ErrorsDictionary> ErrorsDic { set; get; }
}
class ErrorsClass
{
public object Errors { get; set; }
}
Output:
Nume=NoCountry Mesaj=The CountryCode field is required. Description=Error encountered when Country parameter is missing from the request
Nume=NoLOI Mesaj=Validation failed:
-- LengthOfInterview cannot be empty Description=Error encountered when LOI parameter is missing from the request
You can use Newtonsoft.json NuGet. Try this
var files = JObject.Parse(YourJson);
var recList = files.SelectTokens("$..Errors").ToList();
foreach (JProperty prop in recList.Children())
{
string key = prop.Name.ToString();
string value = prop.Value.ToString();
//Do your stuffs here
}

Get values from dynamic JSON properties C#

I am working on WCF and I want to get record list array date wise and I need array key as the date which has common in record like below:
{
"EventAppGetAllSessionByCustomerIdResult":{
"02/22/2017":[
{
"SessionDate":"02/22/2017"
}
],
"08/27/2016":[
{
"SessionDate":"08/27/2016"
}
],
"Status":{
"Description":"Successfull!",
"Status":1
}
}
}
Basically, I want to extract values of SessionDate.
I assumed that you want to extract "SessionDate" property from your JSON. I recommend using JObject.Parse() method.
JObject jObject = JObject.Parse(json);
var result = (JObject)jObject["EventAppGetAllSessionByCustomerIdResult"];
var dates = new List<string>();
foreach(JProperty prop in result.Properties())
{
if (prop.Name != "Status")
{
var values = jObject["EventAppGetAllSessionByCustomerIdResult"][prop.Name].Values<string>("SessionDate");
dates.AddRange(values);
}
}
Little explanation:
In your case "02/22/2017" is property which has an array of objects. Each object has "SessionDate" property which holds value. So, following line will extract values from "SessionDate" of all objects:
var values = jObject["EventAppGetAllSessionByCustomerIdResult"][prop.Name].Values<string>("SessionDate");
values represents all dates from a single property. In your case, it can be from "02/22/2017" or from "08/27/2016".
dates will be list of "SessionDate" values. Of course, you have to handle possible exceptions by yourself.
I'm not sure its what you want but try this as your output object:
public class Session
{
public string SessionDate { get; set; }
}
public class Status
{
public string Description { get; set; }
public int Code { get; set; }
}
public class EventAppGetAllSessionByCustomerIdResult
{
public KeyValuePair<string, Session[]>[] EventAppGetAllSessionByCustomerId { get; set; }
public Status Status { get; set; }
}

Updating Field in RavenDB Document

Good day,
I have a RavenDB JSON Document in which one field ("Info") contains a string that looks like this:
"{\"value1\":\"9\", \"value2\": \"dog\", ....}"
I would like to remove the escaping "\" characters so it will be recognized as a JSON List by RavenDB.
However, I have tried updating the Documents with
newString = oldString.Replace("\\", "") ,
newString = oldString.Replace(#"\", "")
and newString = oldString.Trim(new Char[] { #"\" })
but it does not work. After applying these above mentioned methods the string looks unchanged.
Please see below the full code:
while(true)
{
var result = session.Query<Documents>()
.Take(1000).Skip(i)
.ToList();
if (result.Count == 0)
break;
foreach (var r in result)
{
string rInfo = r.Info.ToString();
rInfo = rInfo.Replace("\\", "");
PATCHED_Doc r_Doc = new PATCHED_Doc()
{
Info = rInfo,
Value = "test",
Id = r.Id,
Date = r.Date,
};
session.Store(r_Doc);
session.SaveChanges();
}
session.SaveChanges();
i += result.Count;
}
public class PATCHED_Doc
{
public string Info { get; set; }
public string Value { get; set; }
public int Id { get; set; }
public string Date { get; set; }
}
Thank you in advance for helping.
You need to Parse the JSON into an object and then hand it over to Raven DB. Strings are treated as strings. Use JSON.NET library to parse it into Anonymous objects. Change your Info property to type of object. Then Assign the anonymous object to the Info property.

Deserialise JSON and access content using Linq to JSon

I have the following JSON stored in a cookie that I wish to parse:
{"package":[{"id":"5054","nodeId":"3286"},{"id":"8888","nodeId":"7777"}], "hotel":[{"id":"3421","nodeId":"1234"},{"id":"8748","nodeId":"2435"}], "activity":[{"id":"5054","nodeId":"3286"},{"id":"8888","nodeId":"7777"},{"id":"2131","nodeId":"2342"}]}
I understand from the accepted answer on this question Deserializing JSON to .NET object using Newtonsoft (or LINQ to JSON maybe?) that you can use the following code to access individual objects within JSON notation:
JToken token = JObject.Parse(stringFullOfJson);
int page = (int)token.SelectToken("page");
int totalPages = (int)token.SelectToken("total_pages");
I've therefore adapted this into my code as follows:
HttpCookie cookie = Request.Cookies.Get("wishlist");
string JSONstring = string.Empty;
string nodeId = string.Empty;
if (cookie != null)
{
JSONstring = cookie.Value;
JToken token = JObject.Parse(JSONstring);
}
I now wish to only retreive the package array for example and loop through each of the items in this array and output the ids in the following format:
5054,8888
From the example code I sort of came up with the following approach but i'm not sure if i'm proceeding in the right direction.
JObject obj = JObject.Parse(JSONstring);
JArray packages = (JArray)obj["package"];
What is the best way of specifying one of the arrays eg. hotel, package , looping through their contents and outputting each of the id nodes that are found? The nodeId will always be numeric but the id could be a string or an int so this adds another layer of complication.
Any help would be greatly appreciated and I apologise if this is a sumwhat stupid or easy question however I have jsut started working with .Net and OO so some of the concepts are still a bit foggy.
Here's How I would Do This, I'd Create the classes required to Deserialize the JSON :-
public class JSONCookie
{
public Package[] package { get; set; }
public Hotel[] hotel { get; set; }
public Activity[] activity { get; set; }
}
public class Package
{
public string id { get; set; }
public string nodeId { get; set; }
}
public class Hotel
{
public string id { get; set; }
public string nodeId { get; set; }
}
public class Activity
{
public string id { get; set; }
public string nodeId { get; set; }
}
Now, I would Create a method that actually does the deserialising :-
public JSONCookie GetJSONCookieResponse()
{
try
{
// Add your own code that gets the Response Here.
// string response = "{"package":[{"id":"5054","nodeId":"3286"},{"id":"8888","nodeId":"7777"}], "hotel":[{"id":"3421","nodeId":"1234"},{"id":"8748","nodeId":"2435"}], "activity":[{"id":"5054","nodeId":"3286"},{"id":"8888","nodeId":"7777"},{"id":"2131","nodeId":"2342"}]}";
//return new JsonSerializer().Deserialize<JSONCookie>(new JsonTextReader(new StringReader(response)));
}
catch
{
return null;
}
}
From the JSONCookie Object that is returned, you can then use LINQ to pick out what you need like follows :-
x.package.Select(p=>p.id);
After a lot of trawling Google, this is the easiest solution I have come up with:
HttpCookie cookie = Request.Cookies.Get("wishlist");
string JSONstring = string.Empty;
string nodeId = string.Empty;
string test = string.Empty;
if (cookie != null)
{
JSONstring = cookie.Value;
JObject obj = JObject.Parse(JSONstring);
JArray packages = (JArray)obj["package"];
foreach (var item in packages.Children()){
var properties = item.Children<JProperty>();
var idElement = properties.FirstOrDefault(x => x.Name == "id");
var myElementValue = idElement.Value;
test = test + myElementValue + ",";
}
}
This will output all ids in the packages array in a CSV format (with a trailing ,)

C# Parsing JSON array of objects

I have an array of objects like this in json format:
{"results":[{"SwiftCode":"","City":"","BankName":"Deutsche Bank","Bankkey":"10020030","Bankcountry":"DE"},{"SwiftCode":"","City":"10891 Berlin","BankName":"Commerzbank Berlin (West)","Bankkey":"10040000","Bankcountry":"DE"}]}
What I want to get is a object[] in C#, where one object contains all the data what is in one json object. The thing is, I can NOT make a class with the properties of this object like here:
public class Result
{
public int SwiftCode { get; set; }
public string City { get; set; }
// .
// .
public string Bankcountry { get; set; }
}
Because I get everytime different results back, but I know it's always an array of objects. Someone knows how I could manage to get an array of objects back?
EDIT
I have to pass this object to powershell via WriteObject(results). So the ouput should only be the object IN the array.
Though this is an old question, I thought I'd post my answer anyway, if that helps someone in future
JArray array = JArray.Parse(jsonString);
foreach (JObject obj in array.Children<JObject>())
{
foreach (JProperty singleProp in obj.Properties())
{
string name = singleProp.Name;
string value = singleProp.Value.ToString();
//Do something with name and value
//System.Windows.MessageBox.Show("name is "+name+" and value is "+value);
}
}
This solution uses Newtonsoft library, don't forget to include using Newtonsoft.Json.Linq;
Use newtonsoft like so:
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json.Linq;
class Program
{
static void Main()
{
string json = "{'results':[{'SwiftCode':'','City':'','BankName':'Deutsche Bank','Bankkey':'10020030','Bankcountry':'DE'},{'SwiftCode':'','City':'10891 Berlin','BankName':'Commerzbank Berlin (West)','Bankkey':'10040000','Bankcountry':'DE'}]}";
var resultObjects = AllChildren(JObject.Parse(json))
.First(c => c.Type == JTokenType.Array && c.Path.Contains("results"))
.Children<JObject>();
foreach (JObject result in resultObjects) {
foreach (JProperty property in result.Properties()) {
// do something with the property belonging to result
}
}
}
// recursively yield all children of json
private static IEnumerable<JToken> AllChildren(JToken json)
{
foreach (var c in json.Children()) {
yield return c;
foreach (var cc in AllChildren(c)) {
yield return cc;
}
}
}
}
Use NewtonSoft JSON.Net library.
dynamic obj = Newtonsoft.Json.JsonConvert.DeserializeObject(jsonString);
Hope this helps.
I have just got an solution a little bit easier do get an list out of an JSON object. Hope this can help.
I got an JSON like this:
{"Accounts":"[{\"bank\":\"Itau\",\"account\":\"456\",\"agency\":\"0444\",\"digit\":\"5\"}]"}
And made some types like this
public class FinancialData
{
public string Accounts { get; set; } // this will store the JSON string
public List<Accounts> AccountsList { get; set; } // this will be the actually list.
}
public class Accounts
{
public string bank { get; set; }
public string account { get; set; }
public string agency { get; set; }
public string digit { get; set; }
}
and the "magic" part
Models.FinancialData financialData = (Models.FinancialData)JsonConvert.DeserializeObject(myJSON,typeof(Models.FinancialData));
var accounts = JsonConvert.DeserializeObject(financialData.Accounts) as JArray;
foreach (var account in accounts)
{
if (financialData.AccountsList == null)
{
financialData.AccountsList = new List<Models.Accounts>();
}
financialData.AccountsList.Add(JsonConvert.DeserializeObject<Models.Accounts>(account.ToString()));
}
Using .NET 6 you could use built in System.Text.Json.Nodes
Example:
string json = #"{""results"":[{""SwiftCode"":"""",""City"":"""",""BankName"":""Deutsche Bank"",""Bankkey"":""10020030"",""Bankcountry"":""DE""},{""SwiftCode"":"""",""City"":""10891 Berlin"",""BankName"":""Commerzbank Berlin (West)"",""Bankkey"":""10040000"",""Bankcountry"":""DE""}]}";
JsonObject obj = JsonNode.Parse(json).AsObject();
JsonArray jsonArray = (JsonArray)obj["results"];
I believe this is much simpler;
dynamic obj = JObject.Parse(jsonString);
string results = obj.results;
foreach(string result in result.Split('))
{
//Todo
}

Categories