JSON with dynamic Root-Object - c#

problably I'm not experienced enought and my question is kind of dumb:
For learning purposes I'm trying to connect to a REST-Service, which delivers JSON-Data.
From what I've learned, the purpose of JSON is to deliver the same data to any possible client without having a State of itself.
My code is looking like this:
public static void DoSomething()
{
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("SomeUrl"));
// Add an Accept header for JSON format.
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
// List data response.
HttpResponseMessage response = client.GetAsync("").Result;
if (response.IsSuccessStatusCode)
{
Task<Stream> readTask = response.Content.ReadAsStreamAsync();
readTask.ContinueWith(task =>
{
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(RootObject));
using (Stream result = task.Result)
{
result.Position = 0;
RootObject obj = (RootObject)ser.ReadObject(result);
}
});
}
else
{
Console.WriteLine("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase);
}
}
public class Sum
{
public int id { get; set; }
public string name { get; set; }
public int profileIconId { get; set; }
public int summonerLevel { get; set; }
public long revisionDate { get; set; }
}
public class RootObject
{
public Sum khalgor { get; set; }
}
But here's my Problem: I've created this classes "Sum" and "RootObject" by using the Website http://json2csharp.com/, the JSON-String is looking like this:
{"khalgor":{"id":23801741,"name":"Khalgor","profileIconId":7,"summonerLevel":30,"revisionDate":1396876104000}}
The Problem: The Name "Khalgor" seems to be used as a Root-Object, but it's a Name. So if I'd like to user for another Name, I'd have to user another RootObject.
It does not make that much sense to create such a Structure, so my question: What's the best practice here? Do I map this RootObject/Property to another object manually? Do I use some Reflection to dynamically create an Property or rename it?
As usual, thanks a lot for all Responses
Matthias
Edit:
I tinkered arround a bit and that's my first idea of a solution:
public static class LOLObjectFactory
{
public static ILOLObject Create(string jsonString)
{
JavaScriptSerializer jss = new JavaScriptSerializer();
Dictionary<String, object> entry = (jss.Deserialize<dynamic>(jsonString) as Dictionary<string, object>).First().Value as Dictionary<String, object>;
Type selectedType = null;
List<string> fieldNames = entry.Select(f => f.Key).OrderBy(f => f).ToList();
Type[] types = typeof(ILOLObject).Assembly.GetTypes();
foreach(var type in types)
{
List<string> typeProperties = type.GetProperties().Select(f => f.Name).OrderBy(f => f).ToList();
if (fieldNames.SequenceEqual(typeProperties) && typeof(ILOLObject).IsAssignableFrom(type))
{
selectedType = type;
break;
}
}
ILOLObject result = System.Activator.CreateInstance(selectedType) as ILOLObject;
foreach(var prop in result.GetType().GetProperties())
{
prop.SetValue(result, entry.First(f => f.Key == prop.Name).Value);
}
return result;
}
}
So all the objects I have have the ILOLObject implemented. I'm sure it's not working for everything, but I guess that would be a good approach?
Edit2: Just by looking at it I see I'll have a lot of work to do, but I think the idea behind it is quite clear.

I think your best bet for json "fragments" is to deserialize into a dynamic object:
dynamic stuff = JsonConvert.DeserializeObject(inputData);
Then you can deserialize parts that make sense into proper .NET objects.
SomeObject o = JsonConvert.DeserializeObject<SomeObject>(stuff["someProperty"].ToString());

If you want to ignore the root altogether (e.g. it changes its name everytime) use Json.NET to parse it into an object and ignore the topmost element. Example:
JObject obj = JObject.Parse(json);
if (obj != null)
{
var root = obj.First;
if (root != null)
{
var sumJson = root.First;
if (sumJson != null)
{
var sum = sumJson.ToObject<Sum>();
}
}
}

Related

NewtonSoft json parsing

