Creating a JSON string, if the left-hand varaible has dashes in - c#

I am trying to create a json string to send via a httprequest, I have json string like so:
{
"a-string": "123",
"another-string": "hello",
"another": "1"
}
My problem is, if I try and generate it like so
string json = new JavaScriptSerializer().Serialize(new
{
"a-string" = "123",
"another-string" = "hello",
"another" = "1"
});
Leads to:
So what is a way of trying to do the above, without getting that error?

Use Json NewtonSoft NuGet package. Then use my answer here to create a C# class for you json. Since your json has names in them which are not allowed as property names in C#, you can use the JsonPropety attribute so it can use it during serialization. Here is all of the code:
public class Rootobject
{
[JsonProperty("a-string")]
public string astring { get; set; }
[JsonProperty("another-string")]
public string anotherstring { get; set; }
public string another { get; set; }
}
public class Program
{
public static void Main()
{
var root = new Rootobject { another = "1", anotherstring = "hello", astring = "123" };
string json = JsonConvert.SerializeObject(root);
Console.Read();
}
}

Related

Compare JSON array and JSON object: Cannot convert Array to String error

I am trying to compare json value and based on that i want to update the existing value,for example, currently we have "value" : [r0] in json, i want to compare and if value : [r0] ,then update it to [r0,r1] but iam hiting error that it cannot compare and there is a cast issue, could someone suggest what could be done
public void updateJsonParameter(string file)
{
try
{
var list = new List<string> { "joe", "test" };
JArray array = new JArray(list);
var jobject = JObject.Parse(file);
var ringvalue = (string)jobject["properties"]["parameters"]["ringValue"]["value"]; // unable to case here and compare
jobject["properties"]["parameters"]["ringValue"]["value"] = array; // able to update value but i want to update after comparing the existing values
var result = JsonConvert.SerializeObject(jobject);
}
following is the json format
{
"properties": {
"displayName": "jayatestdefid",
"description": "test assignment through API",
"metadata": {
"assignedBy": "xyz#gmail.com"
},
"policyDefinitionId": "/providers/Microsoft.Management/managementgroups/MGTest/providers/Microsoft.Authorization/policyDefinitions/test",
"parameters": {
"ringValue": {
"value": ["r0"]
}
},
"enforcementMode": "DoNotEnforce",
}
}
jobject.properties.parameters.ringValue.value is an array ["r0"] with one element "r0". If you want to check if it's an array with one element and that element is "r0", do exactly that:
var ringvalue = jobject["properties"]["parameters"]["ringValue"]["value"];
if(ringvalue.length == 1 && ringvalue[0] == "r0")
jobject["properties"]["parameters"]["ringValue"]["value"] = array;
You could compare the ringvalue (which is an JArray) using JArray.DeepEquals and then replace if the comparison returns true. For example,
var list = new List<string> { "joe", "test" };
JArray array = new JArray(list);
JArray valueToCompare = new JArray(new[]{"r0"});
var ringvalue = (JArray)jobject["properties"]["parameters"]["ringValue"]["value"];
if(JArray.DeepEquals(ringvalue,valueToCompare))
{
jobject["properties"]["parameters"]["ringValue"]["value"] = array;
}
First, as Klaycon said in his answer, it's worth noting that your "value" is not a single string. In json, whenever you see [ and ] then you have a collection, or an array, or a list.
When I work with json strings, I always like to be able to convert them into a strongly typed object. There is a very handy online tool I use all the time: http://json2csharp.com/
I took your json string that you provided and pasted it into that website. Here is that your object(s) look like when converted into c# classes:
public class RootObject // You can name this whatever you want
{
public Properties properties { get; set; }
}
public class Metadata
{
public string assignedBy { get; set; }
}
public class RingValue
{
public List<string> value { get; set; }
}
public class Parameters
{
public RingValue ringValue { get; set; }
}
public class Properties
{
public string displayName { get; set; }
public string description { get; set; }
public Metadata metadata { get; set; }
public string policyDefinitionId { get; set; }
public Parameters parameters { get; set; }
public string enforcementMode { get; set; }
}
Now, we can easily do the logic you need as follows:
// This is your json string, escaped and turned into a single string:
string file = "{ \"properties\": { \"displayName\": \"jayatestdefid\", \"description\": \"test assignment through API\", \"metadata\": { \"assignedBy\": \"xyz#gmail.com\" }, \"policyDefinitionId\": \"/providers/Microsoft.Management/managementgroups/MGTest/providers/Microsoft.Authorization/policyDefinitions/test\", \"parameters\": { \"ringValue\": { \"value\": [\"r0\"] } }, \"enforcementMode\": \"DoNotEnforce\", }}";
// Convert your json string into an instance of the RootObject class
RootObject jobject = JsonConvert.DeserializeObject<RootObject>(file);
// Get a list of all the "values"
List<string> values = jobject.properties.parameters.ringValue.value;
// Loop over your colleciton of "value" and do your logic
for (int i = 0; i < values.Count; ++i)
{
if (values[i] == "r0")
{
values[i] = "r0,r1";
}
}
// And finally, turn your object back into a json string
var result = JsonConvert.SerializeObject(jobject);
And this is the final result:
{
"properties":{
"displayName":"jayatestdefid",
"description":"test assignment through API",
"metadata":{
"assignedBy":"xyz#gmail.com"
},
"policyDefinitionId":"/providers/Microsoft.Management/managementgroups/MGTest/providers/Microsoft.Authorization/policyDefinitions/test",
"parameters":{
"ringValue":{
"value":[
"r0,r1"
]
}
},
"enforcementMode":"DoNotEnforce"
}
}

How to extract those values from the JSON string

I have this JSON string but are not sure how I will parse out the values that are inside:
has
has2
I do succeed to parse out the "id" correctly but are not sure how to access:
CORS
CORS2
CORS3
CORS4
I get the error:
'Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.String[]' because the type requires a JSON array (e.g. [1,2,3])
I have pasted the JSON in the pastebin:
https://pastebin.com/iWgGV9VK
The code I have:
public void getInfo()
{
String JSONstring = "{ id: 'hello', name: 'Hello',has:{ CORS: false,CORS2: true},has2:{ CORS3: false,CORS4: true}}";
String id = ""; List<String> has = new List<String>(); List<String> has2 = new List<String>();
var deserializedTicker = JsonConvert.DeserializeObject<JsonInfo>(JSONstring);
id = deserializedTicker.id;
has = deserializedTicker.has.ToList();
has2 = deserializedTicker.has.ToList();
}
public class JsonInfo
{
public String id { get; set; }
public String[] has { get; set; }
public String[] has2 { get; set; }
}
I am trying with the dynamic approach using an object but gets an error here also:
''Newtonsoft.Json.Linq.JValue' does not contain a definition for 'id''
//responseBody holds the JSON string
dynamic stuff = JsonConvert.DeserializeObject(responseBody);
foreach (var info in stuff)
{
dynamic id = info.Value.id; //''Newtonsoft.Json.Linq.JValue' does not contain a definition for 'id''
dynamic has = info.Value.has;
dynamic has2 = info.Value.has2;
if (has != null && has2 != null)
{
dynamic cors = has.CORS;
if(cors != null)
{
MessageBox.Show(cors.ToString());
}
}
}
First off, let's correct your JSON:
{
"id": "hello",
"name": "Hello",
"has": {
"CORS": false,
"CORS2": true
},
"has2": {
"CORS3": false,
"CORS4": true
}
}
Now, the problem you are experiencing is because you are attempting to deserialize the value in "has" and "has2" as arrays. In the JSON, they are not arrays; they are objects. As such, you need to define new classes with the same properties so the JSON can be properly deserialized:
public class JsonInfo
{
public string id { get; set; }
public string name { get; set; }
public JsonHasInfo has { get; set; }
public JsonHas2Info has2 { get; set; }
}
public class JsonHasInfo
{
public bool CORS { get; set; }
public bool CORS2 { get; set; }
}
public class JsonHas2Info
{
public bool CORS3 { get; set; }
public bool CORS4 { get; set; }
}
Now you should be able to deserialize the (correct) JSON properly:
String JSONstring = "{ \"id\": \"hello\", \"name\": \"Hello\", \"has\": { \"CORS\": false, \"CORS2\": true }, \"has2\": { \"CORS3\": false, \"CORS4\": true } }\";"
var deserializedTicker = JsonConvert.DeserializeObject<JsonInfo>(JSONstring);
You json was incorrect, the key has contains a dict no list.
You need change your deserialize to dictionary or change your json.
Here you can see an example:
https://json-schema.org/understanding-json-schema/reference/array.html#array
In your JSON, has is an object, not an array. You should model your class to support an object containing the attributes CORS, CORS2, and so on, and so forth.
Edit: If you want to stick to has being an array, you should change your JSON to match what an array expects, which could be like: has: [ false, true ], and omit the CORS thing.

Create JSON object from string in C#

I am trying to create a JSON string which contains one container and one array.
I can do this by using a stringbuilder but I am trying to find a better way to get the JSON string; I want:
{ "message":{ "text":"test sms"},"endpoints":["+9101234"]}
I tried this:
string json = new JavaScriptSerializer().Serialize(new
{
text = "test sms",
endpoints = "[dsdsd]"
});
And the output is:
{"text":"test sms","endpoints":"[dsdsd]"}
Any help or suggestions how to get the required format?
In the most recent version of .NET we have the System.Text.Json namespace, making third party libraries unecessary to deal with json.
using System.Text.Json;
And use the JsonSerializer class to serialize:
var data = GetData();
var json = JsonSerializer.Serialize(data);
and deserialize:
public class Person
{
public string Name { get; set; }
}
...
var person = JsonSerializer.Deserialize<Person>("{\"Name\": \"John\"}");
Other versions of .NET platform there are different ways like the JavaScriptSerializer where the simplest way to do this is using anonymous types, for sample:
string json = new JavaScriptSerializer().Serialize(new
{
message = new { text = "test sms" },
endpoints = new [] {"dsdsd", "abc", "123"}
});
Alternatively, you can define a class to hold these values and serialize an object of this class into a json string. For sample, define the classes:
public class SmsDto
{
public MessageDto message { get; set; }
public List<string> endpoints { get; set; }
}
public class MessageDto
{
public string text { get; set; }
}
And use it:
var sms = new SmsDto()
{
message = new MessageDto() { text = "test sms" } ,
endpoints = new List<string>() { "dsdsd", "abc", "123" }
}
string json = new JavaScriptSerializer().Serialize(sms);

c# Converting json string with list of objects to a c# object

I'm tring to convert a string json to c# object,
I've already read several replies in here regarding to similar questions but none of the solutions worked.
This is the json obj
{
"Customer": {
"data_0": {
"id": "273714",
"FirstName": "Zuzana",
"LastName": "Martinkova"
},
"data_1": {
"id": "274581",
"FirstName": "Ricardo",
"LastName": "Lambrechts"
},
"data_2": {
"id": "275190",
"FirstName": "Daniel",
"LastName": "Mojapelo"
},
"data_3": {
"id": "278031",
"FirstName": "Sulochana",
"LastName": "Chandran"
}
}
}
I created the following objects according to the json obj
public class Customer
{
public List<Data> Customers{ get; set; }
public Customer()
{
Customers = new List<Data>();
}
}
public class Data
{
public string id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
As for my code I made a small console app example with all the solotions I found here
static void Main(string[] args)
{
try
{
string jsonString = File.ReadAllText(ConfigurationSettings.AppSettings["filepath"].ToString());
//solution 1
JObject jsonone = JObject.Parse(jsonString);
var collection_one = jsonone.ToObject<Customer>();
//solution 2
JavaScriptSerializer serializer = new JavaScriptSerializer();
var collection_two = serializer.Deserialize<Customer>(jsonString);
//solution 2
var collection_three = JsonConvert.DeserializeObject<Customer> (jsonString);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message); ;
}
Console.ReadKey();
}
Ths json string I get from a 3rd party webservice so just for the example I'm reading the json from a txt file,
the jsonString param value after reading is:
"{\"Customer\":{\"data_0\":{\"id\":\"273714\",\"FirstName\":\"Zuzana\",\"LastName\":\"Martinkova\"},\"data_1\":{\"id\":\"274581\",\"FirstName\":\"Ricardo\",\"LastName\":\"Lambrechts\"},\"data_2\":{\"id\":\"275190\",\"FirstName\":\"Daniel\",\"LastName\":\"Mojapelo\"},\"data_3\":{\"id\":\"278031\",\"FirstName\":\"Sulochana\",\"LastName\":\"Chandran\"}}}"
On every solution I make the collections count is 0, data objects are not including inside the list.
Can someone put some light on it and tell me what is wrong?
Thanks in advance
Your JSON is a Dictionary<string, Data>, not a List<Data>. In addition to that your property is called "Customer", not "Customers". To solve this you need to change a couple things:
public class Customer
{
//JsonProperty is Used to serialize as a different property then your property name
[JsonProperty(PropertyName = "Customer")]
public Dictionary<string, Data> CustomerDictionary { get; set; }
}
public class Data
{
public string Id { get; set; } //You should make this "Id" not "id"
public string FirstName { get; set; }
public string LastName { get; set; }
}
With these class definitions you can easily use the JsonConvert.DeserializeObject() and JsonConvert.SerializeObject() methods:
Customer customer = JsonConvert.DeserializeObject<Customer>(json);
string newJson = JsonConvert.SerializeObject(customer);
I made a fiddle here to demonstrate.
You can try this one.
Add empty class
public class Customer : Dictionary<string, Data>{} //empty class
And the update your existing code
//solution 1
JObject jsonone = JObject.Parse(jsonString);
//Add this line
var token = jsonone.SelectToken("Customer").ToString();
//solution 2 - update jsonString to token variable created above.
var collection_three = JsonConvert.DeserializeObject<Customer>(token);

JSON cannot get data

Hi I'm trying to parse a JSON page in C#, but I can't seem to read some strings, like:
"versions": [
{
"date": 1340466559,
"dl_link": "http://dev.bukkit.org/media/files/599/534/NoSwear.jar",
"filename": "NoSwear.jar",
"game_builds": [
"CB 1.2.5-R4.0"
],
"hard_dependencies": [],
"md5": "d0ce03e817ede87a9f76f7dfa67a64cb",
"name": "NoSwear v5.1",
"soft_dependencies": [],
"status": "Semi-normal",
"type": "Release"
},
How could I read that?
This is the code I have right now and works for everything else except this:
public static void GetMoreInfo(string plugin)
{
try
{
string url = "http://bukget.org/api/plugin/";
var wc = new WebClient();
var json = wc.DownloadString(url + plugin);
var moreInfo = JsonConvert.DeserializeObject<MoreInfo>(json);
foreach (var category in moreInfo.categories)
{
Categories += category + ", ";
}
Categories = Categories.Remove(Categories.Length - 2, 2);
}
catch (Exception)
{
}
finally
{
if (string.IsNullOrEmpty(Categories))
{
Categories = "No data found.";
}
}
}
public class MoreInfo
{
public string[] categories;
}
How about handling your json dynamically, instead of deserializing to a concrete class?
var wc = new WebClient();
var json = wc.DownloadString("http://bukget.org/api/plugin/test");
dynamic moreInfo = JsonConvert.DeserializeObject(json);
Console.WriteLine("{0} {1} {2}", moreInfo.name, moreInfo.desc, moreInfo.status);
string categories = String.Join(",", moreInfo.categories);
Console.WriteLine(categories);
Or would you prefer the classical approach?
var plugin = JsonConvert.DeserializeObject<Plugin>(json);
string categories = String.Join(",",plugin.categories);
public class Plugin
{
public List<string> authors;
public string bukkitdev_link;
public List<string> categories;
public string desc;
public string name;
public string plugin_name;
public string status;
public List<Version> versions;
}
public class Version
{
public string date;
public string filename;
public string name;
//.......
}
I could be wrong, but the JSON you're receiving is an array named versions but you're trying to deserialize it into a MoreInfo object that exposes an array named categories (unless it's just a typo in your example). Have you tried renaming MoreInfo.categories to MoreInfo.versions?
UPDATE
I don't think that would make a difference because the JSON converter doesn't know what to do with each object in the array. You need to provide an object to deserialize each element in the JSON array.
For example, try modifying the MoreInfo object to include matching properties to the JSON string (the elements in the array)
[DataContract]
public class MoreInfo
{
[DataMember]
public DateTime date { get; set; }
[DataMember]
public string dl_link { get; set; }
...
}
And then try to deserialize the JSON string to a List<MoreInfo>:
JsonConverter.DeserializeObject<List<MoreInfo>>(json)
You will then have to modify the rest of your code to work with MoreInfo objects and not strings in an array.
REFER TO THIS ANSWER
See this question, the accepted answer should help you solve your problem: Json.NET: Deserialization with list of objects

Categories

Resources