如何将任何对象序列化为字符串?

Rob*_*ous 7 .net c# serialization json.net

我遇到了一个问题,我的JSON序列化程序因为角色<不时出现而随机失败.我无法确定它来自何处,我想 - 在异常时 - 使用不同的方法重新编译,以便我可以看到有问题的对象的完整表示.有没有办法做到这一点?

我目前的代码:

// data is of type 'object'
serialized = JsonConvert.SerializeObject(data, new JsonSerializerSettings() {
    Error = delegate(object sender, ErrorEventArgs args) {
        // reserialize here and output object so I know what the heck is going on
    }
})
Run Code Online (Sandbox Code Playgroud)

dbc*_*dbc 18

没有万无一失的方法来序列化任何可能的c#对象.

相反,您有几种方法可以解决您的问题:

  1. 打开Json.NET跟踪.请参阅使用序列化跟踪进行调试.这应该告诉您对象图中问题发生的位置.

  2. JsonConvert.SerializeObject()如果JsonSerializer.Serialize()使用JsonTextWriter包装a 序列化并写入字符串StringWriter,则可以刷新编写器并记录部分序列化,而不是使用序列化.这可能会让人知道问题出在哪里.

  3. 您可以尝试使用各种其他序列化程序进行序列化,如果有任何工作,请记录结果.

  4. 如果您的某个对象属性抛出异常,则可能会尝试强制字段序列化.请参阅JSON.Net:强制序列化所有私有字段和子类中的所有字段.

例如,将#1,#2和#3放在一起可以得到以下方法:

public static class JsonSerializerExtensions
{
    public static string SerializeObject(object obj, JsonSerializerSettings settings = null)
    {
        settings = settings ?? new JsonSerializerSettings();

        var sb = new StringBuilder();
        using (var writer = new StringWriter(sb))
        using (var jsonWriter = new JsonTextWriter(writer))
        {
            var oldError = settings.Error;
            var oldTraceWriter = settings.TraceWriter;
            var oldFormatting = settings.Formatting;
            try
            {
                settings.Formatting = Newtonsoft.Json.Formatting.Indented;
                if (settings.TraceWriter == null)
                    settings.TraceWriter = new MemoryTraceWriter();
                settings.Error = oldError + delegate(object sender, Newtonsoft.Json.Serialization.ErrorEventArgs args)
                {
                    jsonWriter.Flush();

                    var logSb = new StringBuilder();
                    logSb.AppendLine("Serialization error: ");
                    logSb.Append("Path: ").Append(args.ErrorContext.Path).AppendLine();
                    logSb.Append("Member: ").Append(args.ErrorContext.Member).AppendLine();
                    logSb.Append("OriginalObject: ").Append(args.ErrorContext.OriginalObject).AppendLine();
                    logSb.AppendLine("Error: ").Append(args.ErrorContext.Error).AppendLine();
                    logSb.AppendLine("Partial serialization results: ").Append(sb).AppendLine();
                    logSb.AppendLine("TraceWriter contents: ").Append(settings.TraceWriter).AppendLine();

                    logSb.AppendLine("JavaScriptSerializer serialization: ");
                    try
                    {
                        logSb.AppendLine(new JavaScriptSerializer().Serialize(obj));
                    }
                    catch (Exception ex)
                    {
                        logSb.AppendLine("Failed, error: ").AppendLine(ex.ToString());
                    }

                    logSb.AppendLine("XmlSerializer serialization: ");
                    try
                    {
                        logSb.AppendLine(obj.GetXml());
                    }
                    catch (Exception ex)
                    {
                        logSb.AppendLine("Failed, error: ").AppendLine(ex.ToString());
                    }

                    logSb.AppendLine("BinaryFormatter serialization: ");
                    try
                    {
                        logSb.AppendLine(BinaryFormatterExtensions.ToBase64String(obj));
                    }
                    catch (Exception ex)
                    {
                        logSb.AppendLine("Failed, error: ").AppendLine(ex.ToString());
                    }

                    Debug.WriteLine(logSb);
                };
                var serializer = JsonSerializer.CreateDefault(settings);
                serializer.Serialize(jsonWriter, obj);
            }
            finally
            {
                settings.Error = oldError;
                settings.TraceWriter = oldTraceWriter;
                settings.Formatting = oldFormatting;
            }
        }

        return sb.ToString();
    }
}

public static class XmlSerializerExtensions
{
    public static T LoadFromXML<T>(this string xmlString)
    {
        using (StringReader reader = new StringReader(xmlString))
        {
            return (T)new XmlSerializer(typeof(T)).Deserialize(reader);
        }
    }

    public static string GetXml<T>(this T obj)
    {
        using (var textWriter = new StringWriter())
        {
            var settings = new XmlWriterSettings() { Indent = true, IndentChars = "  " };
            using (var xmlWriter = XmlWriter.Create(textWriter, settings))
                new XmlSerializer(obj.GetType()).Serialize(xmlWriter, obj);
            return textWriter.ToString();
        }
    }
}

public static class BinaryFormatterExtensions
{
    public static string ToBase64String<T>(T obj)
    {
        using (var stream = new MemoryStream())
        {
            new BinaryFormatter().Serialize(stream, obj);
            return Convert.ToBase64String(stream.GetBuffer(), 0, checked((int)stream.Length)); // Throw an exception on overflow.
        }
    }

    public static T FromBase64String<T>(string data)
    {
        return FromBase64String<T>(data, null);
    }

    public static T FromBase64String<T>(string data, BinaryFormatter formatter)
    {
        using (var stream = new MemoryStream(Convert.FromBase64String(data)))
        {
            formatter = (formatter ?? new BinaryFormatter());
            var obj = formatter.Deserialize(stream);
            if (obj is T)
                return (T)obj;
            return default(T);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

你可能会取代最后Debug.WriteLine()用适当的测井方法,然后替换JsonConvert.SerializeObject(data)JsonSerializerExtensions.SerializeObject(data)在应用程序代码.