Can somebody help me to parse the json and get the details.
Lets say i have Top2 input parameter as Police and i want to know the respective Top3 and in that Top3 array i need to check whether Test1Child value is there or not.
I am using newtonsoft json + c# and so far i can get till DeviceTypes using below code
var json = File.ReadAllText(jsonFile); // below json is stored in file jsonFile
var jObject = JObject.Parse(json);
JArray MappingArray =(JArray)jObject["Top1"];
string strTop1 = ObjZone.Top1.ToString();
string strTop2 = ObjZone.Top2.ToString();
var JToken = MappingArray.Where(obj => obj["Top2"].Value<string>() == strTop2).ToList();
//Json
{
"Top1": [
{
"Top2": "Test1",
"Top3": [
"Test1Child"
]
},
{
"Top2": "Test2",
"Top3": [
"Test2Child"
]
}
]
}
I'd use http://json2csharp.com/ (or any other json to c# parser) and then use C# objects (it's just easier for me)
This would look like that for this case:
namespace jsonTests
{
public class DeviceTypeWithResponseTypeMapper
{
public string DeviceType { get; set; }
public List<string> ResponseTypes { get; set; }
}
public class RootObject
{
public List<DeviceTypeWithResponseTypeMapper> DeviceTypeWithResponseTypeMapper { get; set; }
}
}
and the use it like that in code:
var rootob = Newtonsoft.Json.JsonConvert.DeserializeObject<RootObject>(str);
var thoseThatHaveNotUsed = rootob.DeviceTypeWithResponseTypeMapper.Where(dtwrtm =>
dtwrtm.ResponseTypes.Any(rt => rt == "NotUsed"));
foreach (var one in thoseThatHaveNotUsed)
{
Console.WriteLine(one.DeviceType);
}
this code lists all the Device types that have "NotUsed" among the responses.
version 2 (extending your code) would look like that, i believe:
static void Main(string[] args)
{
var json = str; // below json is stored in file jsonFile
var jObject = JObject.Parse(json);
JArray ZoneMappingArray = (JArray)jObject["DeviceTypeWithResponseTypeMapper"];
string strDeviceType = "Police";
string strResponseType = "NotUsed";
var JToken = ZoneMappingArray.Where(obj => obj["DeviceType"].Value<string>() == strDeviceType).ToList();
var isrespTypeThere = JToken[0].Last().Values().Any(x => x.Value<string>() == strResponseType);
Console.WriteLine($"Does {strDeviceType} have response type with value {strResponseType}? {yesorno(isrespTypeThere)}");
}
private static object yesorno(bool isrespTypeThere)
{
if (isrespTypeThere)
{
return "yes!";
}
else
{
return "no :(";
}
}
result:
and if you'd like to list all devices that have response type equal to wanted you can use this code:
var allWithResponseType = ZoneMappingArray.Where(jt => jt.Last().Values().Any(x => x.Value<string>() == strResponseType));
foreach (var item in allWithResponseType)
{
Console.WriteLine(item["DeviceType"].Value<string>());
}

Serialise entire Page tree to JSON in EpiServer

