Criação de JSON em tempo real com JObject

97

Para alguns de meus testes de unidade, desejo a capacidade de construir valores JSON específicos (álbuns de registro neste caso) que podem ser usados ​​como entrada para o sistema em teste.

Eu tenho o seguinte código:

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

Isso funciona bem, mas eu nunca gostei muito da sintaxe da "string mágica" e preferiria algo mais próximo da sintaxe expando-property em JavaScript como esta:

jsonObject.Date = DateTime.Now;
jsonObject.Album = "Me Against The World";
jsonObject.Year = 1995;
jsonObject.Artist = "2Pac";
Karl Anderson
fonte
5
Você deve receber o dobro de pontos pela seleção de artista / álbum!
spottedmahn

Respostas:

145

Bem, que tal:

dynamic jsonObject = new JObject();
jsonObject.Date = DateTime.Now;
jsonObject.Album = "Me Against the world";
jsonObject.Year = 1995;
jsonObject.Artist = "2Pac";
Dimitar Dimitrov
fonte
3
Perfeito! Exatamente o que eu estava procurando, esqueci completamente dynamic.
Karl Anderson
Recebo 'Newtonsoft.Json.Linq.JObject' não contém uma definição para o erro 'Data' quando tento executar seu código. A forma como eu poderia fazer isso funcionar é mudar a primeira linha para: dynamic jsonExpando = new ExpandoObject();e adicionar uma linha após o seu código:JObject jsonObject = JObject.FromObject(jsonExpando);
BornToCode
3
Se você deseja adicionar um List <> ao seu objeto Json, você precisa fazer algo como jsonObject.list = JToken.FromObject(mylist);.
Steve Smith
Você pode usar a combinação de índice e notação de propriedade caso acerte o nome do campo com um caractere especial, por exemplo, Create-Year ". Você não será capaz de escrever jsonObject.Create-Year = 1995, mas pode usar o seguinte. JsonObject [" Create-Year "] = 1995; jsonObject.Artist =" 2Pac ";
PAS
72

Você pode usar a JObject.Parseoperação e simplesmente fornecer texto JSON delimitado por aspas simples.

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

Isso tem a vantagem de ser realmente JSON e, portanto, é lido como JSON.

Ou você tem dados de teste que são dinâmicos, você pode usar a JObject.FromObjectoperação e fornecer um objeto embutido.

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

Documentação Json.net para serialização

Lee Jensen
fonte
10
JObject.FromObject deve ser marcado como a resposta correta. Obrigado.
Thomas
1
Acho que JObject.FromObjectnão funcionará se houver propriedades com caracteres especiais como -.
Jatin Sanghvi
40

Nem dynamic, nem a JObject.FromObjectsolução funciona quando você tem propriedades JSON que não são nomes de variáveis ​​C # válidos, por exemplo "@odata.etag". Eu prefiro a sintaxe do inicializador do indexador em meus casos de teste:

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

Ter um conjunto separado de símbolos delimitadores para inicializar JObjecte adicionar propriedades torna os inicializadores de índice mais legíveis do que os inicializadores de objeto clássicos, especialmente no caso de objetos JSON compostos conforme abaixo:

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

Com a sintaxe do inicializador de objetos, a inicialização acima seria:

JObject jsonObject = new JObject
{
    { "Date", DateTime.Now },
    { "Album", "Me Against The World" },
    { "Year", 1995 }, 
    { "Artist", new JObject
        {
            { "Name", "2Pac" },
            { "Age", 28 }
        }
    }
};
Jatin Sanghvi
fonte
2
A última é definitivamente a melhor sintaxe para escrever json em c #.
Anthony Brenelière 01 de
consulte stackoverflow.com/questions/51015036/… para saber como fazer isso também com coleções
kofifus
30

Existem alguns ambientes onde você não pode usar dinâmico (por exemplo, Xamarin.iOS) ou casos em que você apenas procura uma alternativa para as respostas válidas anteriores.

Nestes casos, você pode fazer:

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

Mais documentação aqui: http://www.newtonsoft.com/json/help/html/CreatingLINQtoJSON.htm

Daniele D.
fonte
2

Maneira simples de criar newtonsoft JObject de Propriedades.

Este é um exemplo de propriedades do usuário

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

e eu quero esta propriedade em Newtonsoft JObject é:

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

A saída será assim:

{"Name":"Manjunath","MobileNo":"9876543210","Address":"Mumbai, Maharashtra, India"}
Manjunath Bilwar
fonte
2

Mais cedo ou mais tarde você terá um imóvel com caráter especial. Você pode usar índice ou combinação de índice e propriedade.

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
PAS
fonte
Como isso responde à pergunta?
Enigmativity
@Enigmativity, o que quero dizer é que você pode usar a notação de índice e a notação de propriedade juntas. ou seja, obj [x] = x1; obj.y = y1 pode ser usado no mesmo código. A combinação de palavra-chave dinâmica e notação de índice responde às perguntas. Nenhuma outra resposta menciona isso. Possivelmente, isso deve ser um comentário do que uma resposta.
PAS
Só acho que a questão é sobre não usar cordas mágicas, mas essa resposta está dando a ele isso.
Enigmativity
@Enigmativity, palavra-chave dinâmica apenas engana o compilador. Portanto, não é diferente de uma string arbitrária. o objeto do tipo dinâmico não é fortemente tipado. É apenas um açúcar sintático. Se o objeto subjacente não tiver propriedade, o tempo de execução falhará. mas você simplesmente não pode usar propriedades se o nome da propriedade contiver caracteres especiais, por exemplo, 99BottlesOfBeer, namespace, It's-All-Over. Então, nesses casos, podemos usar propriedades indexadas. Outra resposta faz você pensar que é uma ou outra, mas você pode misturar e combinar propriedade e índice.
PAS de
-3

Você pode usar a biblioteca Newtonsoft e usá-la da seguinte maneira

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
fonte
5
você não está realmente usando a biblioteca newtonsoft aqui
Mickey Perlstein