Tworzenie JSON w locie za pomocą JObject

97

W przypadku niektórych moich testów jednostkowych chcę mieć możliwość budowania określonych wartości JSON (w tym przypadku albumów z nagraniami), które można wykorzystać jako dane wejściowe dla testowanego systemu.

Mam następujący kod:

var jsonObject = new JObject();
jsonObject.Add("Date", DateTime.Now);
jsonObject.Add("Album", "Me Against The World");
jsonObject.Add("Year", 1995);
jsonObject.Add("Artist", "2Pac");

To działa dobrze, ale nigdy nie lubiłem składni „magicznego ciągu” i wolałbym coś bliższego składni właściwości expando w JavaScript, na przykład:

jsonObject.Date = DateTime.Now;
jsonObject.Album = "Me Against The World";
jsonObject.Year = 1995;
jsonObject.Artist = "2Pac";
Karl Anderson
źródło
5
Powinieneś otrzymać podwójne punkty za wybór wykonawcy / albumu!
spottedmahn

Odpowiedzi:

145

A co powiesz na:

dynamic jsonObject = new JObject();
jsonObject.Date = DateTime.Now;
jsonObject.Album = "Me Against the world";
jsonObject.Year = 1995;
jsonObject.Artist = "2Pac";
Dimitar Dimitrov
źródło
3
Doskonały! Dokładnie to, czego szukałem, zupełnie o czym zapomniałem dynamic.
Karl Anderson
Otrzymuję „Newtonsoft.Json.Linq.JObject” nie zawiera definicji błędu „Data”, gdy próbuję uruchomić kod. Sposób, w jaki mogłem to zadziałać, to zmienić pierwszą linię na: dynamic jsonExpando = new ExpandoObject();i dodać linię po kodzie:JObject jsonObject = JObject.FromObject(jsonExpando);
BornToCode
3
Jeśli chcesz dodać List <> do obiektu Json, musisz zrobić coś takiego jsonObject.list = JToken.FromObject(mylist);.
Steve Smith
Możesz użyć kombinacji indeksu i notacji właściwości w przypadku, gdy trafisz nazwę pola zawierającą znak specjalny, np. Create-Year ". Nie będziesz w stanie napisać jsonObject.Create-Year = 1995, ale możesz użyć następującego. JsonObject [" Create-Year "] = 1995; jsonObject.Artist =" 2Pac ";
PAS
72

Możesz użyć tej JObject.Parseoperacji i po prostu podać tekst JSON rozdzielany pojedynczymi cudzysłowami.

JObject  o = JObject.Parse(@"{
  'CPU': 'Intel',
  'Drives': [
    'DVD read/writer',
    '500 gigabyte hard drive'
  ]
}");

Ma to tę zaletę, że faktycznie jest JSON, więc czyta się go jako JSON.

Lub masz dane testowe, które są dynamiczne, możesz użyć JObject.FromObjectoperacji i podać obiekt wbudowany.

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

Dokumentacja Json.net dotycząca serializacji

Lee Jensen
źródło
10
JObject.FromObject należy zaznaczyć jako poprawną odpowiedź. Dzięki.
Thomas
1
Myślę, że JObject.FromObjectnie zadziała, jeśli istnieją właściwości ze znakami specjalnymi, takimi jak -.
Jatin Sanghvi
40

Ani dynamic, ani JObject.FromObjectrozwiązanie nie działa, gdy masz właściwości JSON, które nie są prawidłowymi nazwami zmiennych C #, np "@odata.etag". Preferuję składnię inicjatora indeksatora w moich przypadkach testowych:

JObject jsonObject = new JObject
{
    ["Date"] = DateTime.Now,
    ["Album"] = "Me Against The World",
    ["Year"] = 1995,
    ["Artist"] = "2Pac"
};

