144

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";
1
  • 10
    You should get double points for the artist / album selection! Commented Aug 24, 2018 at 20:08

9 Answers 9

204

Well, how about:

dynamic jsonObject = new JObject();
jsonObject.Date = DateTime.Now;
jsonObject.Album = "Me Against the world";
jsonObject.Year = 1995;
jsonObject.Artist = "2Pac";
Sign up to request clarification or add additional context in comments.

9 Comments

Perfect! Exactly what I was looking for, completely forgot about dynamic.
I get 'Newtonsoft.Json.Linq.JObject' does not contain a definition for 'Date' error when I try to run your code. The way I could make it work is change the first line to: dynamic jsonExpando = new ExpandoObject(); and add a line after your code: JObject jsonObject = JObject.FromObject(jsonExpando);
If you want to add a List<> to your Json object, you need to do something like jsonObject.list = JToken.FromObject(mylist);.
You could use combination of index and property notation in case you hit field name having special character e.g. Create-Year". You will not b able to write jsonObject.Create-Year = 1995, but can use following. jsonObject["Create-Year"] = 1995; jsonObject.Artist = "2Pac";
Now instead of magic strings you have magic properties :)
|
106

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

3 Comments

JObject.FromObject should be marked as the correct answer. Thanks.
I think JObject.FromObject won't work if there are properties with special characters like -.
This is a better answer!
81

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 }
        }
    }
};

3 Comments

The last one is definitively the best syntax to write json in c#.
see stackoverflow.com/questions/51015036/… for how to do this with collections as well
@AnthonyBrenelière I find the index initializer syntax a lot more clearer. For e.g. this { "Album", "Me Against The World" } in the object initializer looks like a collection of items.
42

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

Comments

8

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

4 Comments

How does this answer the question?
@Enigmativity, The point I am making is, you can use index notation and property notation together. i.e. obj[x] =x1; obj.y = y1 can be used in the same code. The combination of dynamic keyword and index notation answers the questions. No other answer has mentions this. Possibly, this should be comment than a answer.
I just think that the question is about not using magic strings, but this answer is giving him that.
@Enigmativity, dynamic keyword just fools the compiler. So it's no different than arbitrary string. object of dynmaic type is not strongly typed. It's just a syntactic sugar. If the underlying object doesn't have property it will failed runtime. but you just cannot use properties if the name of property contains special characters e.g. 99BottlesOfBeer, namespace, It’s-All-Over. So in those cases, we can use indexed properties. Other answer make you think that it's one or other, but you can mix and match property and index.
5

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"}

2 Comments

Another option (if User definition is not required) is using anonymous types : var obj = JObject.FromObject(new { Name = "Walter", Country = "Peru" });. Reference here
Yes, that is correct. Can be created using anonymous type. @WalterAgile
0

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.

1 Comment

This does not provide an answer to the question. To critique or request clarification from an author, leave a comment below their post. - From Review
0

This works well for me

var jsonObject = JObject.FromObject(new Dictionary<string, string>() {
{ "Date",DateTime.Now.ToString() }
,{ "Album", "Me Against The World" }
,{ "Year", "1995" }
,{ "Artist", "2Pac" }
});

JSON is always a string. So creating a Dictionary will naturally convert automagically to JSON when it is parsed out. If you want to make it a JObject, just create the Dictionary in the static method and have it immediately become one. The JObject class will do your conversions as well.

Comments

-4

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 );

1 Comment

you're not actually using the library newtonsoft here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.