0

I am very new to this.Pardon me if I make any mistakes.

I have data in JSON form.Can I read this data directly and use it in C# code ?

From what I understood from reading up on the internet,I think I have to convert it into an object form to use the data.Am I right ?

If yes,Then I saw this method to convert as below :

string data = JsonConvert.DeserializeObject<string>(getmyissue());

getmyissue is the function which returns a string which has data in json format.

This gives me an exception saying

"Error reading string.Unexpected Token."

Can someone guide me where am I going wrong ?

EDIT

MyIssue.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Example
{
    public class MyIssue
    {
        public string name{get;set;}
        public string description { get; set; }
        public string created { get;set; }
        public string updated{get;set;}
        public string displayName { get; set; }

    }
}

Program.cs

MyIssue obj=null;
        try
        {             
            obj = JsonConvert.DeserializeObject<MyIssue>(manager.getmyissue());
        }
        catch(Exception e)
        {
            Console.WriteLine(e.Message);
        }

        Console.WriteLine("Name:  "+obj.name);
bishnu
  • 49
  • 1
  • 11

2 Answers2

3

The easiest way to de-serialize Json in a C#/.NET program is to use the brilliant NewtonSoft JSON library.

There are numerous ways to do it, but I have to admit that the NS libs just get on with the task (and no I'm not a member of the team etc, just an Avid User :-) ).

To do what you want for example, if you had:

{'Name': 'A person', 'AllowAccess': true,'Areas': ['Sales','Admin']}

You would first build an object to represent it as follows:

public MyObject
{
  public string Name { get; set; }
  public bool AllowAccess { get; set; }
  public List<string> Areas { get; set; }
}

Once you've done this, it's a simple case of just doing the following:

string jsonString = "// Your json formated string data goes here";
MyObject myObject = JsonConvert.DeserializeObject<MyObject>(jsonString);

The properties in your object should at that point, reflect the properties in the JSON data you sent to it.

You will of course need to add the NS JSON Libs to your project, either via NuGet or Manually, which ever is easier for you, everything you need to know about that is here:

How to install JSON.NET using NuGet?

The really good thing about NS JSON however is not the ease of use, but the fact that it can also do dynamic de-serialization.

This comes in handy if you've no idea what to expect in the JSON you receive, and so don't know ahead of time how to construct an object to hold the results.

Rather than repeat what others have said however, you can find more information of doing things dynamically in this stack overflow post:

Deserializing JSON using JSon.NET with dynamic data

Update

Looking at your JSON data you have way more fields/properties in there than your trying to parse, and none of the libraries in common use (To the best of my knowledge) will pick and choose the fields to copy, you either have an object that represents them all, or not at all, the later of which I believe is the problem your facing.

I have a rather neat "JSON" plug in for chrome, than when given a chunk of JSON data formats the output for me nicely and makes it easy to read, it also helps massively when defining objects, allowing you to see the full nested structure of your data, here are a series of images showing your JSON data formatted using this plugin:

Image 1

Image 2

I'm not going to paste anymore images in, but that goes on for another 4 pages!!

Now, some extra information that may help you.

I know from experience (I had to write a parser in PHP for these Jira webhooks) that within the Jira control panel, you can configure your webhooks to ONLY return the information your interested in.

Right now, it looks like you've just told the system to dump everything, for every event that you've hooked too (Which looks like - all of them), it's been a while since I did any work with these, but as well as a global webhook, you also have individual webhooks, which only fire on specific events and produce JSON data that's very much smaller than what your dealing with here.

I'd therefore advise you, to take a look in your Jira control panel (Or ask your Admin/Lead Dev/etc to take a look) and seriously trim down as much of that data as you can.

Further more, if memory serves me right, you can also make various web API calls to the Jira service to get this info too, and in that case you can tell the API exactly what your interested in, meaning it will only return the fields you need.

Right now, your main problem is the sheer volume of data your trying to deal with, if you tackle that problem, you'll find the issues surrounding the code your trying to get working will be very much easier to deal with.

Update 2

Just to make it clearer what I mean by using a "dynamic" type to get at your data, you would use something like the following code:

string jsonString = "// Your json formated string data goes here";
var result = JsonConvert.DeserializeObject<dynamic>(jsonString);

The difference here is that your using the C# dynamic type rather than a strongly typed object of your own design.

"dynamic" is useful, because it's kind of like having an empty object, and then having the properties added for you, without you having to define it.

What this essentially means is that, if you pass in the following JSON:

{'Name': 'A person', 'AllowAccess': true,'Areas': ['Sales','Admin']}

You'll end up with a dynamic object that looks like:

result = dynamic
{
  public string Name { get; set; }
  public bool AllowAccess { get; set; }
  public List<string> Areas { get; set; }
}

thus:

result.Name 

will get you access to the contents of the Name field and so on.

If your JSON was then changed to become:

{'Name': 'A person', 'AllowAccess': true,'Areas': ['Sales','Admin'], 'Location': 'The World' }

Your object would magically have a property called 'Location' containing the value 'The World' which you could access using:

result.Location

In your case, this would allow you to define your concrete object EG:

public MyObject
{
  public string Name { get; set; }
  public string Email { get; set; }
}

and then do something like the following (Assuming that your inbound JSON had properties in called Name & Email):

string jsonString = "// Your json formated string data goes here";
var result = JsonConvert.DeserializeObject<dynamic>(jsonString);
MyObject myObject = new MyObject
{
  Name = result.Name,
  Email = result.Email
}

You'd then discard the dynamic object as you'd not need it anymore.

The BIG problem your going to have with this approach is maintaining your models. Manual property assignment is all fine and dandy for a small handful of properties and objects, but it soon becomes a huge maintenance nightmare as your software grows.

I'm sure it doesn't take much to imagine what kind of task you'd be facing if you had to do this for 100 different JSON requests and 50 different types of objects.

For this reason, using this approach you should really consider using some kind of mapping technology such as "AutoMapper", however for now I'm going to advise you leave that until later before you start researching it, as it'll not help you to be clear about dealing with this dynamic approach.

Community
  • 1
  • 1
shawty
  • 5,729
  • 2
  • 37
  • 71
  • Thank you for your answer.This is what I had tried.But my object doesn't have the data for some reason.I tried putting a breakpoint in the line and I notice that myObject.Name is null.Any idea where the mistake is happening ?I have followed the exact approach as your answer. – bishnu May 07 '15 at 11:26
  • The json string is received correctly.I have checked it by printing the string on the console.The error happens when it is getting converted to myObject, – bishnu May 07 '15 at 11:37
  • Do an update on your question and copy/paste your EXACT code from your project into your question above, it's probably a simple mistake, but unless I/WE can read your EXACT code we can't really help. For completeness you should also copy/paste the exact JSON string printed on your console too, just so we can check that your object structure and JSON structure match. – shawty May 07 '15 at 13:51
  • **Additional:** Also make 100% sure you added newtonsoft JSON to your project, if you didn't then you will get error because the functionality can't be found. – shawty May 07 '15 at 13:53
  • So your attempting to parse a Jira WebHook then eh? :-) looking now. – shawty May 07 '15 at 14:16
  • ok, 2 things stand out immediately here. **1)** Your JSON contains way more data than the object model your trying to fill, your throwing the entire chunk of JSON at an object that looks only to be a small subset of the data your trying to parse. **2)** Your object structure **MUST** match exactly the fields you have in your JSON if your trying to do static de-serialization (Which is what your trying to do), if you have more data than fields in the object that you care about, then I'd strongly advise you to look at the link on de-serializing dynamic data and only grabbing the properties – shawty May 07 '15 at 14:23
  • *(cont)* you need. Either that, or read through the JSON you have very, very carefully and implement every property name you see in there. None of the JSON serializers either NS or the built in ones will search for and implement specific fields, to do that you'd need to implement some kind of intelligent mapper. – shawty May 07 '15 at 14:25
  • Shawty-The field names in my object exactly match the Json fields.Can't I selectively choose only the ones I require ? – bishnu May 07 '15 at 16:16
  • Not that I'm aware of (Unless someone here knows of some JSON toolkit that does), All of the JSON toolkits I've used including Newtonsoft must have an object that matches the entire JSON payload otherwise nothing get's created. As I mentioned in my last comment, your best bet is to read the link on "Dynamic JSON objects", create a dynamic object, then just pluck out the small number of fields you need into a concrete object. Trying to do it as you are however will fail unless you have every field in your object, the same will apply to Thorstens answer too. – shawty May 07 '15 at 17:49
  • When you say "dynamic json objects" can I use something like Biofractal's answer here: http://stackoverflow.com/questions/2546138/deserializing-json-data-to-c-sharp-using-json-net – bishnu May 08 '15 at 04:34
  • Yes that's exactly what I meant. Let me add another update to my answer, to explain better. – shawty May 08 '15 at 08:54
  • Thanks shawty.I am being able to access fields like description and reporter.assignee.I need the createdDate and updatedDate which are in customFields.How do I access those ? – bishnu May 08 '15 at 15:56
  • Also,how can I access your chrome plugin ? – bishnu May 08 '15 at 15:57
  • Not sure what you mean by "Custom Fields", if you mean those that have names such as "custom_12345" then same as any other field, there should be a property with that name on the object. The thing with dynamic objects, is you can't really tell ahead of time what NS-JSON will or will not add add to the output object. As for the chrome plug-in, it's not mine, but if your working with lot's of JSON is very handy. You can find it in the chrome web-store at : https://chrome.google.com/webstore/detail/jsonview/chklaanhfefbnpoihckbnefhakgolnmc?hl=en – shawty May 11 '15 at 10:30
0

The JSON you get is already a string, so converting it to string doesn't make much sense. You need to create classes that reflect the structure represented by the JSON string.

For example to convert the following JSON into objects, you'd have to create a class for the users:

{"user":{"name":"asdf","teamname":"b","email":"c","players":["1","2"]}}

public class User
{
    public string name { get; set; }
    public string teamname { get; set; }
    public string email { get; set; }
    public Array players { get; set; }
}

Then you should be able to use this:

JavaScriptSerializer jss= new JavaScriptSerializer(); 
List<User> users = jss.Deserialize<List<User>>(jsonResponse); 
Thorsten Dittmar
  • 55,956
  • 8
  • 91
  • 139
  • Yes,my bad.You are correct. I thought DeseriiarizeObject will convert it to some readable form.I will try reading on how to create classes that reflect the structure represented by the JSON string. – bishnu May 07 '15 at 10:40