I am trying to deserialize JSON file and want to assign to object ScanResult. var text showing all the values but scanresult showing null some null values. https://gyazo.com/ff2ce386f845394c458a88d43a1f30d8
please suggest if I am missing something.
//MY jSon File SCAN Test 1-1543045410222.json 's code
{
"at": 1543045410222,
"i": 1000,
"s": {
"Sensor1": ["OFF"],
"Sensor2": ["OFF"],
"DataReady1": ["OFF"],
"DataReady2": ["OFF"],
"CV1": [5.0],
"CV2": [6.0]
}
}
//ViewModel Code is as below:
public void ResendScanResult()
{
var ScanActivities = scanActivityManager.GetAll();
foreach (var item in ScanActivities)
{
var scanName = item.ScanName;
var dir = _dataFilePath + scanName + "\\";
var jsonFileName = string.Format("{0}{1}-{2}.json", dir, scanName, item.ScanDateEpoch);
string fileName = Path.GetFileName(jsonFileName);
// ScanResult scanResult = new ScanResult();
var text = File.ReadAllText(jsonFileName);
//var scanResults = JsonConvert.DeserializeObject<ScanResult>(text);
Common.Model.ScanResult scanResult = JsonConvert.DeserializeObject<Common.Model.ScanResult>(text);
var Mvm = MonitorViewModel.Instance;
// TargetProvider target = Mvm.GetTargetProvider(scanResult);
// Mvm.PublishToServer(target, scanResult);
}
}
and my scanRescult class code is as below :
namespace ABX.Common.Model
{
public class ScanResult
{
public ScanResult()
{
At = DateTimeOffset.Now.ToUnixTimeMilliseconds();
Interval = 1;
}
public string Name { get; set; }
public long At { get; set; }
public long Interval { get; set; }
public JObject Values { get; set; }
public string FileName { get; set; }
public JObject ToJson()
{
JObject json = new JObject
{
{ "at", At },
{ "i", Interval },
{ "s", Values }
};
return json;
}
Either rename your class properties to match your JSON, rename your JSON to match your class properties, or implement a custom JsonConverter, where you can implement arbitrary mapping.
Related
I have a settings.json file present in the Release folder of my application. What I want to do is change the value of it, not temporarily, permanently.. That means, deleting the old entry, writing a new one and saving it.
Here is the format of the JSON file
{
"Admins":["234567"],
"ApiKey":"Text",
"mainLog": "syslog.log",
"UseSeparateProcesses": "false",
"AutoStartAllBots": "true",
"Bots": [
{
"Username":"BOT USERNAME",
"Password":"BOT PASSWORD",
"DisplayName":"TestBot",
"Backpack":"",
"ChatResponse":"Hi there bro",
"logFile": "TestBot.log",
"BotControlClass": "Text",
"MaximumTradeTime":180,
"MaximumActionGap":30,
"DisplayNamePrefix":"[AutomatedBot] ",
"TradePollingInterval":800,
"LogLevel":"Success",
"AutoStart": "true"
}
]
}
Suppose I want to change the password value and instead of BOT PASSWORD I want it to be only password. How do I do that?
Here's a simple & cheap way to do it (assuming .NET 4.0 and up):
string json = File.ReadAllText("settings.json");
dynamic jsonObj = Newtonsoft.Json.JsonConvert.DeserializeObject(json);
jsonObj["Bots"][0]["Password"] = "new password";
string output = Newtonsoft.Json.JsonConvert.SerializeObject(jsonObj, Newtonsoft.Json.Formatting.Indented);
File.WriteAllText("settings.json", output);
The use of dynamic lets you index right into json objects and arrays very simply. However, you do lose out on compile-time checking. For quick-and-dirty it's really nice but for production code you'd probably want the fully fleshed-out classes as per #gitesh.tyagi's solution.
Use the JObject class in Newtonsoft.Json.Linq to modify JSON values without knowing the JSON structure ahead of time:
using Newtonsoft.Json.Linq;
string jsonString = File.ReadAllText("myfile.json");
// Convert the JSON string to a JObject:
JObject jObject = Newtonsoft.Json.JsonConvert.DeserializeObject(jsonString) as JObject;
// Select a nested property using a single string:
JToken jToken = jObject.SelectToken("Bots[0].Password");
// Update the value of the property:
jToken.Replace("myNewPassword123");
// Convert the JObject back to a string:
string updatedJsonString = jObject.ToString();
File.WriteAllText("myfile.json", updatedJsonString);
Example:
// This is the JSON string from the question
string jsonString = "{\"Admins\":[\"234567\"],\"ApiKey\":\"Text\",\"mainLog\":\"syslog.log\",\"UseSeparateProcesses\":\"false\",\"AutoStartAllBots\":\"true\",\"Bots\":[{\"Username\":\"BOT USERNAME\",\"Password\":\"BOT PASSWORD\",\"DisplayName\":\"TestBot\",\"Backpack\":\"\",\"ChatResponse\":\"Hi there bro\",\"logFile\":\"TestBot.log\",\"BotControlClass\":\"Text\",\"MaximumTradeTime\":180,\"MaximumActionGap\":30,\"DisplayNamePrefix\":\"[AutomatedBot] \",\"TradePollingInterval\":800,\"LogLevel\":\"Success\",\"AutoStart\":\"true\"}]}";
JObject jObject = Newtonsoft.Json.JsonConvert.DeserializeObject(jsonString) as JObject;
// Update a string value:
JToken jToken = jObject.SelectToken("Bots[0].Password");
jToken.Replace("myNewPassword123");
// Update an integer value:
JToken jToken2 = jObject.SelectToken("Bots[0].TradePollingInterval");
jToken2.Replace(555);
// Update a boolean value:
JToken jToken3 = jObject.SelectToken("Bots[0].AutoStart");
jToken3.Replace(false);
// Get an indented/formatted string:
string updatedJsonString = jObject.ToString();
//Output:
//{
// "Admins": [
// "234567"
// ],
// "ApiKey": "Text",
// "mainLog": "syslog.log",
// "UseSeparateProcesses": "false",
// "AutoStartAllBots": "true",
// "Bots": [
// {
// "Username": "BOT USERNAME",
// "Password": "password",
// "DisplayName": "TestBot",
// "Backpack": "",
// "ChatResponse": "Hi there bro",
// "logFile": "TestBot.log",
// "BotControlClass": "Text",
// "MaximumTradeTime": 180,
// "MaximumActionGap": 30,
// "DisplayNamePrefix": "[AutomatedBot] ",
// "TradePollingInterval": 555,
// "LogLevel": "Success",
// "AutoStart": false
// }
// ]
//}
You must have classes to instantiate json values to :
public class Bot
{
public string Username { get; set; }
public string Password { get; set; }
public string DisplayName { get; set; }
public string Backpack { get; set; }
public string ChatResponse { get; set; }
public string logFile { get; set; }
public string BotControlClass { get; set; }
public int MaximumTradeTime { get; set; }
public int MaximumActionGap { get; set; }
public string DisplayNamePrefix { get; set; }
public int TradePollingInterval { get; set; }
public string LogLevel { get; set; }
public string AutoStart { get; set; }
}
public class RootObject
{
public List<string> Admins { get; set; }
public string ApiKey { get; set; }
public string mainLog { get; set; }
public string UseSeparateProcesses { get; set; }
public string AutoStartAllBots { get; set; }
public List<Bot> Bots { get; set; }
}
Answer to your Ques(Untested code) :
//Read file to string
string json = File.ReadAllText("PATH TO settings.json");
//Deserialize from file to object:
var rootObject = new RootObject();
JsonConvert.PopulateObject(json, rootObject);
//Change Value
rootObject.Bots[0].Password = "password";
// serialize JSON directly to a file again
using (StreamWriter file = File.CreateText(#"PATH TO settings.json"))
{
JsonSerializer serializer = new JsonSerializer();
serializer.Serialize(file, rootObject);
}
I am trying to parse manually a string in json. This is how my json look like
{{
"dbViews": [
{
"viewID": 0,
"viewColumns": [
{
"dbTitle": "ColNmid",
"viewTitle": "string",
"activated": true,
"activatedLabel": "Afficher"
},
{
"dbTitle": "ColNmdelete",
"viewTitle": "string",
"activated": true,
"activatedLabel": "Afficher"
}
]
}
],
"AddViewName": "test"
}}
This is how i am trying to read it.
UserViewDto User = new UserViewDto();
dynamic obj = JObject.Parse(json);
User.id = obj.dbViews.viewID;
User.viewName = obj.AddViewName;
foreach (var item in obj.viewColumns)
{
if (obj.dbTitle == "ColNmid")
{
User.ColNmid = obj.viewTitle;
}
}
I can only read addViewName, i can't seem to access viewID or viewColumn.
Update:
after the comments I obviously miss the second array. Here my new code witch work
UserViewDto User = new UserViewDto();
dynamic obj = JObject.Parse(json);
User.viewName = obj.AddViewName;
foreach (var view in obj.dbViews)
{
User.id = view.viewID;
foreach (var item in view.viewColumns)
{
if (item.dbTitle == "ColNmid")
{
User.ColNmid = item.viewTitle;
}
}
}
Your json in question is invalid (extra { and } at start and end). It seems that you are using Newtonsoft's Json.NET library. Usual approach is to create model corresponding to your json structure and deserialize it:
public class Root
{
[JsonProperty("dbViews")]
public List<DbView> DbViews { get; set; }
[JsonProperty("AddViewName")]
public string AddViewName { get; set; }
}
public class DbView
{
[JsonProperty("viewID")]
public long ViewId { get; set; }
[JsonProperty("viewColumns")]
public List<ViewColumn> ViewColumns { get; set; }
}
public class ViewColumn
{
[JsonProperty("dbTitle")]
public string DbTitle { get; set; }
[JsonProperty("viewTitle")]
public string ViewTitle { get; set; }
[JsonProperty("activated")]
public bool Activated { get; set; }
[JsonProperty("activatedLabel")]
public string ActivatedLabel { get; set; }
}
var result = JsonConvert.DeserializeObject<Root>();
You don't need to include all properties in your class, you can include only needed ones.
If you don't want to create custom models and want to loop through the JObject properties in your case you can do it for example like that:
var jObj = JObject.Parse(json);
foreach(var view in jObj["dbViews"]) // dbViews is an array
{
Console.WriteLine(view["viewID"]);
foreach (var viewColumn in view["viewColumns"]) // viewColumns is an array
{
Console.WriteLine(viewColumn["dbTitle"]);
}
}
I have this JSON string called assignee:
{
"id": 15247055788906,
"gid": "15247055788906",
"name": "Bo Sundahl",
"resource_type": "user"
}
I want to get the "name" element and its value if it's not null. I have tried
var jobject = JsonConvert.DeserializeObject<JObject>(assignee);
And
var jo = JObject.Parse(assignee);
I tried looping through it but I just get null exception or empty output even though if I just print the assignee variable itself its filled with data.
My loop is like:
foreach (var result in jobject["name"])
{
Debug.WriteLine(result);
}
The simplest and best way is to deserialise to a C# class, for example:
public class Data
{
public long Id { get; set; }
public string Name { get; set; }
//etc..
}
And deserialise like this
var data = JsonConvert.DeserializeObject<Data>(json);
var name = data.Name;
To get name use this
string name = jobject["name"];
Using ["name"] returns a JToken, it is null if the property doesn't exist
JToken token = jo["name"];
Debug.WriteLine(token?.ToString() ?? "<default value>");
If you don't know properties beforehand, you can loop through JObject properties and get name value pairs as following:
var jsonObject = JObject.Parse(str);
foreach (var item in jsonObject)
{
var name = item.Key;
JToken token = item.Value;
if (token is JValue)
{
var value = token.Value<string>();
}
}
Here is how it should work:
class Data
{
public long? Id { get; set; }
public string Gid { get; set; }
public string Name { get; set; }
public string Resource_Type { get; set; }
}
class Program
{
static void Main(string[] args)
{
string assignee = "{\"id\": 15247055788906, \"gid\": \"15247055788906\", \"name\": \"Bo Sundahl\", \"resource_type\": \"user\"}";
Data data = JsonConvert.DeserializeObject<Data>(assignee);
Console.WriteLine(data.Id);
Console.WriteLine(data.Gid);
Console.WriteLine(data.Name);
Console.WriteLine(data.Resource_Type);
Console.ReadLine();
}
}
I have a JSON file saved locally that is being opened and read from successfully, but every time I try to parse it it fails. I've checked the JSON online but I can't find fault with it.
{
"Groups": [
{
"UniqueId": "233619708",
"Title": "Partno",
"Customer": "Customer",
"Items": []
}
]
}
I'm using a modified version of the JSON reader included in a sample source in VS, which looks like this:
private async Task GetSampleDataAsync()
{
if (this._groups.Count != 0)
return;
StorageFile file = await Windows.Storage.KnownFolders.PicturesLibrary.GetFileAsync("DB.json");
string jsonText = await FileIO.ReadTextAsync(file);
if (jsonText == "") {
await new Windows.UI.Popups.MessageDialog("File Blank!").ShowAsync();
}
JsonObject jsonObject;
if(JsonObject.TryParse(jsonText, out jsonObject))
{ await new Windows.UI.Popups.MessageDialog("File Read Error! Json Couldn't Parse!").ShowAsync();
throw new FormatException(jsonText);
}
if(jsonObject.Count == 0)
{
return;
}
JsonArray jsonArray = jsonObject["Groups"].GetArray();
foreach (JsonValue groupValue in jsonArray)
{
JsonObject groupObject = groupValue.GetObject();
Part group = new Part(groupObject["UniqueId"].GetString(),
groupObject["Title"].GetString(),
groupObject["Customer"].GetString(),
groupObject["Description"].GetString());
foreach (JsonValue itemValue in groupObject["Items"].GetArray())
{
JsonObject itemObject = itemValue.GetObject();
group.Items.Add(new Box(itemObject["UniqueId"].GetString(),
Convert.ToInt16( itemObject["Qty"].GetNumber()),
itemObject["Location"].GetString(),
group.UniqueId));
}
this.Groups.Add(group);
}
}
Any ideas anyone? Every time JsonObject.TryParse runs it returns false, and JsonObject.Parse returns a KeyMissingException.
Thanks.
(btw, I know there's nothing in the items part, I've tried both with and without...)
Have you tried using the other Json conversion method?
JsonConvert.DeserializeObject(jsonText);
I remember from having to grab data from bitcoin API's that when one method didn't work as expected it was worth trying the other one.
I think it had something to do with JObject.Parse being for JSON Objects and JsonConvert.Deserialize being for JSON arrays.
EDIT:
This will parse and deserialize the JSON you provided.
public class MyJsonObject
{
public string UniqueId { get; set; }
public string Title { get; set; }
public string Customer { get; set; }
public string Description { get; set; }
public List<JsonObjectItem> Items { get; set; }
}
public class JsonObjectItem
{
public string UniqueId { get; set; }
public string Qty { get; set; }
public string Location { get; set; }
}
public void ParseJson(string jsonText)
{
JObject jsonObject = JObject.Parse(jsonText);
if(jsonObject != null)
{
JToken token = null;
if(jsonObject.TryGetValue("Groups", out token))
{
foreach (var partData in token.Children())
{
if (!partData.HasValues)
continue;
MyJsonObject obj = partData.ToObject<MyJsonObject>();
Part group = new Part(obj.UniqueId, obj.Title, obj.Customer, obj.Description);
if(obj.Items.Count > 0)
{
foreach (var item in obj.Items)
{
short qty;
if(!Int16.TryParse(item.Qty, out qty))
{
// Decide what to do if is error with parsing qty.
}
group.Items.Add(new Box(item.UniqueId, qty, item.Location, obj.UniqueId));
}
}
}
}
}
}
HOWEVER - Depending upon the exact make up of your 'Part' class, you may even be able to simplify this even further and change:
MyJsonObject obj = partData.ToObject<MyJsonObject>();
to:
Part group = partData.ToObject<Part>();
and that should populate the properties and list of items in one go.
Hope that is helpful
How can I deserialize:
{
"data": [
{"ForecastID":8587961,"StatusForecast":"Done"},
{"ForecastID":8588095,"StatusForecast":"Done"},
{"ForecastID":8588136,"StatusForecast":"Done"},
{"ForecastID":8588142,"StatusForecast":"Pending"}
]
}
to
class RawData
{
public string data { get; set; }
}
So, I just want to have
[
{"ForecastID":8587961,"StatusForecast":"Done"},
{"ForecastID":8588095,"StatusForecast":"Done"},
{"ForecastID":8588136,"StatusForecast":"Done"},
{"ForecastID":8588142,"StatusForecast":"Pending"}
]
as value of property data of RawData's class instance.
Using Json.Net
var obj = (JObject)JsonConvert.DeserializeObject(json);
var newJson = obj["data"].ToString();
or using built-in JavaScriptSerializer
var dict = new JavaScriptSerializer().Deserialize<Dictionary<string, object>>(json);
var newjson = new JavaScriptSerializer().Serialize(dict["data"]);
It would have made far much more sense to deserialize this JSON structure to:
public class Forecast
{
public IEnumerable<ForecastData> Data { get; set; }
}
public class ForecastData
{
public int ForecastID { get; set; }
public string StatusForecast { get; set; }
}
which is pretty trivial with the JavaScriptSerializer class that's built into the framework:
string json = "your JSON data here";
IEnumerable<ForecastData> data = new JavaScriptSerializer()
.Deserialize<Forecast>(json)
.Data;
or if you don't want to define models you could do that:
dynamic result = new JavaScriptSerializer().DeserializeObject(json);
foreach (var item in result["data"])
{
Console.WriteLine("{0}: {1}", item["ForecastID"], item["StatusForecast"]);
}