programing

개체를 문자열로 직렬화

itmemos 2023. 5. 22. 20:25
반응형

개체를 문자열로 직렬화

개체를 파일에 저장하는 방법은 다음과 같습니다.

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

제가 작성하지 않았음을 인정합니다(유형 매개 변수를 사용하는 확장 방법으로 변환했을 뿐입니다.

이제 xml을 파일에 저장하는 대신 문자열로 반환하기 위해 필요합니다.알아보고는 있지만, 아직 알아내지 못했습니다.

저는 이것이 이 물체들에 익숙한 사람에게는 정말 쉬울 것이라고 생각했습니다.만약 그렇지 않다면, 나는 결국 그것을 알아낼 것입니다.

다음 대신 를 사용합니다.

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

고하는것중다니이요합용참사다니중▁note▁to▁use▁important▁is것합요▁it를 사용하는 것은 중요합니다.toSerialize.GetType()typeof(T)첫 번째 할 경우 는 XmlSerializer의 가능한 모든 합니다.T함), (으)에서 는 (으)로 인해 합니다.T이하는 몇 예시 .XmlSerializer 던지기Exception 때에typeof(T)이 사용되는 이유는 파생 형식의 인스턴스를 파생 형식의 기본 클래스인 http://ideone.com/1Z5J1 에 정의된 SerializeObject를 호출하는 메서드에 전달하기 때문입니다.

은 코드를 Mono를 합니다; Ideone은 Mono입니다.Exception .NET 런타임을 할 수 .MessageIdeone에 표시된 것보다 훨씬 더 효과적이지만 똑같이 실패합니다.

을 직렬화 및 역직렬화(XML/JSON 파일 이름)SerializationHelper.cs):

using Newtonsoft.Json;
using System.IO;
using System.Xml.Serialization;

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

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

        public static T DeserializeJson<T>(this string toDeserialize)
        {
            return JsonConvert.DeserializeObject<T>(toDeserialize);
        }

        public static string SerializeJson<T>(this T toSerialize)
        {
            return JsonConvert.SerializeObject(toSerialize);
        }
    }
}

저는 이것이 실제로 질문에 대한 답이 아니라는 것을 압니다. 하지만 질문에 대한 투표 수와 받아들여진 답변으로 볼 때, 저는 사람들이 실제로 코드를 사용하여 물체를 문자열로 직렬화하고 있다고 의심합니다.

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}

코드 안전 참고

승인된 답변과 관련하여, 사용하는 것이 중요합니다.toSerialize.GetType()typeof(T)XmlSerializer생성자: 첫 번째 시나리오를 사용하면 코드가 모든 가능한 시나리오를 커버하는 반면, 후자를 사용하면 때때로 실패합니다.

이하는 몇 예시 .XmlSerializer▁an▁던지▁throwingtypeof(T)파생된 유형의 인스턴스를 호출하는 메서드로 전달하기 때문에 사용됩니다.SerializeObject<T>()파생된 형식의 기본 클래스인 http://ideone.com/1Z5J1 에 정의되어 있습니다.Ideone은 모노를 사용하여 코드를 실행합니다. Microsoft .NET 런타임을 사용하여 얻을 수 있는 실제 예외는 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();
    }
}

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

저는 이 조작된 코드를 승인된 답변에 공유할 필요가 있다고 느꼈습니다. 저는 평판이 없기 때문에 논평할 수 없습니다.

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

xhafan이 제안한 JSONConvert 방법을 사용할 수 없었습니다.

.Net 4.5에서 "시스템"을 추가한 후에도.Web.Extensions" 어셈블리 참조 JSONConvert에 여전히 액세스할 수 없습니다.

그러나 참조를 추가하면 다음을 사용하여 동일한 문자열을 인쇄할 수 있습니다.

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

경우에 따라 고유한 문자열 직렬화를 구현할 수도 있습니다.

하지만 여러분이 무엇을 하고 있는지 알지 못하는 한 그것은 아마도 나쁜 생각일 것입니다.(예: 배치 파일로 I/O 직렬화)

그런 식으로 하면 손으로 쉽게 편집할 수 있지만, 해당 이름에 새 줄이 포함되어 있지 않은 것처럼 몇 가지 검사를 더 수행해야 합니다.

public string name {get;set;}
public int age {get;set;}

Person(string serializedPerson) 
{
    string[] tmpArray = serializedPerson.Split('\n');
    if(tmpArray.Length>2 && tmpArray[0].Equals("#")){
        this.name=tmpArray[1];
        this.age=int.TryParse(tmpArray[2]);
    }else{
        throw new ArgumentException("Not a valid serialization of a person");
    }
}

public string SerializeToString()
{
    return "#\n" +
           name + "\n" + 
           age;
}

[VB]

Public Function XmlSerializeObject(ByVal obj As Object) As String

    Dim xmlStr As String = String.Empty

    Dim settings As New XmlWriterSettings()
    settings.Indent = False
    settings.OmitXmlDeclaration = True
    settings.NewLineChars = String.Empty
    settings.NewLineHandling = NewLineHandling.None

    Using stringWriter As New StringWriter()
        Using xmlWriter__1 As XmlWriter = XmlWriter.Create(stringWriter, settings)

            Dim serializer As New XmlSerializer(obj.[GetType]())
            serializer.Serialize(xmlWriter__1, obj)

            xmlStr = stringWriter.ToString()
            xmlWriter__1.Close()
        End Using

        stringWriter.Close()
    End Using

    Return xmlStr.ToString
End Function

Public Function XmlDeserializeObject(ByVal data As [String], ByVal objType As Type) As Object

    Dim xmlSer As New System.Xml.Serialization.XmlSerializer(objType)
    Dim reader As TextReader = New StringReader(data)

    Dim obj As New Object
    obj = DirectCast(xmlSer.Deserialize(reader), Object)
    Return obj
End Function

[C#]

public string XmlSerializeObject(object obj)
{
    string xmlStr = String.Empty;
    XmlWriterSettings settings = new XmlWriterSettings();
    settings.Indent = false;
    settings.OmitXmlDeclaration = true;
    settings.NewLineChars = String.Empty;
    settings.NewLineHandling = NewLineHandling.None;

    using (StringWriter stringWriter = new StringWriter())
    {
        using (XmlWriter xmlWriter = XmlWriter.Create(stringWriter, settings))
        {
            XmlSerializer serializer = new XmlSerializer( obj.GetType());
            serializer.Serialize(xmlWriter, obj);
            xmlStr = stringWriter.ToString();
            xmlWriter.Close();
        }
    }
    return xmlStr.ToString(); 
}

public object XmlDeserializeObject(string data, Type objType)
{
    XmlSerializer xmlSer = new XmlSerializer(objType);
    StringReader reader = new StringReader(data);

    object obj = new object();
    obj = (object)(xmlSer.Deserialize(reader));
    return obj;
}

언급URL : https://stackoverflow.com/questions/2434534/serialize-an-object-to-string

반응형