2012-12-06 10 views
14

TL; DR: C'è un modo integrato in ServiceStack.Text per produrre JSON piuttosto stampato?ServiceStack.Text offre una buona stampa di JSON?

Sto usando ServiceStack.Text per eseguire la serializzazione JSON. Funziona davvero bene finora, ma il JSON creato (usando .ToJSON()) non è formattato con spazi bianchi o newline (molto probabilmente per risparmiare spazio quando si inviano attraverso la rete). Tuttavia, in alcune circostanze sarebbe bello avere il JSON formattato per facilitare la leggibilità umana.

Il metodo .Dump() esegue una sorta di formattazione, tuttavia non produce JSON valido (ad esempio mancano le doppie quotazioni circostanti).

risposta

8

I T.Dump() e T.PrintDump() metodi di estensione in ServiceStack.Text sono solo una versione abbastanza formattata del JSV Format che si crea con la classe TypeSerializer o T.ToJsv() metodo di estensione. È solo per fornire una copia di dati umana amichevole, non è analizzabile.

Il nuovo metodo string.IndentJson() interno disponibile da v4.5.5 vi permetterà di JSON pretty-print altrimenti è possibile installare un'estensione Abbastanza JSONView per Chrome o Firefox per vedere abbastanza JSON o si può incollare il JSON in jsonprettyprint.com

+2

Pitty, sarebbe davvero bello avere abbastanza la stampa per JSON. Non si tratta solo di visualizzare i dati personalmente durante il debug, ma, ad esempio, quando si scrive JSON in file per la memorizzazione persistente. – Dyna

+0

Certo, può essere utile, ma non a scapito del rallentamento e dell'inquinamento del percorso principale. Un processo di post-formattazione che funziona come 'T.Dump()' è migliore. Ma non qualcosa di cui ho bisogno, quindi non è una priorità per me: prima ne ho bisogno prima di implementarla :) – mythz

+3

Per qualcosa come un file di configurazione, essere in grado di leggere il documento in un editor di testo è utile, e la velocità non è è davvero un grosso problema per il caricamento di un file di configurazione. –

2

Avere un formato abbastanza json sarebbe buono dal testo del servicestack. Come soluzione alternativa perché ho creato un plug-in per formattare JSON quando ne avevo bisogno. Speriamo che una futura versione dello stack di servizio possa sbarazzarsi di questo codice.

Scarica la DLL dal link sottostante, (ti dà un metodo di estensione per formattare il JSON) http://www.markdavidrogers.com/json-pretty-printerbeautifier-library-for-net/

Ho usato questo al posto di qualcosa come json.net come ho voluto assicurarsi che non l'ho fatto cambiare la serializzazione servicestack di JSON.

Poi ho creato il codice di avvio seguente pluging

using System; 
using System.Collections.Generic; 
using System.IO; 
using System.Linq; 
using System.Text; 
using JsonPrettyPrinterPlus; 
using ServiceStack.Common.Web; 
using ServiceStack.ServiceClient.Web; 
using ServiceStack.ServiceHost; 
using ServiceStack.ServiceModel.Serialization; 
using ServiceStack.ServiceModel.Support; 
using ServiceStack.WebHost.Endpoints; 

namespace Bm.Services.Plugins 
{ 
    public class PrettyJsonFormatPlugin : IPlugin 
    { 
     public const string JsonPrettyText = "application/prettyjson"; 
     public void Register(IAppHost appHost) 
     { 
      appHost.ContentTypeFilters.Register(JsonPrettyText, 
       Serialize, 
       Deserialize); 

     } 

     public static void Serialize(IRequestContext requestContext, object dto, Stream outputStream) 
     { 
      var json = HttpResponseFilter.Instance.Serialize(ContentType.Json, dto); 

      json = json.PrettyPrintJson(); 
      byte[] bytes = Encoding.UTF8.GetBytes(json); 

      outputStream.Write(bytes, 0, bytes.Length); 
     } 

     public static object Deserialize(Type type, Stream fromStream) 
     { 
      var obj = JsonDataContractDeserializer.Instance.DeserializeFromStream(type, fromStream); 
      return obj; 
     } 

    } 

    public class PrettyJsonServiceClient : JsonServiceClient 
    { 
     public PrettyJsonServiceClient() : base() 
     { 
     } 

     public PrettyJsonServiceClient(string baseUri) : base(baseUri) 
     {   
     } 

     public PrettyJsonServiceClient(string syncReplyBaseUri, string asyncOneWayBaseUri) : base(syncReplyBaseUri, asyncOneWayBaseUri) 
     { 
     } 

     public override string Format 
     { 
      get 
      { 
       return "prettyjson"; 
      } 
     } 
    } 
} 

In te registrare il nuovo plugin

EndpointHost.AddPlugin(new PrettyJsonFormatPlugin()); 

Per chiamare un servizio di esempio da C#

var prettyJsonClient = new PrettyJsonServiceClient(HOST_URL); 
var ret = prettyJsonClient.Get<string>(@"/system/ping/test"); 

Ecco un equivilent xml one

using System; 
using System.Collections.Generic; 
using System.IO; 
using System.Linq; 
using System.Text; 
using Bm.Core; 
using JsonPrettyPrinterPlus; 
using ServiceStack.Common.Web; 
using ServiceStack.ServiceClient.Web; 
using ServiceStack.ServiceHost; 
using ServiceStack.ServiceModel.Serialization; 
using ServiceStack.ServiceModel.Support; 
using ServiceStack.WebHost.Endpoints; 

namespace Bm.Services.Plugins 
{ 
    public class PrettyXmlFormatPlugin : IPlugin 
    { 
    public const string XmlPrettyText = "application/prettyxml"; 
    public void Register(IAppHost appHost) 
    { 
     appHost.ContentTypeFilters.Register(XmlPrettyText, 
     Serialize, 
     Deserialize); 

    } 

    public static void Serialize(IRequestContext requestContext, object dto, Stream outputStream) 
    { 

     var xml = HttpResponseFilter.Instance.Serialize(ContentType.Xml, dto); 

     xml = Common.PrettyXml(xml); 
     byte[] bytes = Encoding.UTF8.GetBytes(xml); 

     outputStream.Write(bytes, 0, bytes.Length); 
    } 

    public static object Deserialize(Type type, Stream fromStream) 
    { 
     var obj = JsonDataContractDeserializer.Instance.DeserializeFromStream(type, fromStream); 
     return obj; 
    } 

    } 

    public class PrettyXmlServiceClient : XmlServiceClient 
    { 
    public PrettyXmlServiceClient() 
     : base() 
    { 
    } 

    public PrettyXmlServiceClient(string baseUri) 
     : base(baseUri) 
    { 
    } 

    public PrettyXmlServiceClient(string syncReplyBaseUri, string asyncOneWayBaseUri) 
     : base(syncReplyBaseUri, asyncOneWayBaseUri) 
    { 
    } 

    public override string Format 
    { 
     get 
     { 
     return "prettyxml"; 
     } 
    } 
    } 
} 
0

a diventare piuttosto JSON:

var formattedJson = JsvFormatter.Format(JsonSerializer.SerializeToString(dto)); 

La stringa JSON risultante può essere analizzato di nuovo:

var dto = JsonSerializer.DeserializeFromString<MyDto>(formattedJson); 
Problemi correlati