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

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

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


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

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


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

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

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

5
nie korzystasz tutaj z biblioteki newtonsoft
Mickey Perlstein
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.