Czy istnieje sposób .NET 2.0 (C#) do serializacji obiektu, podobnie jak przy użyciu XmlSerializer w prostym/dostosowywalnym formacie czytelnym dla człowieka, który wygląda na przykład na PXLS lub JSON? Też wiem, że XML jest czytelny dla człowieka, szukam czegoś z mniej irytującą redundancją, coś, co możesz wyprowadzić na konsolę jako wynik dla użytkownika.Serialize w czytelnym dla człowieka formacie tekstowym
Odpowiedz
do serializacji do JSON w .NET to zrobić w następujący sposób:
public static string ToJson(IEnumerable collection)
{
DataContractJsonSerializer ser = new DataContractJsonSerializer(collection.GetType());
string json;
using (MemoryStream m = new MemoryStream())
{
XmlDictionaryWriter writer = JsonReaderWriterFactory.CreateJsonWriter(m);
ser.WriteObject(m, collection);
writer.Flush();
json = Encoding.Default.GetString(m.ToArray());
}
return json;
}
Element zbiory muszą mieć atrybut „DataContract”, a każdy członek chcesz być szeregowane do JSON musi mieć " DataMember "attibute.
Jest możliwe, że działa to tylko dla .NET 3.5. Ale jest równie prosta wersja 2.0 aswell ...
Wbudowane opcje serializacji dla .Net to Xml, Xml-Soap i plik binarny. Ponieważ wykluczyłeś xml i plik binarny z pewnością nie jest czytelny dla człowieka, musisz przetworzyć własny.
Podczas toczenia własne, masz kilka opcji:
- dodać metody użyteczne lub rozszerzeniem do klasy, jak AviewAnew zasugerował
- Extend System.Runtime.Serialization.Formatter/Wdrażanie System.Runtime. Serialization.IFormatter
- Znajdź ogólny komponent online przez Google, który zrobi to, co chcesz.
Należy pamiętać, że druga pozycja może być wyspecjalizowana dla danej klasy (nie musi być w stanie obsłużyć żadnej klasy, jeśli jej nie chcesz), a dwie ostatnie pozycje nie wykluczają się wzajemnie .
Szukałem formatera .NET JSON w przeszłości i na pewno istnieje wiele opcji. Jednak tym razem skończyłem w innym kierunku. Po prostu nie czułem się pewnie w żadnym z nich. Może ktoś inny może dostarczyć bardziej szczegółowe zalecenie. JSON staje się na tyle duży, że wkrótce Microsoft włączy do niego "natywne" wsparcie w ramach.
Mógłbym napisać własny HumanSerializer że odzwierciedla typ obiektu, które zostały podane do niego - ale to zużywają zbyt dużo czasu. Myślałem, że już wcześniej może być ktoś, kto rozwiązał ten problem - ale google go nie znalazło. – Martin
znalazłem exaustive dokumentację tutaj:
z tej klasy modified (rodzajowych wsparcia)
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
public class JSONHelper
{
public static string Serialize<T>(T obj)
{
DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType());
MemoryStream ms = new MemoryStream();
serializer.WriteObject(ms, obj);
string retVal = Encoding.Default.GetString(ms.ToArray());
ms.Dispose();
return retVal;
}
public static T Deserialize<T>(string json)
{
T obj = Activator.CreateInstance<T>();
MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(json));
DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType());
obj = (T)serializer.ReadObject(ms);
ms.Close();
ms.Dispose();
return obj;
}
}
Co z czytelnym dla człowieka formatem tekstu ? – MajesticRa
Użycie 'Encoding.Default' nie działa dla tekstu innego niż ASCII, ponieważ (nieudokumentowana) implementacja' DataContractJsonSerializer.WriteObject' używa zakodowanego na sztywno 'Encoding.UTF8'. – mrexodia
https://stackoverflow.com/a/38538454/6627992
Możesz użyć następującej standardowej metody uzyskiwania sformatowanego Json
JsonReaderWriterFactory.CreateJsonWriter (strumień Stream, kodowanie Kodowanie, bool ownsStream, bool tiret indentChars String)
Tylko ustawić "wcięcie == true"
Spróbuj coś takiego
public readonly DataContractJsonSerializerSettings Settings =
new DataContractJsonSerializerSettings
{ UseSimpleDictionaryFormat = true };
public void Keep<TValue>(TValue item, string path)
{
try
{
using (var stream = File.Open(path, FileMode.Create))
{
var currentCulture = Thread.CurrentThread.CurrentCulture;
Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
try
{
using (var writer = JsonReaderWriterFactory.CreateJsonWriter(
stream, Encoding.UTF8, true, true, " "))
{
var serializer = new DataContractJsonSerializer(type, Settings);
serializer.WriteObject(writer, item);
writer.Flush();
}
}
catch (Exception exception)
{
Debug.WriteLine(exception.ToString());
}
finally
{
Thread.CurrentThread.CurrentCulture = currentCulture;
}
}
}
catch (Exception exception)
{
Debug.WriteLine(exception.ToString());
}
}
zwrócić uwagę do linii
var currentCulture = Thread.CurrentThread.CurrentCulture;
Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
....
Thread.CurrentThread.CurrentCulture = currentCulture;
należy użyć InvariantCulture, aby uniknąć wyjątków podczas deserializacji na komputerach z różnymi ustawieniami regionalnymi. Na przykład niepoprawny format double lub DateTime czasami je powoduje.
Na deserializacji
public TValue Revive<TValue>(string path, params object[] constructorArgs)
{
try
{
using (var stream = File.OpenRead(path))
{
var currentCulture = Thread.CurrentThread.CurrentCulture;
Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
try
{
var serializer = new DataContractJsonSerializer(type, Settings);
var item = (TValue) serializer.ReadObject(stream);
if (Equals(item, null)) throw new Exception();
return item;
}
catch (Exception exception)
{
Debug.WriteLine(exception.ToString());
return (TValue) Activator.CreateInstance(type, constructorArgs);
}
finally
{
Thread.CurrentThread.CurrentCulture = currentCulture;
}
}
}
catch
{
return (TValue) Activator.CreateInstance(typeof (TValue), constructorArgs);
}
}
Dzięki!
Zastosuj XSL do xml, aby usunąć to, czego nie chcesz zobaczyć?
coś
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="text" indent="yes"/>
<xsl:template match="*">
<xsl:value-of select="name()" /><xsl:text>
</xsl:text>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates select="*"/>
</xsl:template>
<xsl:template match="@*|text()|comment()|processing-instruction">
<xsl:value-of select="name()" />:<xsl:value-of select="." /><xsl:text>
</xsl:text>
</xsl:template>
</xsl:stylesheet>
Kilka minut temu przy użyciu [Json.NET] (http://www.codeplex.com/Json) dowiedziałem się, że JSON nie jest najlepszym sposobem, aby to zrobić, ponieważ nie obsługuje Enums. Rezultatem jest liczba, która nie jest czytelna dla ludzi. – Martin
Okej, cóż, implementacja zależy od tego, co serializujesz. Jeśli jest to tylko jeden typ z kilkoma członkami, dlaczego nie wystarczy przesłonić "ToString" i zwrócić ciąg.Format w dowolnym formacie, który chcesz – ullmark