Suppose I have the following:
var b = true;
var f = "{ \"templateName\": \"name\", \"Active\": \"" +b + "\"}";
That b value does not work for me :( , I tried different scenario's with no luck.
The proper way of doing this is to work with objects directly. Then you can serialize to whatever format you want (if you want JSON, JSON.NET is what you should use).
For instance, you should have a class that looks something like this:
public class TestClass
{
public bool Active { get; set; }
public string TemplateName { get; set; }
}
This is a class that represents your JSON object, but instead of modifying strings and dealing with that headache, we just deal with objects.
In your code you can instantiate and/or modify an instance of that object:
var testObj = new TestClass()
{
Active = true,
TemplateName = "SomeName"
};
//changed my mind, I want Active to be false now
testObj.Active = false;
Then with the power of JSON.NET you can serialize this object into JSON:
string jsonString = JsonConvert.SerializeObject(testObj);
Related
So I have a JSON string where I just want to read a specific value. How do I just pick "Read me please!" from string below?
var readString = /*Read me please!*/
JSON string:
"{\"aString\":\"Read me please!\"}"
For better understanding, how do I do the same here? (just "Read me please!"):
"{\"Result\":
{
\"aString\":\"Read me please!\",
\"anotherString\":\"Dont read me!\"
}
}"
If both alternative have different solution I would like to know both.
PS: I do not wish to save the value into object/class or so. Just temporary inside var readString.
You could write a model:
public class MyModel
{
public string AString { get; set; }
}
and then use a JSON serializer such as Json.NET:
string readString = "{\"aString\":\"Read me please!\"}";
MyModel model = JsonConvert.DeserializeObject<MyModel>(readString);
Console.WriteLine(model.AString);
If you don't want to use third party solutions you could use the built-in JavaScriptSerializer class:
string readString = "{\"aString\":\"Read me please!\"}";
MyModel model = new JavaScriptSerializer().Deserialize<MyModel>(readString);
Console.WriteLine(model.AString);
Now assuming you want to handle your second JSON string you could simply adapt your model:
public class Wrapper
{
public MyModel Result { get; set; }
}
public class MyModel
{
public string AString { get; set; }
public string AnotherString { get; set; }
}
and then deserialize to this wrapper class:
string readString = ... the JSON string in your second example ...;
Wrapper wrapper = JsonConvert.DeserializeObject<Wrapper>(readString);
Console.WriteLine(wrapper.Result.AString);
Console.WriteLine(wrapper.Result.AnotherString);
UPDATE:
And if you don't want to deserialize to a model you could directly do this:
string readString = "{\"aString\":\"Read me please!\"}";
var res = (JObject)JsonConvert.DeserializeObject(readString);
Console.WriteLine(res.Value<string>("aString"));
or with the built-in JavaScriptSerializer class:
string readString = "{\"aString\":\"Read me please!\"}";
var serializer = new JavaScriptSerializer();
var res = (IDictionary<string, object>)serializer.DeserializeObject(readString);
Console.WriteLine(res["aString"]);
var readString = JObject.Parse(str)["aString"];
Or for your second example:
var readString2 = JObject.Parse(str2)["Result"]["aString"];
Json.NET also provides a JSON reader if you don't want to deserialize the whole thing. For example:
string json = "{\"Result\": { \"aString\":\"Read me please!\", \"anotherString\":\"Dont read me!\" } }";
using (var reader = new JsonTextReader(new StringReader(json)))
{
while (reader.Read())
{
if (reader.TokenType == JsonToken.PropertyName && (string)reader.Value == "aString")
{
reader.Read();
Console.Write(reader.Value);
break;
}
}
}
Console.ReadKey();
You have to use Newtonsoft (JSON.NET) to accomplish that. Then, you can access your json property this way:
var obj = JsonConvert.DeserializeObject(yourJson);
Console.WriteLine(obj.Result.aString);
I played around with writing a generic method that can read any part of my json string. I tried a lot of the answers on this thread and it did not suit my need. So this is what I came up with. I use the following method in my service layer to read my configuration properties from the json string.
public T getValue<T>(string json,string jsonPropertyName)
{
var parsedResult= JObject.Parse(json);
return parsedResult.SelectToken(jsonPropertyName).ToObject<T>();
}
and this is how you would use it :
var result = service.getValue<List<string>>(json, "propertyName");
So you can use this to get specific properties within your json string and cast it to whatever you need it to be.
My Json is
{
Id: 1,
Name:'Alex',
ConnectedObjectName:'Obj',
ConnectedObjectId: 99
}
I want this JSON to be converted to the following object
Class Response
{
int Id,
string Name,
ConnectedObject Obj
}
Class ConnectedObject
{
string COName,
int COId
}
Is there a way to achieve this using DataContractJsonSerializer
Most serializers want the object and the data to share a layout - so most json serializers would want ConnectedObjectName and ConnectedObjectId to exist on the root object, not an inner object. Usually, if the data isn't a good "fit" for what you want to map it into, the best approach is to use a separate DTO model that matches the data and the serializer, then map from the DTO model to the actual model you want programatically, or using a tool like auto-mapper.
If you used the DTO approach, just about any JSON deserializer would be fine here. Json.NET is a good default. DataContractJsonSerializer would be way way down on my list of JSONserializers to consider.
To expand on what Marc Gravell has said, most JSON serializers would expect your JSON to look like the following, which would map correctly to your classes:
{
"Id": 1,
"Name": "Alex",
"Obj" : {
"COName": "Obj",
"COId": 99
}
}
The way to get around this would be to read your JSON into an object that matches it, and then map it form that object to the object that you want:
Deserialize to this object:
class COJson {
public int Id;
public string Name;
public string ConnectedObjectName;
public int ConnectedObjectId;
}
Then map to this object:
class Response {
public int Id;
public string Name;
public ConnectedObject Obj;
}
class ConnectedObject {
public string COName;
public string COId;
}
Like this:
using(var stream = new MemoryStream(Encoding.Unicode.GetBytes(json)))
{
var serializer = new DataContractJsonSerializer(typeof(COJson));
var jsonDto = (COJson)ser.ReadObject(stream);
var dto = new Response(){
Id = jsonDto.Id,
Name = jsonDto.Name,
Obj = new ConnectedObject(){
COName = jsonDto.ConnectedObjectName,
COId = jsonDto.ConnectedObjectId
}
};
return dto;
}
I'm new to the REST/JSON interface.
I'm working in VS 2013 C#, Framework is 4.5.
Right now I've successfully created items on a list in Sharepoint, using a JSON payload similar to this:
{ '__metadata': { 'type': 'SP.Data.ABCs_x0020_for_x0020_TAC_x0020_SiebelListItem' },
'Priority':'A',
'Requirements_x0020_Status':'Fully Documented',
'Status':'Under Consideration',
'Description':'This is a test',
'ABC_x0020_Type':'Enhancement',
'Title':'Testing: 921253434',
'Business_x0020_Unit_x0020_Affect':'TAC',
'AssignedToId':'1',
'Submitted_x0020_by':'sdsd',
'Applies_x0020_To':'Screens/Views',
'Screen_x002f_View_x002f_Module':'CSR'}
I was manually creating the JSON payload and decided to try out some objects that might help with the Serialization/Deserialization.
Here is the code:
ABCItem item = new ABCItem();
item.Title = "Testing " + ran.Next();
item.ABC_x0020_Type = "Enchancement";
item.Applies_x0020_To = "Screens/View";
item.Priority = "A";
item.Requirements_x0020_Status = "Fully Documented";
item.Screen_x002f_View_x002f_Module = "CSR";
item.Business_x0020_Unit_x0020_Affect = "TAC";
item.Submitted_x0020_by = "Brian Hintze";
item.Status = "Under Consideration";
item.AssignedToId = 1;
item.Description = "The quick brown fox jumped over the lazy dog and then drank a pint of beer.";
string json = JsonConvert.SerializeObject(item);
Unfortunately I can't figure out how to get the __metadata part of the JSON payload to get added correctly. I've tried this
item.__metadata = "{ 'type': 'SP.Data.ABCs_x0020_for_x0020_TAC_x0020_SiebelListItem' }";
But that didn't work.
I've tried fiddling around the MetaDataSettings, but so far I can't figure out the right combination.
string json = JsonConvert.SerializeObject(item,new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.All,
// $type no longer needs to be first
MetadataPropertyHandling = MetadataPropertyHandling.Default
});
Any help would be appreciated. I'm sure it is something fairly basic that I'm missing.
thanks,
lee
The JSON serializer will convert objects to JavaScript objects.
Instead of making item.__metadata a string value, try making it an object with a member property called Type that equals "SP.Data.ABCs_x0020_for_x0020_TAC_x0020_SiebelListItem".
You probably want to make the property __metadata be a reference to its own class. After all, this is a complex json object.
Using json2csharp.com 1 you can see that your ABCItem class should look like
public class Metadata
{
public string type { get; set; }
}
public class ABCItem
{
public Metadata __metadata { get; set; }
public string Priority { get; set; }
(...)
}
I am connecting you Google Places API to retrive results in the form of a JSON string. You can view the complete format of the string Here.
If you a look at it you will see that the actual results array starts after two elements which are html_attributions and next_page_token.
So When i try to deserialize it in this way:
var serializer = new JavaScriptSerializer();
var arr= serializer.Deserialize(result,typeof(string[]));
I get an empty array.
My question is how is there a way i can separate html_attributions and next_page_token fields and the pass the valid results array from the string to be deserialized?
I don't understand the part where you wish to seperate the html_attributions and the next_page_token.
Wouldn't it be sufficient to just deserialize the response with whatever properties that you need?
For example, you can deserialize the response to only retrieve the values that you desire;
// I represent the wrapper result
class Result
{
public List<string> html_attributions { get; set; }
public string next_page_token { get; set; }
public List<ResultItem> results { get; set; }
}
// I represent a result item
class ResultItem
{
public string id { get; set; }
public string name { get; set; }
}
// the actual deserialization
Result Deserialize(string json)
{
var serializer = new JavaScriptSerializer();
return serializer.Deserialize(json, typeof(Result));
}
Edit:
The reason that your deserialization doesn't return you a array of strings is because the response that you retrieve is infact an object and not an array, however the parameter within that object which is named results is an array. In order for you to deserialize more properties you'll have to define them in your "ResultItem" class, sorry for my poor naming here.
For instance, if you'd wish to also retrieve the icon property per result you'll have to add a property named "icon" of type string.
Meanwhile the property "photos" is an array, in order to deserialize it you'll have to create another class and add a property of type list/array of that newly created class, and it has to be named "photos" unless you use a different serializer or use DataContract and DataMember attributes (using the Name property for field mapping).
// the representation of a photo within a result item
class Photo
{
public int height { get; set; }
public List<string> html_attributions { get; set; }
public string photo_reference { get; set; }
public int width { get; set; }
}
// I represent a result item
class ResultItem
{
public string id { get; set; }
public string name { get; set; }
// the added icon
public string icon { get; set; }
// the added photos collection, could also be an array
public List<Photo> photos { get; set; }
}
Just look at the JSON result to figure out what other properties that you might want to add, for instance the "scope" property is an string whilst the "price_level" is an integer.
If I understand your comment correctly you're only interested in the actual results, you'll still have to deserialize the response correctly with its wrapper.
// the actual deserialization
List<ResultItem> Deserialize(string json)
{
var serializer = new JavaScriptSerializer();
var result = serializer.Deserialize(json, typeof(Result));
return result.results;
}
Edit2:
If you really want a string[] as a result you could simply take use of System.Linq using the code above.
string[] stringArray = result.results.Select(r => string.Format("id:{0} - name:{1}", r.id, r.name)).ToArray();
Edit3:
Instead of using the JavascriptSerializer you could use JObject functionality which can be found in the Newtonsoft.Json.Linq library.
var jsonObject = JObject.Parse(json);
string[] results = jsonObject.SelectTokens("results").Select(r => r.ToString()).ToArray();
This will give you an array of strings where each value within the array is the actual json string for each result.
If you however would like to query for the coordinates only:
var jsonObject = JObject.Parse(json);
var coordinates = jsonObject["results"]
.Select(x => x.SelectToken("geometry").SelectToken("location"))
.Select(x => string.Format("{0},{1}", (string)x.SelectToken("lat"), (string)x.SelectToken("lng")))
.ToArray();
This would give you an array of coordinates, eg:
[
"-33.867217,151.195939",
"-33.866786,151.195633",
...
]
Whatever approach you choose you'll be able to accomplish same results using either Newtonsoft or the .net serializer, whilst the Newtonsoft approach would allow you to query without creating strong types for deserialization.
I don't find the point of "[...] pass the valid results array from the string to be deserialized".
Maybe you need to switch to JSON.NET and do something like this:
// You simply deserialize the entire response to an ExpandoObject
// so you don't need a concrete type to deserialize the whole response...
dynamic responseEntity = JsonConvert.DeserializeObject<ExpandoObject>(
googlePlacesJson, new ExpandoObjectConverter()
);
// Now you can access result array as an `IEnumerable<dynamic>`...
IEnumerable<dynamic> results = responseEntity.results;
foreach(dynamic result in results)
{
// Do stuff for each result in the whole response...
}
I have to read a given JSON string into C# objects. So far so good but this case is kind of special to me. The JSON string contains 2 entities. One is a flat object and the second is a list, logical at least but not really in JSON. I hope you can help me finding a solution to this.
To explain it better i will show you a part of my JSON input:
{
"game":{"GameMode":"1","IsNetworkMode":"1","NbMaxPlayer":"12","GameState":"1"},
"player_56":{"PlayerUserId":"137187","PlayerIALevel":"-1","PlayerObserver":"0"},
"player_7":{"PlayerUserId":"3440","PlayerIALevel":"-1","PlayerObserver":"0"}
}
I want to serialize the Player entities into a collection of objects of this type. The Problem is that they arent really stored as a collection in JSON. They have dynamic names as "player_56" and the number is not in any logical order like "1,2,3".
At the moment I am using the DataContractJsonSerializer for this task.
[DataContract]
public class AlbReplay
{
[DataMember(Name = "game")]
public AlbGame Game { get; set; }
[DataMember(Name = "player")]
public List<AlbPlayer> Players { get; set; }
}
Any suggestions?
I don't know the extent of DataContractJsonSerializer, but there might be an interface you can implement on your class to define how to parse the JSON.
But if you're able to use JSON.Net:
public class Player
{
public int Id { get; set; }
public int PlayerUserId { get; set; }
public int PlayerIALevel { get; set; }
public int PlayerObserver { get; set; }
}
And then you can use Linq-To-JSON:
var data = #"{
""game"":{""GameMode"":""1"",""IsNetworkMode"":""1"",""NbMaxPlayer"":""12"",""GameState"":""1""},
""player_56"":{""PlayerUserId"":""137187"",""PlayerIALevel"":""-1"",""PlayerObserver"":""0""},
""player_7"":{""PlayerUserId"":""3440"",""PlayerIALevel"":""-1"",""PlayerObserver"":""0""}
}";
JObject o = JObject.Parse(data);
IEnumerable<Player> players =
o.Children()
.Where(p => ((JProperty)p).Name.StartsWith("player"))
.Select(p =>
new Player
{
Id = int.Parse(((JProperty)p).Name.Split('_')[1]),
PlayerUserId = int.Parse((string)p.Children<JObject>().First()["PlayerUserId"]),
PlayerIALevel = int.Parse((string)p.Children<JObject>().First()["PlayerIALevel"]),
PlayerObserver = int.Parse((string)p.Children<JObject>().First()["PlayerObserver"]),
});
Mangle your JSON into a collection of player objects.
player_8: {...}
player_99: {...}
to
players: [
{id: 8 ...},
{id: 99 ...}
]
How to mangle your JSON, a RegEx would likely be sufficient.
EDIT Here's code for the string mangling using Regex. A few assumptions were made: there are no objects embedded inside of the game and player objects and the player object list is the last part of the json string.
string json_test = #"{
""game"":{""GameMode"":""1"",""IsNetworkMode"":""1"",""NbMaxPlayer"":""12"",""GameState"":""1""},
""player_56"" : {""PlayerUserId"":""137187"",""PlayerIALevel"":""-1"",""PlayerObserver"":""0""},
""player_2"": {""PlayerUserId"":""137187"",""PlayerIALevel"":""-1"",""PlayerObserver"":""0""}
}";
json_test = new Regex(#"""player_(\d+)""\s*:\s*{").Replace(json_test, #"""player"" : {""Id"": $1,");
Console.WriteLine("player_##:{...} -> player:{id: ##,..}");
Console.WriteLine(json_test);
json_test = new Regex(#"""player""\s*:\s*{").Replace(json_test, #"""players"" : [{", 1);
json_test = new Regex(#"""player""\s*:\s*{").Replace(json_test, #"{");
json_test = new Regex(#"}$").Replace(json_test, #"]}");
Console.WriteLine("player:{...}, -> players: [{...},...]");
Console.WriteLine(json_test);
As with all considerations regarding speed, you'll have to test it out, having the Regex objects as static and reusable would be my first step if I had to optimize the above.