How can I convert a generic JObject to camelCase plain json string?
I've tried with JsonSerializerSettings but doesn't work (Newtonsoft.Json 4.5.11)
[Test]
public void should_convert_to_camel_case()
{
var serializer = JsonSerializer.Create(new JsonSerializerSettings()
{
ContractResolver = new CamelCasePropertyNamesContractResolver()
});
var jo = new JObject();
jo["CamelCase"] = 1;
var stringWriter = new StringWriter();
var writer = new JsonTextWriter(stringWriter);
serializer.Serialize(writer,jo);
var serialized = stringWriter.ToString();
Assert.AreEqual("{\"camelCase\":1}", serialized);
}
UPDATE
According to http://json.codeplex.com/workitem/23853 that cannot be done (tnx to #nick_w for the link)
This question starts from a JObject and wants to work to a camel-cased JSON object. If you are actually starting from an object and want to get to a JObject that is already camelcased, then you can do this:
var serializer = new JsonSerializer()
{
ContractResolver = new CamelCasePropertyNamesContractResolver()
};
var jo = JObject.FromObject(someDataContract, serializer);
The resulting 'jo' will be camelcased.
According to this Json.NET issue, when serializing a JObject this way the contract resolver is ignored:
When serializing a JObject the contract resolvers seems to be ignored. Surely this is not how it is supposed to be?
Closed Jan 30, 2013 at 8:50 AM by JamesNK
That does make sense but it is too big a breaking change I'm afraid.
Inspired by the workaround on that page, you could do something like this:
var jo = new JObject();
jo["CamelCase"] = 1;
string json = JsonConvert.SerializeObject(jo);
var jObject = JsonConvert.DeserializeObject<ExpandoObject>(json);
var settings = new JsonSerializerSettings()
{
ContractResolver = new CamelCasePropertyNamesContractResolver()
};
var serialized = JsonConvert.SerializeObject(jObject, settings);
Assert.AreEqual("{\"camelCase\":1}", serialized);
Edit:
Good point about the Dictionary<string, object>. So doing it this way skips the additional JsonConvert.SerializeObject, but it also mitigates the need for the ExpandoObject, which is important if you are using .NET 3.5.
Dictionary<string, object> jo = new Dictionary<string, object>();
jo.Add("CamelCase", 1);
var settings = new JsonSerializerSettings()
{
ContractResolver = new CamelCasePropertyNamesContractResolver()
};
var serialized = JsonConvert.SerializeObject(jo, settings);
Assert.AreEqual("{\"camelCase\":1}", serialized);
As of this May 8th, 2013 blog post by James Newton-King regarding the 5.0 release of Json.NET, this has been addressed with the addition of "DefaultSettings". The example from that page follows but read the page for details for 3rd party libraries.
// settings will automatically be used by JsonConvert.SerializeObject/DeserializeObject
JsonConvert.DefaultSettings = () => new JsonSerializerSettings
{
Formatting = Formatting.Indented,
ContractResolver = new CamelCasePropertyNamesContractResolver()
};
Employee e = new Employee
{
FirstName = "Eric",
LastName = "Example",
BirthDate = new DateTime(1980, 4, 20, 0, 0, 0, DateTimeKind.Utc),
Department = "IT",
JobTitle = "Web Dude"
};
string json = JsonConvert.SerializeObject(e);
// {
// "firstName": "Eric",
// "lastName": "Example",
// "birthDate": "1980-04-20T00:00:00Z",
// "department": "IT",
// "jobTitle": "Web Dude"
// }
public static JsonSerializer FormattingData()
{
var jsonSerializersettings = new JsonSerializer {
ContractResolver = new CamelCasePropertyNamesContractResolver() };
return jsonSerializersettings;
}
public static JObject CamelCaseData(JObject jObject)
{
var expandoConverter = new ExpandoObjectConverter();
dynamic camelCaseData =
JsonConvert.DeserializeObject(jObject.ToString(),
expandoConverter);
return JObject.FromObject(camelCaseData, FormattingData());
}
Related
I have to use an API that expects a string containing a an array of json objects.
internal string InitConnect( string RequestData )
{
try
{
dynamic filejsonJarray = new JArray();
filejsonJarray = JArray.Parse(RequestData);
JObject jsonObject = (JObject)filejsonJarray.First;
if (jsonObject.ContainsKey("IP_ADDRESS".ToUpper()))
{
...
}
}
}
In my code I tried different ways of calling this API but don't seem to be able to get the argument right. I have to create an object (connData) using data I have read from a config file (sJSONConfig) and use it as an argument to API; last thing I tried:
string sJSONConfig = Global.ReadJsonConfig();
// returns"{\r\n \"Name\": \"BLAH\",\r\n \"IPAddress\": \"1.2.3.4\",\r\n \"Port\": \"5880\"\r\n}"
JArray filejsonJarray = new JArray();
JObject jsonObject = new JObject();
jsonObject = JObject.Parse(sSJONConfig);
//filejsonJarray = JArray.Parse(sSJONConfig);
//jsonObject = (JObject)filejsonJarray.First;
// Reconnect using new config data
var connData = new
{
NAME = jsonObject.Property("Name").Value.ToString(),
IP_ADDRESS = jsonObject.Property("IPAddress").Value.ToString(),
PORT = jsonObject.Property("Port").Value.ToString(),
Enabled = "true",
Something = "false"
};
string reqData = JsonConvert.SerializeObject(filejsonJarray);
//filejsonJarray.Add(reqData);
InitConnect(reqData);
Obviously, I cannot changed the InitConnect API.
You can create your desired JSON like this:
string sJSONConfig = Global.ReadJsonConfig();
JObject jsonObject = JObject.Parse(sJSONConfig);
JObject connData = new JObject(
new JProperty("NAME", jsonObject["Name"]),
new JProperty("IP_ADDRESS", jsonObject["IPAddress"]),
new JProperty("PORT", jsonObject["Port"]),
new JProperty("Enabled", "true"),
new JProperty("Something", "false")
);
JArray filejsonJarray = new JArray(connData);
string reqData = filejsonJarray.ToString();
InitConnect(reqData);
I am trying to parse a json and populate these values into an object with DataContractJsonSerializer. Having no luck with this yet.
The json is -
{
"0": [
547,
541,
507,
548,
519,
0
],
"1": [
573,
504
]
}
I have tried the following code:
try
{
string json = #"""0"":[547,541,507,548,519,0],""1"":[573,504]";
using (var memStream = new MemoryStream(Encoding.UTF8.GetBytes(json)))
{
var seraializer = new DataContractSerializer(typeof(MyClass));
var jsonParsed = seraializer.ReadObject(memStream);
}
}
catch(Exception ex)
{
}
Always getting an exception that the data is invalid at the root. But online json validators say this is a valid json.
MyClass -
[DataContract]
public class MyClass
{
[DataMember]
public Dictionary<string, List<int>> values { get; set; }
}
Thanks Patrick for providing me a working solution with Newtonsoft. But just to learn , I want to see what am I doing wrong with DataContractJsonSerializer. The code below gives me no exception, but I am not getting any values after the parsing is complete.
string json = #"{""0"":[547,541,507,548,519,0],""1"":[573,504]}";
using (var memStream = new MemoryStream(Encoding.UTF8.GetBytes(json)))
{
var seraializer = new DataContractJsonSerializer(typeof(Dictionary<string, List<int>>));
var jsonParsed = seraializer.ReadObject(memStream);
}
You should use Dictionary<string, List<int>> as the type to deserialize to. You also need to use the right serializer (DataContractSerializer is for XML, DataContractJsonSerializer for JSON):
var seraializer = new DataContractJsonSerializer(typeof(Dictionary<string, List<int>>), new DataContractJsonSerializerSettings() { UseSimpleDictionaryFormat = true });
var jsonParsed = seraializer.ReadObject(memStream);
Or for JSON.NET:
var x = JsonConvert.DeserializeObject<Dictionary<string, List<int>>>(json);
maybe someone know the solution. I can't deserialize expression.
Client side:
var expresion= (Expression<Func<Company, bool>>)(model => model.Id ==id);
var respond = new JObject();
respond .Add("Expression", JToken.FromObject(expresion));
Server side:
JsonSerializer serializer = new JsonSerializer();
serializer.ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor;
T p = (T)serializer.Deserialize(new JTokenReader(jObject), typeof(T));
Exception:
{"Unable to find a constructor to use for type System.Linq.Expressions.Expression`1[System.Func`2[HostStorageModels.Company,System.Boolean]]. A class should either have a default constructor, one constructor with arguments or a constructor marked with the JsonConstructor attribute. Path 'Expression.Type'."}
I think that it is explicitly telling you that there is no constructor to build the Expression. If you check Expression Constructor () in the MSDN documentation, you will see that it is protected. You could try to send the expression in other serializable format and re build it when you receive it at the other side.
https://github.com/6bee/Remote.Linq
var query = (Expression<Func<Person, bool>>)(model => model.FirstName == "test2");
var remoteExpression = query.ToRemoteLinqExpression();
var request = new Request<Person>
{
Items = new List<Person>()
{
new Person() { FirstName = "test", Id = 1 },
new Person() { FirstName = "test2", Id = 2 }
},
Expression = remoteExpression
};
var serializerSettings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto };
string jsonString = JsonConvert.SerializeObject(request, serializerSettings);
var result = JsonConvert.DeserializeObject<Request<Person>>(jsonString, serializerSettings);
var expresion = result.Expression.ToLinqExpression<Person, bool>();
var filtered = request.Items.Where(expresion.Compile()).ToList();
For some of my unit tests I want the ability to build up particular JSON values (record albums in this case) that can be used as input for the system under test.
I have the following code:
var jsonObject = new JObject();
jsonObject.Add("Date", DateTime.Now);
jsonObject.Add("Album", "Me Against The World");
jsonObject.Add("Year", 1995);
jsonObject.Add("Artist", "2Pac");
This works fine, but I have never really like the "magic string" syntax and would prefer something closer to the expando-property syntax in JavaScript like this:
jsonObject.Date = DateTime.Now;
jsonObject.Album = "Me Against The World";
jsonObject.Year = 1995;
jsonObject.Artist = "2Pac";
Well, how about:
dynamic jsonObject = new JObject();
jsonObject.Date = DateTime.Now;
jsonObject.Album = "Me Against the world";
jsonObject.Year = 1995;
jsonObject.Artist = "2Pac";
You can use the JObject.Parse operation and simply supply single quote delimited JSON text.
JObject o = JObject.Parse(#"{
'CPU': 'Intel',
'Drives': [
'DVD read/writer',
'500 gigabyte hard drive'
]
}");
This has the nice benefit of actually being JSON and so it reads as JSON.
Or you have test data that is dynamic you can use JObject.FromObject operation and supply a inline object.
JObject o = JObject.FromObject(new
{
channel = new
{
title = "James Newton-King",
link = "http://james.newtonking.com",
description = "James Newton-King's blog.",
item =
from p in posts
orderby p.Title
select new
{
title = p.Title,
description = p.Description,
link = p.Link,
category = p.Categories
}
}
});
Json.net documentation for serialization
Neither dynamic, nor JObject.FromObject solution works when you have JSON properties that are not valid C# variable names e.g. "#odata.etag". I prefer the indexer initializer syntax in my test cases:
JObject jsonObject = new JObject
{
["Date"] = DateTime.Now,
["Album"] = "Me Against The World",
["Year"] = 1995,
["Artist"] = "2Pac"
};
Having separate set of enclosing symbols for initializing JObject and for adding properties to it makes the index initializers more readable than classic object initializers, especially in case of compound JSON objects as below:
JObject jsonObject = new JObject
{
["Date"] = DateTime.Now,
["Album"] = "Me Against The World",
["Year"] = 1995,
["Artist"] = new JObject
{
["Name"] = "2Pac",
["Age"] = 28
}
};
With object initializer syntax, the above initialization would be:
JObject jsonObject = new JObject
{
{ "Date", DateTime.Now },
{ "Album", "Me Against The World" },
{ "Year", 1995 },
{ "Artist", new JObject
{
{ "Name", "2Pac" },
{ "Age", 28 }
}
}
};
There are some environment where you cannot use dynamic (e.g. Xamarin.iOS) or cases in where you just look for an alternative to the previous valid answers.
In these cases you can do:
using Newtonsoft.Json.Linq;
JObject jsonObject =
new JObject(
new JProperty("Date", DateTime.Now),
new JProperty("Album", "Me Against The World"),
new JProperty("Year", "James 2Pac-King's blog."),
new JProperty("Artist", "2Pac")
)
More documentation here:
http://www.newtonsoft.com/json/help/html/CreatingLINQtoJSON.htm
Sooner or later you will have property with a special character. e.g. Create-Date. The hyphen won't be allowed in property name. This will break your code. In such scenario, You can either use index or combination of index and property.
dynamic jsonObject = new JObject();
jsonObject["Create-Date"] = DateTime.Now; //<-Index use
jsonObject.Album = "Me Against the world"; //<- Property use
jsonObject["Create-Year"] = 1995; //<-Index use
jsonObject.Artist = "2Pac"; //<-Property use
Simple way of creating newtonsoft JObject from Properties.
This is a Sample User Properties
public class User
{
public string Name;
public string MobileNo;
public string Address;
}
and i want this property in newtonsoft JObject is:
JObject obj = JObject.FromObject(new User()
{
Name = "Manjunath",
MobileNo = "9876543210",
Address = "Mumbai, Maharashtra, India",
});
Output will be like this:
{"Name":"Manjunath","MobileNo":"9876543210","Address":"Mumbai, Maharashtra, India"}
You could use the nameof expression combined with a model for the structure you're trying to build.
Example:
record RecordAlbum(string Album, string Artist, int Year);
var jsonObject = new JObject
{
{ nameof(RecordAlbum.Album), "Me Against The World" },
{ nameof(RecordAlbum.Artist), "2Pac" },
{ nameof(RecordAlbum.Year), 1995 }
};
As an added benefit to removing the "magic string" aspect - this also will give you a little bit of refactor-ability. You can easily rename any given property name for the record and it should update the value returned by the nameof() expression.
You can use Newtonsoft library and use it as follows
using Newtonsoft.Json;
public class jb
{
public DateTime Date { set; get; }
public string Artist { set; get; }
public int Year { set; get; }
public string album { set; get; }
}
var jsonObject = new jb();
jsonObject.Date = DateTime.Now;
jsonObject.Album = "Me Against The World";
jsonObject.Year = 1995;
jsonObject.Artist = "2Pac";
System.Web.Script.Serialization.JavaScriptSerializer oSerializer =
new System.Web.Script.Serialization.JavaScriptSerializer();
string sJSON = oSerializer.Serialize(jsonObject );
I need to create a Json object dynamically by looping through columns.
so declaring an empty json object then add elements to it dynamically.
eg:
List<String> columns = new List<String>{"FirstName","LastName"};
var jsonObj = new {};
for(Int32 i=0;i<columns.Count();i++)
jsonObj[col[i]]="Json" + i;
And the final json object should be like this:
jsonObj={FirstName="Json0", LastName="Json1"};
[TestFixture]
public class DynamicJson
{
[Test]
public void Test()
{
dynamic flexible = new ExpandoObject();
flexible.Int = 3;
flexible.String = "hi";
var dictionary = (IDictionary<string, object>)flexible;
dictionary.Add("Bool", false);
var serialized = JsonConvert.SerializeObject(dictionary); // {"Int":3,"String":"hi","Bool":false}
}
}
I found a solution very similar to DPeden, though there is no need to use the IDictionary, you can pass directly from an ExpandoObject to a JSON convert:
dynamic foo = new ExpandoObject();
foo.Bar = "something";
foo.Test = true;
string json = Newtonsoft.Json.JsonConvert.SerializeObject(foo);
and the output becomes:
{ "FirstName":"John", "LastName":"Doe", "Active":true }
You should use the JavaScriptSerializer. That can Serialize actual types for you into JSON :)
Reference: http://msdn.microsoft.com/en-us/library/system.web.script.serialization.javascriptserializer.aspx
EDIT: Something like this?
var columns = new Dictionary<string, string>
{
{ "FirstName", "Mathew"},
{ "Surname", "Thompson"},
{ "Gender", "Male"},
{ "SerializeMe", "GoOnThen"}
};
var jsSerializer = new JavaScriptSerializer();
var serialized = jsSerializer.Serialize(columns);
Output:
{"FirstName":"Mathew","Surname":"Thompson","Gender":"Male","SerializeMe":"GoOnThen"}
Using dynamic and JObject
dynamic product = new JObject();
product.ProductName = "Elbow Grease";
product.Enabled = true;
product.StockCount = 9000;
Console.WriteLine(product.ToString());
// {
// "ProductName": "Elbow Grease",
// "Enabled": true,
// "StockCount": 9000
// }
Or how about:
JObject obj = JObject.FromObject(new
{
ProductName = "Elbow Grease",
Enabled = true,
StockCount = 9000
});
Console.WriteLine(obj.ToString());
// {
// "ProductName": "Elbow Grease",
// "Enabled": true,
// "StockCount": 9000
// }
https://www.newtonsoft.com/json/help/html/CreateJsonDynamic.htm