I am completely new to EpiServer and this has been killing me for days :(
I am looking for a simple way to convert a page and all it's descendents to a JSON tree.
I have got this far:
public class MyPageController : PageController<MyPage>
{
public string Index(MyPage currentPage)
{
var output = new ExpandoObject();
var outputDict = output as IDictionary<string, object>;
var pageRouteHelper = ServiceLocator.Current.GetInstance<EPiServer.Web.Routing.PageRouteHelper>();
var pageReference = pageRouteHelper.PageLink;
var children = DataFactory.Instance.GetChildren(pageReference);
var toOutput = new { };
foreach (PageData page in children)
{
outputDict[page.PageName] = GetAllContentProperties(page, new Dictionary<string, object>());
}
return outputDict.ToJson();
}
public Dictionary<string, object> GetAllContentProperties(IContentData content, Dictionary<string, object> result)
{
foreach (var prop in content.Property)
{
if (prop.IsMetaData) continue;
if (prop.GetType().IsGenericType &&
prop.GetType().GetGenericTypeDefinition() == typeof(PropertyBlock<>))
{
var newStruct = new Dictionary<string, object>();
result.Add(prop.Name, newStruct);
GetAllContentProperties((IContentData)prop, newStruct);
continue;
}
if (prop.Value != null)
result.Add(prop.Name, prop.Value.ToString());
}
return result;
}
}
The problem is, by converting the page structure to Dictionaries, the JsonProperty PropertyName annotations in my pages are lost:
[ContentType(DisplayName = "MySubPage", GroupName = "MNRB", GUID = "dfa8fae6-c35d-4d42-b170-cae3489b9096", Description = "A sub page.")]
public class MySubPage : PageData
{
[Display(Order = 1, Name = "Prop 1")]
[CultureSpecific]
[JsonProperty(PropertyName = "value-1")]
public virtual string Prop1 { get; set; }
[Display(Order = 2, Name = "Prop 2")]
[CultureSpecific]
[JsonProperty(PropertyName = "value-2")]
public virtual string Prop2 { get; set; }
}
This means I get JSON like this:
{
"MyPage": {
"MySubPage": {
"prop1": "...",
"prop2": "..."
}
}
}
Instead of this:
{
"MyPage": {
"MySubPage": {
"value-1": "...",
"value-2": "..."
}
}
}
I know about using custom ContractResolvers for the JSON serialisation, but that will not help me because I need JSON property names that cannot be inferred from the C# property name.
I would also like to be able to set custom JSON property names for the pages themselves.
I really hope that a friendly EpiServer guru can help me out here!
Thanks in advance :)
One of the C# dev's on my project rolled his own solution for this in the end. He used reflection to examine the page tree and built the JSON up from that. Here it is. Hopefully it will help someone else as much as it did me!
using EPiServer;
using EPiServer.Core;
using EPiServer.DataAbstraction;
using EPiServer.DataAnnotations;
using EPiServer.ServiceLocation;
using EPiServer.Web.Mvc;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Dynamic;
using System.Reflection;
using System;
using System.Runtime.Caching;
using System.Linq;
using Newtonsoft.Json.Linq;
using EPiServer.Framework;
using EPiServer.Framework.Initialization;
namespace NUON.Models.MyCorp
{
public class MyCorpPageController : PageController<MyCorpPage>
{
public string Index(MyCorpPage currentPage)
{
Response.ContentType = "text/json";
// check if the JSON is cached - if so, return it
ObjectCache cache = MemoryCache.Default;
string cachedJSON = cache["myCorpPageJson"] as string;
if (cachedJSON != null)
{
return cachedJSON;
}
var output = new ExpandoObject();
var outputDict = output as IDictionary<string, object>;
var pageRouteHelper = ServiceLocator.Current.GetInstance<EPiServer.Web.Routing.PageRouteHelper>();
var pageReference = pageRouteHelper.PageLink;
var contentLoader = ServiceLocator.Current.GetInstance<IContentLoader>();
var children = contentLoader.GetChildren<PageData>(currentPage.PageLink).OfType<PageData>();
var toOutput = new { };
var jsonResultObject = new JObject();
foreach (PageData page in children)
{
// Name = e.g. BbpbannerProxy . So remove "Proxy" and add the namespace
var classType = Type.GetType("NUON.Models.MyCorp." + page.GetType().Name.Replace("Proxy", string.Empty));
// Only keep the properties from this class, not the inherited properties
jsonResultObject.Add(page.PageName, GetJsonObjectFromType(classType, page));
}
// add to cache
CacheItemPolicy policy = new CacheItemPolicy();
// expire the cache daily although it will be cleared whenever content changes.
policy.AbsoluteExpiration = DateTimeOffset.Now.AddDays(1.0);
cache.Set("myCorpPageJson", jsonResultObject.ToString(), policy);
return jsonResultObject.ToString();
}
[InitializableModule]
[ModuleDependency(typeof(EPiServer.Web.InitializationModule),
typeof(EPiServer.Web.InitializationModule))]
public class EventsInitialization : IInitializableModule
{
public void Initialize(InitializationEngine context)
{
var events = ServiceLocator.Current.GetInstance<IContentEvents>();
events.PublishedContent += PublishedContent;
}
public void Preload(string[] parameters)
{
}
public void Uninitialize(InitializationEngine context)
{
}
private void PublishedContent(object sender, ContentEventArgs e)
{
// Clear the cache because some content has been updated
ObjectCache cache = MemoryCache.Default;
cache.Remove("myCorpPageJson");
}
}
private static JObject GetJsonObjectFromType(Type classType, object obj)
{
var jsonObject = new JObject();
var properties = classType.GetProperties(BindingFlags.Public
| BindingFlags.Instance
| BindingFlags.DeclaredOnly);
foreach (var property in properties)
{
var jsonAttribute = property.GetCustomAttributes(true).FirstOrDefault(a => a is JsonPropertyAttribute);
var propertyName = jsonAttribute == null ? property.Name : ((JsonPropertyAttribute)jsonAttribute).PropertyName;
if (property.PropertyType.BaseType == typeof(BlockData))
jsonObject.Add(propertyName, GetJsonObjectFromType(property.PropertyType, property.GetValue(obj)));
else
{
var propertyValue = property.PropertyType == typeof(XhtmlString) ? property.GetValue(obj)?.ToString() : property.GetValue(obj);
if (property.PropertyType == typeof(string))
{
propertyValue = propertyValue ?? String.Empty;
}
jsonObject.Add(new JProperty(propertyName, propertyValue));
}
}
return jsonObject;
}
}
[ContentType(DisplayName = "MyCorpPage", GroupName = "MyCorp", GUID = "bc91ed7f-d0bf-4281-922d-1c5246cab137", Description = "The main MyCorp page")]
public class MyCorpPage : PageData
{
}
}
Hi I'm looking for the same thing, and until now I find this page and component.
https://josefottosson.se/episerver-contentdata-to-json/
https://github.com/joseftw/JOS.ContentJson
I hope you find it useful