Posiadanie oddzielnego zestawu otaczających symboli do inicjowania JObjecti dodawania do niego właściwości sprawia, że ​​inicjatory indeksu są bardziej czytelne niż klasyczne inicjatory obiektów, szczególnie w przypadku złożonych obiektów JSON, jak poniżej:

JObject jsonObject = new JObject
{
    ["Date"] = DateTime.Now,
    ["Album"] = "Me Against The World",
    ["Year"] = 1995,
    ["Artist"] = new JObject
    {
        ["Name"] = "2Pac",
        ["Age"] = 28
    }
};

W przypadku składni inicjatora obiektu powyższa inicjalizacja wyglądałaby następująco:

JObject jsonObject = new JObject
{
    { "Date", DateTime.Now },
    { "Album", "Me Against The World" },
    { "Year", 1995 }, 
    { "Artist", new JObject
        {
            { "Name", "2Pac" },
            { "Age", 28 }
        }
    }
};
Jatin Sanghvi
źródło
2
Ostatnia z nich to zdecydowanie najlepsza składnia do pisania json w języku C #.
Anthony Brenelière
zobacz stackoverflow.com/questions/51015036/… aby dowiedzieć się, jak to zrobić również z kolekcjami
kofifus
30

Istnieją środowiska, w których nie można używać dynamicznych (np. Xamarin.iOS) lub przypadki, w których po prostu szukasz alternatywy dla poprzednich prawidłowych odpowiedzi.

W takich przypadkach możesz:

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

Więcej dokumentacji tutaj: http://www.newtonsoft.com/json/help/html/CreatingLINQtoJSON.htm

Daniele D.
źródło
2

Prosty sposób tworzenia newtonsoft JObject z Properties.

To jest przykładowe właściwości użytkownika

public class User
{
    public string Name;
    public string MobileNo;
    public string Address;
}

i chcę, aby ta właściwość w Newtonsoft JObject to:

JObject obj = JObject.FromObject(new User()
{
    Name = "Manjunath",
    MobileNo = "9876543210",
    Address = "Mumbai, Maharashtra, India",
});

Wynik będzie taki:

{"Name":"Manjunath","MobileNo":"9876543210","Address":"Mumbai, Maharashtra, India"}
Manjunath Bilwar
źródło
2

Wcześniej czy później będziesz miał własność o specjalnym charakterze. Możesz użyć indeksu lub kombinacji indeksu i właściwości.

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
PIERWSZEŃSTWO
źródło
Jak to odpowiada na pytanie?
Enigmativity
@Enigmativity, Chodzi mi o to, że można używać razem notacji indeksu i notacji właściwości. tj. obj [x] = x1; obj.y = y1 można użyć w tym samym kodzie. Połączenie dynamicznego słowa kluczowego i notacji indeksu odpowiada na pytania. Żadna inna odpowiedź nie wspomina o tym. Być może powinien to być komentarz niż odpowiedź.
PAS
Po prostu myślę, że pytanie dotyczy nie używania magicznych strun, ale ta odpowiedź mu to daje.
Enigmativity
@Enigmativity, dynamiczne słowo kluczowe po prostu oszukuje kompilator. Więc to nie różni się od dowolnego ciągu. obiekt typu dynmaic nie jest silnie typizowany. To tylko cukier syntaktyczny. Jeśli obiekt bazowy nie ma właściwości, nie powiedzie się w czasie wykonywania. ale nie możesz używać właściwości, jeśli nazwa właściwości zawiera znaki specjalne, np. 99BottlesOfBeer, namespace, It's-All-Over. W takich przypadkach możemy użyć indeksowanych właściwości. Inna odpowiedź sprawia, że ​​myślisz, że to jedna lub druga, ale możesz mieszać i dopasowywać właściwość i indeks.
PAS
-3

Możesz użyć biblioteki Newtonsoft i używać jej w następujący sposób

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 );
Nirmal
źródło
5
nie korzystasz tutaj z biblioteki newtonsoft
Mickey Perlstein