To test a class I need some dummy objects which are realistic.
My question is that: While debugging can I get an already constructed object as string? I want to copy this string and paste(assign) it to the dummy object in the test class.
public class Employee
{
public string Name;
public int Age;
public List<string> NamesOfChildren;
}
For example for an instance of this class in debug mode I need some string like
new Employee() {Name = "Serdar", Age = 30, NamesOfChildren = new List() {"NameOfChild1", "NameOfChild2"}}
In other words in debug mode I can see all public and private fields and their values of an object. Can I take this data as string? I need it in the format of creating that object in the editor. (Of course only public fields)
I'm not sure about the private fields, but I believe the Json.NET can help you. You're going to have to add the object name, but I believe you can automate this easily.
You can install it using Nuget:
Install-Package Newtonsoft.Json
You can find more information at: http://james.newtonking.com/json
Here is a example their site has:
Product product = new Product();
product.Name = "Apple";
product.Expiry = new DateTime(2008, 12, 28);
product.Sizes = new string[] { "Small" };
string json = JsonConvert.SerializeObject(product);
//{
// "Name": "Apple",
// "Expiry": "2008-12-28T00:00:00",
// "Sizes": [
// "Small"
// ]
//}
The same idea goes for Deserializing the object:
string json = #"{
'Name': 'Bad Boys',
'ReleaseDate': '1995-4-7T00:00:00',
'Genres': [
'Action',
'Comedy'
]
}";
Movie m = JsonConvert.DeserializeObject<Movie>(json);
string name = m.Name;
// Bad Boys
Related
I've ObservableCollection<dynamic> called myJSON in C# having 4 items as follows:
[
{
"name": "A",
"location": "NY"
},
{
"name": "B",
"location": "NJ"
},
{
"name": "A",
"location": "NY"
},
{
"name": "D",
"location": "MA"
}
]
I need to be able to apply a filter query like say where name="A" and location="NY" and then get back 2 records from above.
I tried code like below but I was only able to parse one record at a time from the above collection. And also the 2nd line seems to error out with a message:
"Cannot access child value on Newtonsoft.Json.Linq.JValue."
JObject json = JObject.Parse(myJSON[0].ToString());
var match = json.Values<JProperty>().Where(m => m.Value["name"].ToString() == "A" && m.Value["location"].ToString() == "NY").FirstOrDefault();
Thanks.
Here:
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using Newtonsoft.Json;
namespace NameLoc
{
class Program
{
class NameLoc
{
public string Name;
public string Location;
}
static void Main(string[] args)
{
var lst = JsonConvert.DeserializeObject<ObservableCollection<NameLoc>>(File.ReadAllText("NameLoc.json"));
var selLst = from sel in lst where sel.Name == "A" && sel.Location == "NY" select sel;
foreach (var it in selLst)
{
Console.WriteLine($"{it.Name}, {it.Location}");
}
Console.WriteLine("Hello World!");
}
}
}
And then be sure to add a file "NameLoc.Json" Set build Action Copy To output I found errors in your json corrected below. Add Newtonsoft.json to pkgs
[
{
"name": "A",
"location": "NY"
},
{
"name": "B",
"location": "NJ"
},
{
"name": "A",
"location": "NY"
},
{
"name": "D",
"location": "MA"
}
]
First, let's fix json format. If you are talking about collection or array then your json format should be like this:
[
{
"name": "A",
"location": "NY"
},
{
"name": "B",
"location": "NJ"
},
{
"name": "A",
"location": "NY"
},
{
"name": "D",
"location": "MA"
}
]
And you should use JArray instead of JObject to parse it so that you can apply filter.
JArray jsonArray = JArray.Parse(jsonString);
var match = jsonArray.Where(i => i["name"].ToString() == "A" && i["location"].ToString() == "NY").ToList();
You do know that your json array is incorrect, don't you? An array is within square brackets [ ... ]. I assume that is a typing error.
My advice would be to separate your concerns: split your problem into separate parts:
I have a string in JSON format containing information about Persons (?), and I need to convert this into a sequence of Persons
I have a sequence of Persons, I need only those Persons with a certain Name and Location.
If you do this, your code will be easier to understand, more reusable, easier to test and easier to change. Who does not want that?
Convert string to a sequence of Persons
For this I write an extension function. This way it looks more like LINQ. See extension methods demystified
public class Person
{
public string Name {get; set;}
public string Location {get; set;}
... // other properties
}
// Converts a JToken to a Person:
public static Person ToPerson(this JToken token)
{
// TODO: decide what to do if token == null. Return null?
Person person = token.ToObject<Person>();
return person;
}
// Converts JSON string to sequence of Persons
public static IEnumerable<Person> ToPersons(this string jsonText)
{
// TODO: exception if jsonText null, or incorrect
IEnumerable<JToken> jsonArray = JArray.Parse(jsonString);
foreach (JToken token in jsonArray)
{
Person person = token.ToPerson();
yield return person;
}
}
Usage looks like LINQ ToList():
string jsonText = ...
IEnumerable<Person> persons = jsonText.ToPersons();
Keep only Persons with certain name and location
After you've converted the json to a sequence of Persons, the rest is standard LINQ
const int name = "John Doe";
const int location = "New York City";
string jsonText = ...
var result = jsonText.ToPersons()
.Where(person => person.Name == name && person.Location == location);
Advantages of this separation of concerns
This Separation has several advantages:
You can reuse ToPersons() for other LINQ statements: "give me all elderly Persons", "give me the cities where my Persons live".
It is easier to test: just create an array of test persons as a source for your LINQ statements
It is easier to understand: people who read your LINQ statements don't have to bother anymore about the conversion: they know the conversion is used already in a lot of other places, and the test software succeeds, hence you can trust the conversion.
It is easier to change: if you want to add a PostCode to your Persons, go ahead, your LINQ statements won't change, only ToPerson()
I am trying to print values from a Json string in a gridview with C# using Visual Studio 2017. The problem is that I can't get the specific Value to a single word.
Here is my code:
string link = #"http://alexander.*************/test.php";
string json = new WebClient().DownloadString(link);
JObject jObject = JObject.Parse(json);
I want to print both Values from "Name" in the gridview, but how?
The Names has to put in this Item list:
myItems = (array?);
string test2 = test1.ToString(Formatting.Indented);
ArrayAdapter<string> adapter = new ArrayAdapter<string>(this, Android.Resource.Layout.SimpleListItem1, myItems);
GridviewCoins.Adapter = adapter;
And finally the json string is:
{
"Coins": [[{
"Name": "007",
"Id": "5294",
}], [{
"Name": "1337",
"Id": "20824",
}
There is a couple problems here, first is that your Coins Property is an array of arrays, and that you jsonObject is not complete it should look like :
"{ "Coins": [[{ "Name": "007", "Id": "5294", } ], [{ "Name": "1337", "Id": "20824", }]]}";
That said if this is a copy paste error I would do some thing like:
public IEnumerable<Coin> GetCoins(string json)
{
var jObject = JObject.Parse(json);
var coinPropery = jObject["Coins"] as JArray;
var coins = new List<Coin>();
foreach (var property in coinPropery)
{
var propertyList = JsonConvert.DeserializeObject<List<Coin>>(property.ToString());
coins.AddRange(propertyList);
}
return coins;
}
and the coin object:
public class Coin
{
public int Id { get; set; }
public string Name { get; set; }
}
when then you have a c# object and you can do what ever you want with it.
EDIT:
You can add to gridview by following Click here
How can I create a JsonArray with a child data object array? I am using Web service and C#.
I want the result of the JsonArray to look like the following:
[{
"name": "Deadpool",
"url": {
"small": "http://api.android.info/images/small/deadpool.jpg",
"medium": "http://api.android.info/images/medium/deadpool.jpg",
"large": "http://api.android.info/images/large/deadpool.jpg"
},
"time": "February 12, 2016"
},
{
"name": "The Jungle Book",
"url": {
"small": "http://api.android.info/images/small/book.jpg",
"medium": "http://api.android.info/images/medium/book.jpg",
"large": "http://api.android.info/images/large/book.jpg"
},
"time": "April 15, 2016"
},
{
"name": "X-Men: Apocalypse",
"url": {
"small": "http://api.android.info/images/small/xmen.jpg",
"medium": "http://api.android.info/images/medium/xmen.jpg",
"large": "http://api.android.info/images/large/xmen.jpg"
},
"time": "May 27, 2016"
}]
First, create the models that can output the given data. You need a MovieModel, a movie can have multiple image sizes and urls stored, we use a dictionary for this.
UPDATED
MovieModel.cs
public class MovieModel
{
public string Name { get; set; }
public Dictionary<string,string> Url { get; set; }
public string Time { get; set; }
}
Now you need to install Newtonsoft.Json from Nuget packages. Then import it.
using Newtonsoft.Json;
Initialize the model and convert to Json using SerializeObject() method.
var movieList = new List<MovieModel>
{
new MovieModel
{
MovieName = "Deadpool",
Time = DateTime.UtcNow.ToString("t"),
Url = new Dictionary<string, string>
{
{ "small", "http://api.android.info/images/small/deadpool.jpg" },
{ "medium", "http://api.android.info/images/medium/deadpool.jpg" }
}
}
// .. add more movies .. //
};
// convert to camelcase and set indentation
var output = JsonConvert.SerializeObject(
movieList,
Formatting.Indented,
new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver()
}
);
// testing output on console
Console.WriteLine(output);
In a real application, you would create Movie instances by getting data from a database, not initializing it for yourself as used in this example.
From a web service method I am returning an object of type 'GridBindingDataSet'. But its not getting serialized as JSON automatically.
Is there some way of making sure that the object gets serialized as JSON? I am using AJAX enabled web service that can be called from client-side using jQuery.
public class GridBindingDataSet
{
public int TotalCount { get; set; }
public DataTable Data { get; set; }
}
EDIT 1:
I am getting the following error when the web service method is called from jQuery:
A circular reference was detected while serializing an object of type 'System.Reflection.RuntimeModule'
EDIT 2:
I used JSON.net to serialize the above object of GridBindingDataSet. The web service is now returning a string rather than a GridBindingObject. Code for this is as below. But the browser cannot understand d.TotalCount and d.Data even though they are there in JSON returned.
[WebMethod]
public string GetJSONDataSetForGrid()
{
...
...
DataTable dt = GetDataForPage0();
int total = GetTotalCount();
GridBindingDataSet gridBindingData = new GridBindingDataSet ( total, dt);
//return a JSON serialized string
return JsonConvert.SerializeObject(gridBindingData,
Formatting.None, new JsonSerializerSettings
{
PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.None
});
}
But the JSON being returned is full of back slashes which the browser is not interpreting since the grid using the JSON string is showing up as empty. d.Data and d.TotalCount are not being parsed from the JSON string.
JSON retuned is as below:
{"d":"{\"TotalCount\":81,\"Data\":[{\"ProductName\":\"Alice Mutton\",\"UnitPrice\":39.00,
\"UnitsInStock\":0,\"Discontinued\":true},{\"ProductName\":\"Aniseed Syrup\",\"UnitPrice\":10.00,
\"UnitsInStock\":13,\"Discontinued\":false}]}"}
Also its worth having a look at Json.Net, many would say one of the best Json serializers available, I use it for all of my projects.
In response to the circular referece have a look at preserving references in the documentation, from their examples:
Directory root = new Directory { Name = "Root" };
Directory documents = new Directory { Name = "My Documents", Parent = root };
File file = new File { Name = "ImportantLegalDocument.docx", Parent = documents };
documents.Files = new List<File> { file };
string preserveReferenacesObjects = JsonConvert.SerializeObject(documents, Formatting.Indented, new JsonSerializerSettings
{
PreserveReferencesHandling = PreserveReferencesHandling.Objects
});
// {
// "$id": "1",
// "Name": "My Documents",
// "Parent": {
// "$id": "2",
// "Name": "Root",
// "Parent": null,
// "Files": null
// },
// "Files": [
// {
// "$id": "3",
// "Name": "ImportantLegalDocument.docx",
// "Parent": {
// "$ref": "1"
// }
// }
// ]
// }
I am building a server dashboard app. I want to take a list of disks from each server and create a list that displays the usage values for each.
Here's a JSON sample we're getting back...
{"server":"webster","disks":[ {"use": "91%", "used": "16G", "mount": "/", "free": "1.6G", "device": "/dev/mapper/vg_f12-lv_root", "total": "18G", "type": "ext4"} ,
{"use": "0%", "used": "0", "mount": "/dev/shm", "free": "500M", "device": "tmpfs", "total": "500M", "type": "tmpfs"} ,
{"use": "22%", "used": "40M", "mount": "/boot", "free": "145M", "device": "/dev/sda1", "total": "194M", "type": "ext4"} ,
{"use": "47%", "used": "52G", "mount": "/rsync", "free": "61G", "device": "/dev/sdb1", "total": "119G", "type": "ext3"} ]}
I get this far with the C# code:
WebClient c = new WebClient();
var data = c.DownloadString("http://192.0.0.40:8000/cgi-bin/df.py");
JObject o = JObject.Parse(data);
string serv = o["server"].Select(s => (string)s).ToString();
lblJson.Text = serv;
But I can't seem to extract "disks" into anything meaningful that I can plugin to a listview. I've tried pumping this into IList, but it always crashes or gives me some rude comments from Intellisense.
I do have a class built for this, but haven't figured out how to port the info into it. For reference, it's here:
public class drive
{
public string Usage;
public string usedSpace;
public string Mount;
public string freeSpace;
public string Device;
public string Total;
public string Type;
}
Note: The sources for JSON are Linux servers. Windows servers will supply data in a different format ultimately.
And then we have VMWare, but I'll flail on that later.
Thanks in advance.
var jsonObj = JsonConvert.DeserializeObject<RootObject>(json);
public class RootObject
{
[JsonProperty("server")]
public string Server;
[JsonProperty("disks")]
public List<Drive> Disks;
}
public class Drive
{
[JsonProperty("use")]
public string Usage;
[JsonProperty("used")]
public string usedSpace;
[JsonProperty("mount")]
public string Mount;
[JsonProperty("free")]
public string freeSpace;
[JsonProperty("device")]
public string Device;
[JsonProperty("total")]
public string Total;
[JsonProperty("type")]
public string Type;
}
There may be a better way to do this, but using the provided drive class, the following works to deserialize your provided JSON:
JObject o = JObject.Parse(data);
List<drive> drives = new List<drive>();
string server = (string)o["server"];
foreach (var d in o["disks"].Children())
{
drives.Add(new drive()
{
Usage = (string)d["use"],
usedSpace = (string)d["used"],
Mount = (string)d["mount"],
freeSpace = (string)d["free"],
Device = (string)d["device"],
Total = (string)d["total"],
Type = (string)d["type"]
});
}