How to get property from dynamic JObject programmatically

I'm parsing a JSON string using the NewtonSoft JObject.
How can I get values from a dynamic object programmatically?
I want to simplify the code to not repeat myself for every object.
public ExampleObject GetExampleObject(string jsonString)
{
ExampleObject returnObject = new ExampleObject();
dynamic dynamicResult = JObject.Parse(jsonString);
if (!ReferenceEquals(dynamicResult.album, null))
{
//code block to extract to another method if possible
returnObject.Id = dynamicResult.album.id;
returnObject.Name = dynamicResult.album.name;
returnObject.Description = dynamicResult.albumsdescription;
//etc..
}
else if(!ReferenceEquals(dynamicResult.photo, null))
{
//duplicated here
returnObject.Id = dynamicResult.photo.id;
returnObject.Name = dynamicResult.photo.name;
returnObject.Description = dynamicResult.photo.description;
//etc..
}
else if..
//etc..
return returnObject;
}
Is there any way I can extract the code blocks in the "if" statements to a separate method e.g:
private void ExampleObject GetExampleObject([string of desired type goes here? album/photo/etc])
{
ExampleObject returnObject = new ExampleObject();
returnObject.Id = dynamicResult.[something goes here?].id;
returnObject.Name = dynamicResult.[something goes here?].name;
//etc..
return returnObject;
}
Is it even possible since we can't use reflection for dynamic objects. Or am I even using the JObject correctly?
Thanks.
Assuming you're using the Newtonsoft.Json.Linq.JObject, you don't need to use dynamic. The JObject class can take a string indexer, just like a dictionary:
JObject myResult = GetMyResult();
returnObject.Id = myResult["string here"]["id"];
Hope this helps!
Another way of targeting this is by using SelectToken (Assuming that you're using Newtonsoft.Json):
JObject json = GetResponse();
var name = json.SelectToken("items[0].name");
For a full documentation: https://www.newtonsoft.com/json/help/html/SelectToken.htm
with dynamic keyword like below:
private static JsonSerializerSettings jsonSettings;
private static T Deserialize<T>(string jsonData)
{
return JsonConvert.DeserializeObject<T>(jsonData, jsonSettings);
}
//if you know what will return
var jresponse = Deserialize<SearchedData>(testJsonString);
//if you know return object type you should sign it with json attributes like
[JsonObject(MemberSerialization = MemberSerialization.OptIn)]
public class SearchedData
{
[JsonProperty(PropertyName = "Currency")]
public string Currency { get; set; }
[JsonProperty(PropertyName = "Routes")]
public List<List<Route>> Routes { get; set; }
}
// if you don't know the return type use dynamic as generic type
var jresponse = Deserialize<dynamic>(testJsonString);

C# JSON deserializer does only check format, it doesn't care about object data

I want to deserialize a JSON message received from TCP/IP in my C# application. I have really simple classes with one or two Properties at most, but they are derived. For example:
public class SemiCommand
{
public SemiCommand()
{
UID = string.Empty;
}
public SemiCommand(string uid)
{
UID = uid;
}
public string UID
{
get;
set;
}
public new string ToString()
{
return new JavaScriptSerializer().Serialize(this);
}
}
public class ResponseCommand : SemiCommand
{
protected const string DEFAULT_INFO = "OK";
public ResponseCommand()
{
UID = string.Empty;
Info = DEFAULT_INFO;
}
public ResponseCommand(string uid)
{
UID = uid;
Info = DEFAULT_INFO;
}
public string Response
{
get;
set;
}
public string Info
{
get;
set;
}
public class GetInfoResponseCommand : ResponseCommand
{
public GetInfoResponseCommand()
: base()
{
Response = "GetInfoResponse";
}
public List<ClientProcess> Processes
{
get;
set;
}
}
I made a few attempts with DataMember and DataContract attributes to solve my problem, but it didn't fix it.
The problem lies here:
private Type[] _deserializationTypes = new Type[] { typeof(StartProcessesRequestCommand), typeof(RequestCommand) };
public RequestCommand TranslateTCPMessageToCommand(string messageInString)
{
RequestCommand requestCommand = null;
for (int i = 0; i < _deserializationTypes.Length; i++)
{
try
{
requestCommand = TryDeserialize(_deserializationTypes[i], messageInString);
break;
}
catch
{
}
}
if (requestCommand == null || (requestCommand != null && requestCommand.Command == string.Empty))
{
throw new System.Runtime.Serialization.SerializationException("Unable to deserialize received message");
}
else
{
return requestCommand;
}
}
If i want to deserialize with a proper format, containing all the necessary properties, it works:
This works: {"Response":"SomeResponse","Info":"Information","UID":"123"}
However, this also works: {"nonexistingProperty":"value"}
The second one also creates a RequestCommand with property values set to null.
1st question: How can I force my messagetranslator function to make RequestCommand only if it receives all of the required properties
2nd question: If i have multiple command types which are derived from one or more ancestors, how is it possible, to deserialize it automatically from the "deepest" class if the received properties allow it.
EDIT:
I serialize/deserialize with these two
private RequestCommand TryDeserialize(Type type, string messageInString)
{
JavaScriptSerializer js = new JavaScriptSerializer();
return (RequestCommand)js.Deserialize(messageInString, type);
}
public string TranslateCommandToTCPMessage(ResponseCommand command)
{
JavaScriptSerializer js = new JavaScriptSerializer();
return js.Serialize(command);
}
The break in the try catch supposed to end the loop if the TrySerialize doesn't throw an exception, therefore the deserialization was successful.
If you actually used DataContractJsonSerializer, and you decorated the members / types in question with DataMember / DataContract, you can actually get this to happen. To do this, you can decorate ALL data members with [IsRequired=true]. This would throw an exception if the members weren't present on the wire.
Another option you have is to use IObjectReference, which let you translate one object to another post-serialization, and you can do this depending on what is deserialized from the wire.

Convert JSON String To C# Object

Trying to convert a JSON string into an object in C#. Using a really simple test case:
JavaScriptSerializer json_serializer = new JavaScriptSerializer();
object routes_list = json_serializer.DeserializeObject("{ \"test\":\"some data\" }");
The problem is that routes_list never gets set; it's an undefined object. Any ideas?
Or, you can use the Newtownsoft.Json library as follows:
using Newtonsoft.Json;
...
var result = JsonConvert.DeserializeObject<T>(json);
Where T is your object type that matches your JSON string.
It looks like you're trying to deserialize to a raw object. You could create a Class that represents the object that you're converting to. This would be most useful in cases where you're dealing with larger objects or JSON Strings.
For instance:
class Test {
String test;
String getTest() { return test; }
void setTest(String test) { this.test = test; }
}
Then your deserialization code would be:
JavaScriptSerializer json_serializer = new JavaScriptSerializer();
Test routes_list =
(Test)json_serializer.DeserializeObject("{ \"test\":\"some data\" }");
More information can be found in this tutorial:
http://www.codeproject.com/Tips/79435/Deserialize-JSON-with-Csharp.aspx
You probably don't want to just declare routes_list as an object type. It doesn't have a .test property, so you really aren't going to get a nice object back. This is one of those places where you would be better off defining a class or a struct, or make use of the dynamic keyword.
If you really want this code to work as you have it, you'll need to know that the object returned by DeserializeObject is a generic dictionary of string,object. Here's the code to do it that way:
var json_serializer = new JavaScriptSerializer();
var routes_list = (IDictionary<string, object>)json_serializer.DeserializeObject("{ \"test\":\"some data\" }");
Console.WriteLine(routes_list["test"]);
If you want to use the dynamic keyword, you can read how here.
If you declare a class or struct, you can call Deserialize instead of DeserializeObject like so:
class MyProgram {
struct MyObj {
public string test { get; set; }
}
static void Main(string[] args) {
var json_serializer = new JavaScriptSerializer();
MyObj routes_list = json_serializer.Deserialize<MyObj>("{ \"test\":\"some data\" }");
Console.WriteLine(routes_list.test);
Console.WriteLine("Done...");
Console.ReadKey(true);
}
}
Using dynamic object with JavaScriptSerializer.
JavaScriptSerializer serializer = new JavaScriptSerializer();
dynamic item = serializer.Deserialize<object>("{ \"test\":\"some data\" }");
string test= item["test"];
//test Result = "some data"
Newtonsoft is faster than java script serializer. ... this one depends on the Newtonsoft NuGet package, which is popular and better than the default serializer.
one line code solution.
var myclass = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(Jsonstring);
Myclass oMyclass = Newtonsoft.Json.JsonConvert.DeserializeObject<Myclass>(Jsonstring);
You can accomplished your requirement easily by using Newtonsoft.Json library. I am writing down the one example below have a look into it.
Class for the type of object you receive:
public class User
{
public int ID { get; set; }
public string Name { get; set; }
}
Code:
static void Main(string[] args)
{
string json = "{\"ID\": 1, \"Name\": \"Abdullah\"}";
User user = JsonConvert.DeserializeObject<User>(json);
Console.ReadKey();
}
this is a very simple way to parse your json.
Here's a simple class I cobbled together from various posts.... It's been tested for about 15 minutes, but seems to work for my purposes. It uses JavascriptSerializer to do the work, which can be referenced in your app using the info detailed in this post.
The below code can be run in LinqPad to test it out by:
Right clicking on your script tab in LinqPad, and choosing "Query
Properties"
Referencing the "System.Web.Extensions.dll" in "Additional References"
Adding an "Additional Namespace Imports" of
"System.Web.Script.Serialization".
Hope it helps!
void Main()
{
string json = #"
{
'glossary':
{
'title': 'example glossary',
'GlossDiv':
{
'title': 'S',
'GlossList':
{
'GlossEntry':
{
'ID': 'SGML',
'ItemNumber': 2,
'SortAs': 'SGML',
'GlossTerm': 'Standard Generalized Markup Language',
'Acronym': 'SGML',
'Abbrev': 'ISO 8879:1986',
'GlossDef':
{
'para': 'A meta-markup language, used to create markup languages such as DocBook.',
'GlossSeeAlso': ['GML', 'XML']
},
'GlossSee': 'markup'
}
}
}
}
}
";
var d = new JsonDeserializer(json);
d.GetString("glossary.title").Dump();
d.GetString("glossary.GlossDiv.title").Dump();
d.GetString("glossary.GlossDiv.GlossList.GlossEntry.ID").Dump();
d.GetInt("glossary.GlossDiv.GlossList.GlossEntry.ItemNumber").Dump();
d.GetObject("glossary.GlossDiv.GlossList.GlossEntry.GlossDef").Dump();
d.GetObject("glossary.GlossDiv.GlossList.GlossEntry.GlossDef.GlossSeeAlso").Dump();
d.GetObject("Some Path That Doesnt Exist.Or.Another").Dump();
}
// Define other methods and classes here
public class JsonDeserializer
{
private IDictionary<string, object> jsonData { get; set; }
public JsonDeserializer(string json)
{
var json_serializer = new JavaScriptSerializer();
jsonData = (IDictionary<string, object>)json_serializer.DeserializeObject(json);
}
public string GetString(string path)
{
return (string) GetObject(path);
}
public int? GetInt(string path)
{
int? result = null;
object o = GetObject(path);
if (o == null)
{
return result;
}
if (o is string)
{
result = Int32.Parse((string)o);
}
else
{
result = (Int32) o;
}
return result;
}
public object GetObject(string path)
{
object result = null;
var curr = jsonData;
var paths = path.Split('.');
var pathCount = paths.Count();
try
{
for (int i = 0; i < pathCount; i++)
{
var key = paths[i];
if (i == (pathCount - 1))
{
result = curr[key];
}
else
{
curr = (IDictionary<string, object>)curr[key];
}
}
}
catch
{
// Probably means an invalid path (ie object doesn't exist)
}
return result;
}
}
As tripletdad99 said
var result = JsonConvert.DeserializeObject<T>(json);
but if you don't want to create an extra object you can make it with Dictionary instead
var result = JsonConvert.DeserializeObject<Dictionary<string, string>>(json_serializer);
add this ddl to reference to your project: System.Web.Extensions.dll
use this namespace: using System.Web.Script.Serialization;
public class IdName
{
public int Id { get; set; }
public string Name { get; set; }
}
string jsonStringSingle = "{'Id': 1, 'Name':'Thulasi Ram.S'}".Replace("'", "\"");
var entity = new JavaScriptSerializer().Deserialize<IdName>(jsonStringSingle);
string jsonStringCollection = "[{'Id': 2, 'Name':'Thulasi Ram.S'},{'Id': 2, 'Name':'Raja Ram.S'},{'Id': 3, 'Name':'Ram.S'}]".Replace("'", "\"");
var collection = new JavaScriptSerializer().Deserialize<IEnumerable<IdName>>(jsonStringCollection);
Copy your Json and paste at textbox on json2csharp and click on Generate button.
A cs class will be generated use that cs file as below
var generatedcsResponce = JsonConvert.DeserializeObject(yourJson);
Where RootObject is the name of the generated cs file;
Another fast and easy way to semi-automate these steps is to:
take the JSON you want to parse and paste it here: https://app.quicktype.io/ . Change language to C# in the drop down.
Update the name in the top left to your class name, it defaults to "Welcome".
In visual studio go to Website -> Manage Packages and use NuGet to add Json.Net from Newtonsoft.
app.quicktype.io generated serialize methods based on Newtonsoft.
Alternatively, you can now use code like:
WebClient client = new WebClient();
string myJSON = client.DownloadString("https://URL_FOR_JSON.com/JSON_STUFF");
var myClass = Newtonsoft.Json.JsonConvert.DeserializeObject(myJSON);
Convert a JSON string into an object in C#. Using below test case.. its worked for me. Here "MenuInfo" is my C# class object.
JsonTextReader reader = null;
try
{
WebClient webClient = new WebClient();
JObject result = JObject.Parse(webClient.DownloadString("YOUR URL"));
reader = new JsonTextReader(new System.IO.StringReader(result.ToString()));
reader.SupportMultipleContent = true;
}
catch(Exception)
{}
JsonSerializer serializer = new JsonSerializer();
MenuInfo menuInfo = serializer.Deserialize<MenuInfo>(reader);
First you have to include library like:
using System.Runtime.Serialization.Json;
DataContractJsonSerializer desc = new DataContractJsonSerializer(typeof(BlogSite));
string json = "{\"Description\":\"Share knowledge\",\"Name\":\"zahid\"}";
using (var ms = new MemoryStream(ASCIIEncoding.ASCII.GetBytes(json)))
{
BlogSite b = (BlogSite)desc.ReadObject(ms);
Console.WriteLine(b.Name);
Console.WriteLine(b.Description);
}
Let's assume you have a class name Student it has following fields and it has a method which will take JSON as a input and return a string Student Object.We can use JavaScriptSerializer here Convert JSON String To C# Object.std is a JSON string here.
public class Student
{
public string FirstName {get;set:}
public string LastName {get;set:}
public int[] Grades {get;set:}
}
public static Student ConvertToStudent(string std)
{
var serializer = new JavaScriptSerializer();
Return serializer.Deserialize<Student>(std);
}
Or, you can use the System.Text.Json library as follows:
using System.Text.Json;
...
var options = new JsonSerializerOptions()
{
PropertyNameCaseInsensitive = true
});
var result = JsonSerializer.Deserialize<List<T>>(json, options);
Where T is your object type that matches your JSON string.
System.Text.Json is available in:
.NET Core 2.0 and above
.NET Framework 4.6.1 and above

Categories

Resources