web-dev-qa-db-ja.com

オブジェクトを文字列にシリアル化する

オブジェクトをファイルに保存するには、次の方法があります。

// Save an object out to the disk
public static void SerializeObject<T>(this T toSerialize, String filename)
{
    XmlSerializer xmlSerializer = new XmlSerializer(toSerialize.GetType());
    TextWriter textWriter = new StreamWriter(filename);

    xmlSerializer.Serialize(textWriter, toSerialize);
    textWriter.Close();
}

私はそれを書いていないことを私は告白します(私はtypeパラメータを取る拡張メソッドに変換しただけです)。

今度は(ファイルに保存するのではなく)文字列としてxmlを返すようにする必要があります。私はそれを調べています、しかし私はまだそれを考え出していません。

私はこれがこれらのオブジェクトに精通している人にとって本当に簡単かもしれないと思いました。そうでなければ、私は最終的にそれを理解するでしょう。

280
Vaccano

StringWriterNAME _ の代わりに StreamWriterNAME _ を使用します。

public static string SerializeObject<T>(this T toSerialize)
{
    XmlSerializer xmlSerializer = new XmlSerializer(toSerialize.GetType());

    using(StringWriter textWriter = new StringWriter())
    {
        xmlSerializer.Serialize(textWriter, toSerialize);
        return textWriter.ToString();
    }
}

XmlSerializerコンストラクターでtoSerialize.GetType()の代わりにtypeof(T)を使用することが重要です:最初のものを使用する場合、コードはTname__のすべての可能なサブクラス(メソッドに対して有効)をカバーしますが、後者は派生型を渡すときに失敗しますTname__から。派生型のインスタンスを派生型の基本クラスで定義されているSerializeObjectを呼び出すメソッドに渡すため、typeof(T)が使用されているときにXmlSerializername__がExceptionname__をスローして、このステートメントを動機付けるコード例のリンクを次に示します。 http://ideone.com/1Z5J1

また、IdeoneはMonoを使用してコードを実行します。 Microsoft .NETランタイムを使用して取得する実際のExceptionname__には、Ideoneに表示されるものとは異なるMessagename__がありますが、同じように失敗します。

490
dtb

これは実際には質問に対する回答ではないことがわかっていますが、質問に対する投票数と受け入れられた回答に基づいて、人々は実際にコードを使用してオブジェクトを文字列に直列化しています。

XMLシリアライゼーションを使用すると、不要な余分なテキストのゴミが出力に追加されます。

次のクラス

public class UserData
{
    public int UserId { get; set; }
}

それは生成します

<?xml version="1.0" encoding="utf-16"?>
<UserData xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <UserId>0</UserId>
</UserData>

もっと良い解決法はJSONシリアライゼーションを使うことです(最も良い方法の一つは Json.NET です)。オブジェクトをシリアル化するには:

var userData = new UserData {UserId = 0};
var userDataString = JsonConvert.SerializeObject(userData);

オブジェクトを逆シリアル化するには:

var userData = JsonConvert.DeserializeObject<UserData>(userDataString);

直列化されたJSON文字列は次のようになります。

{"UserId":0}
67
xhafan

シリアライズおよびデシリアライズ

    public static T Deserialize<T>(this string toDeserialize)
    {
        XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
        using(StringReader textReader = new StringReader(toDeserialize))
        {      
            return (T)xmlSerializer.Deserialize(textReader);
        }
    }

    public static string Serialize<T>(this T toSerialize)
    {
        XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
        using(StringWriter textWriter = new StringWriter())
        {
            xmlSerializer.Serialize(textWriter, toSerialize);
            return textWriter.ToString();
        }
    }
54
ADM-IT

コードの安全上の注意

受け入れられた答え に関して、XmlSerializerコンストラクターでtoSerialize.GetType()の代わりにtypeof(T)を使用することが重要です。最初のコンストラクターを使用する場合、コードはすべての可能なシナリオをカバーします。後者の使用は時々失敗します。

typeof(T)を使用するときにXmlSerializerが例外をスローする、このステートメントを動機付けるコード例のリンクを次に示します。これは、SerializeObject<T>()を呼び出すメソッドに派生型のインスタンスを渡すためです。これは、派生型の基本クラスで定義されています: http://ideone.com/1Z5J1IdeoneはMonoを使用してコードを実行することに注意してください:Microsoft .NETランタイムを使用して取得する実際の例外には、Ideoneに表示されるものとは異なるメッセージがありますが、同じように失敗します。

Ideone(コードを投稿した場所)が将来利用できなくなった場合に備えて、完全を期すために、今後の参照用に完全なコードサンプルをここに投稿します。

using System;
using System.Xml.Serialization;
using System.IO;

public class Test
{
    public static void Main()
    {
        Sub subInstance = new Sub();
        Console.WriteLine(subInstance.TestMethod());
    }

    public class Super
    {
        public string TestMethod() {
            return this.SerializeObject();
        }
    }

    public class Sub : Super
    {
    }
}

public static class TestExt {
    public static string SerializeObject<T>(this T toSerialize)
    {
        Console.WriteLine(typeof(T).Name);             // PRINTS: "Super", the base/superclass -- Expected output is "Sub" instead
        Console.WriteLine(toSerialize.GetType().Name); // PRINTS: "Sub", the derived/subclass

        XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
        StringWriter textWriter = new StringWriter();

        // And now...this will throw and Exception!
        // Changing new XmlSerializer(typeof(T)) to new XmlSerializer(subInstance.GetType()); 
        // solves the problem
        xmlSerializer.Serialize(textWriter, toSerialize);
        return textWriter.ToString();
    }
}
37
Fulvio

