Creando JSON sobre la marcha con JObject

96

Para algunas de mis pruebas unitarias, quiero tener la capacidad de crear valores JSON particulares (álbumes de grabación en este caso) que se puedan usar como entrada para el sistema bajo prueba.

Tengo el siguiente 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");

Esto funciona bien, pero nunca me ha gustado la sintaxis de la "cadena mágica" y preferiría algo más cercano a la sintaxis de propiedad expando en JavaScript como esta:

jsonObject.Date = DateTime.Now;
jsonObject.Album = "Me Against The World";
jsonObject.Year = 1995;
jsonObject.Artist = "2Pac";
Karl Anderson
fuente
5
¡Debería obtener el doble de puntos por la selección de artista / álbum!
spottedmahn

Respuestas:

143

Bueno, que tal:

dynamic jsonObject = new JObject();
jsonObject.Date = DateTime.Now;
jsonObject.Album = "Me Against the world";
jsonObject.Year = 1995;
jsonObject.Artist = "2Pac";
Dimitar Dimitrov
fuente
3
¡Perfecto! Exactamente lo que estaba buscando, olvidado por completo dynamic.
Karl Anderson
Me sale 'Newtonsoft.Json.Linq.JObject' no contiene una definición para el error de 'Fecha' cuando intento ejecutar su código. La forma en que podría hacerlo funcionar es cambiar la primera línea a: dynamic jsonExpando = new ExpandoObject();y agregar una línea después de su código:JObject jsonObject = JObject.FromObject(jsonExpando);
BornToCode
3
Si desea agregar un List <> a su objeto Json, debe hacer algo como jsonObject.list = JToken.FromObject(mylist);.
Steve Smith
Puede usar una combinación de notación de índice y propiedad en caso de que ingrese un nombre de campo con un carácter especial, por ejemplo, Create-Year ". No podrá escribir jsonObject.Create-Year = 1995, pero puede usar lo siguiente. JsonObject [" Create-Year "] = 1995; jsonObject.Artist =" 2Pac ";
PAS
71

Puede utilizar la JObject.Parseoperación y simplemente proporcionar texto JSON delimitado por comillas simples.

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

Esto tiene la ventaja de ser JSON, por lo que se lee como JSON.

O tiene datos de prueba que son dinámicos, puede utilizar la JObject.FromObjectoperación y proporcionar un objeto en línea.

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

Documentación de json.net para la serialización

Lee Jensen
fuente
10
JObject.FromObject debe marcarse como la respuesta correcta. Gracias.
Thomas
1
Creo JObject.FromObjectque no funcionará si hay propiedades con caracteres especiales como -.
Jatin Sanghvi
39

Ni dynamic, ni la JObject.FromObjectsolución funciona cuando tiene propiedades JSON que no son nombres de variable C # válidos, por ejemplo "@odata.etag". Prefiero la sintaxis del inicializador del indexador en mis casos de prueba:

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

Tener un conjunto separado de símbolos adjuntos para inicializar JObjecty agregar propiedades hace que los inicializadores de índice sean más legibles que los inicializadores de objetos clásicos, especialmente en el caso de objetos JSON compuestos como se muestra a continuación:

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

Con la sintaxis del inicializador de objetos, la inicialización anterior sería:

JObject jsonObject = new JObject
{
    { "Date", DateTime.Now },
    { "Album", "Me Against The World" },
    { "Year", 1995 }, 
    { "Artist", new JObject
        {
            { "Name", "2Pac" },
            { "Age", 28 }
        }
    }
};
Jatin Sanghvi
fuente
2
El último es definitivamente la mejor sintaxis para escribir json en c #.
Anthony Brenelière
consulte stackoverflow.com/questions/51015036/… para saber cómo hacer esto con las colecciones también
kofifus
30

Hay algunos entornos en los que no puede usar dinámicos (por ejemplo, Xamarin.iOS) o casos en los que solo busca una alternativa a las respuestas válidas anteriores.

En estos casos puedes hacer:

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

Más documentación aquí: http://www.newtonsoft.com/json/help/html/CreatingLINQtoJSON.htm

Daniele D.
fuente
2

Manera simple de crear newtonsoft JObject desde Propiedades.

Esta es una muestra de propiedades de usuario

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

y quiero que esta propiedad en newtonsoft JObject sea:

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

La salida será así:

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

Tarde o temprano tendrás una propiedad con carácter especial. Puede utilizar índice o una combinación de índice y propiedad.

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
fuente
¿Cómo responde esto a la pregunta?
Enigmativity
@Enigmativity, lo que quiero decir es que puedes usar la notación de índice y la notación de propiedad juntas. es decir, obj [x] = x1; obj.y = y1 se puede usar en el mismo código. La combinación de notación de índice y palabra clave dinámica responde a las preguntas. Ninguna otra respuesta ha mencionado esto. Posiblemente, esto debería ser un comentario que una respuesta.
PAS
Simplemente creo que la pregunta es sobre no usar cuerdas mágicas, pero esta respuesta le da eso.
Enigmativity
@Enigmativity, la palabra clave dinámica simplemente engaña al compilador. Entonces no es diferente a una cadena arbitraria. el objeto de tipo dinmaico no está fuertemente tipado. Es solo un azúcar sintáctico. Si el objeto subyacente no tiene propiedad, fallará en tiempo de ejecución. pero no puede usar propiedades si el nombre de la propiedad contiene caracteres especiales, por ejemplo, 99BottlesOfBeer, espacio de nombres, It's-All-Over. Entonces, en esos casos, podemos usar propiedades indexadas. Otra respuesta le hace pensar que es una u otra, pero puede mezclar y combinar propiedad e índice.
PAS
-3

Puede usar la biblioteca Newtonsoft y usarla de la siguiente manera

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
fuente
5
en realidad no estás usando la biblioteca newtonsoft aquí
Mickey Perlstein