私の2p ...

        string Serialise<T>(T serialisableObject)
        {
            var xmlSerializer = new XmlSerializer(serialisableObject.GetType());

            using (var ms = new MemoryStream())
            {
                using (var xw = XmlWriter.Create(ms, 
                    new XmlWriterSettings()
                        {
                            Encoding = new UTF8Encoding(false),
                            Indent = true,
                            NewLineOnAttributes = true,
                        }))
                {
                    xmlSerializer.Serialize(xw,serialisableObject);
                    return Encoding.UTF8.GetString(ms.ToArray());
                }
            }
        }
10
oPless
public static string SerializeObject<T>(T objectToSerialize)
        {
            System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bf = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
            MemoryStream memStr = new MemoryStream();

            try
            {
                bf.Serialize(memStr, objectToSerialize);
                memStr.Position = 0;

                return Convert.ToBase64String(memStr.ToArray());
            }
            finally
            {
                memStr.Close();
            }
        }

        public static T DerializeObject<T>(string objectToDerialize)
        {
            System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bf = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
            byte[] byteArray = Convert.FromBase64String(objectToDerialize);
            MemoryStream memStr = new MemoryStream(byteArray);

            try
            {
                return (T)bf.Deserialize(memStr);
            }
            finally
            {
                memStr.Close();
            }
        }
4
teapeng

Xhafanが提案しているJSONConvertメソッドを使用できませんでした

.Net 4.5では、 "System.Web.Extensions"アセンブリ参照を追加した後も、JSONConvertにアクセスできませんでした。

ただし、参照を追加すると、次のようにして同じ文字列をプリントアウトできます。

JavaScriptSerializer js = new JavaScriptSerializer();
string jsonstring = js.Serialize(yourClassObject);
1
Thomas Tiveron

私はこの改ざんされたコードを受け入れられた答えと共有する必要があるように感じました - 評判がないので、私はコメントすることができません..

using System;
using System.Xml.Serialization;
using System.IO;

namespace ObjectSerialization
{
    public static class ObjectSerialization
    {
        // THIS: (C): https://stackoverflow.com/questions/2434534/serialize-an-object-to-string
        /// <summary>
        /// A helper to serialize an object to a string containing XML data of the object.
        /// </summary>
        /// <typeparam name="T">An object to serialize to a XML data string.</typeparam>
        /// <param name="toSerialize">A helper method for any type of object to be serialized to a XML data string.</param>
        /// <returns>A string containing XML data of the object.</returns>
        public static string SerializeObject<T>(this T toSerialize)
        {
            // create an instance of a XmlSerializer class with the typeof(T)..
            XmlSerializer xmlSerializer = new XmlSerializer(toSerialize.GetType());

            // using is necessary with classes which implement the IDisposable interface..
            using (StringWriter stringWriter = new StringWriter())
            {
                // serialize a class to a StringWriter class instance..
                xmlSerializer.Serialize(stringWriter, toSerialize); // a base class of the StringWriter instance is TextWriter..
                return stringWriter.ToString(); // return the value..
            }
        }

        // THIS: (C): VPKSoft, 2018, https://www.vpksoft.net
        /// <summary>
        /// Deserializes an object which is saved to an XML data string. If the object has no instance a new object will be constructed if possible.
        /// <note type="note">An exception will occur if a null reference is called an no valid constructor of the class is available.</note>
        /// </summary>
        /// <typeparam name="T">An object to deserialize from a XML data string.</typeparam>
        /// <param name="toDeserialize">An object of which XML data to deserialize. If the object is null a a default constructor is called.</param>
        /// <param name="xmlData">A string containing a serialized XML data do deserialize.</param>
        /// <returns>An object which is deserialized from the XML data string.</returns>
        public static T DeserializeObject<T>(this T toDeserialize, string xmlData)
        {
            // if a null instance of an object called this try to create a "default" instance for it with typeof(T),
            // this will throw an exception no useful constructor is found..
            object voidInstance = toDeserialize == null ? Activator.CreateInstance(typeof(T)) : toDeserialize;

            // create an instance of a XmlSerializer class with the typeof(T)..
            XmlSerializer xmlSerializer = new XmlSerializer(voidInstance.GetType());

            // construct a StringReader class instance of the given xmlData parameter to be deserialized by the XmlSerializer class instance..
            using (StringReader stringReader = new StringReader(xmlData))
            {
                // return the "new" object deserialized via the XmlSerializer class instance..
                return (T)xmlSerializer.Deserialize(stringReader);
            }
        }

        // THIS: (C): VPKSoft, 2018, https://www.vpksoft.net
        /// <summary>
        /// Deserializes an object which is saved to an XML data string.
        /// </summary>
        /// <param name="toDeserialize">A type of an object of which XML data to deserialize.</param>
        /// <param name="xmlData">A string containing a serialized XML data do deserialize.</param>
        /// <returns>An object which is deserialized from the XML data string.</returns>
        public static object DeserializeObject(Type toDeserialize, string xmlData)
        {
            // create an instance of a XmlSerializer class with the given type toDeserialize..
            XmlSerializer xmlSerializer = new XmlSerializer(toDeserialize);

            // construct a StringReader class instance of the given xmlData parameter to be deserialized by the XmlSerializer class instance..
            using (StringReader stringReader = new StringReader(xmlData))
            {
                // return the "new" object deserialized via the XmlSerializer class instance..
                return xmlSerializer.Deserialize(stringReader);
            }
        }
    }
}
0