简体   繁体   English

如何将异常序列化为 Json

[英]How to serialise Exception to Json

C# Exceptions are ISerialisable so they can't also be DataContracts so I can't use JsonDataContractSerializer. C# 异常是可序列化的,所以它们也不能是 DataContracts,所以我不能使用 JsonDataContractSerializer。

What are alternatives to serialising Exceptions to JSON?将异常序列化为 JSON 的替代方法是什么?

Since this has not really been answered yet: Just create a Dictionary containing the error properties you want, serialize it using JSON.NET and put it into a HttpResponseMessage :由于这还没有真正得到回答:只需创建一个包含所需错误属性的字典,使用 JSON.NET 对其进行序列化并将其放入HttpResponseMessage

catch (Exception e)
{
    var error = new Dictionary<string, string>
    {
        {"Type", e.GetType().ToString()},
        {"Message", e.Message},
        {"StackTrace", e.StackTrace}
    };

    foreach (DictionaryEntry data in e.Data)
        error.Add(data.Key.ToString(), data.Value.ToString());

    string json = JsonConvert.SerializeObject(error, Formatting.Indented);

    HttpResponseMessage response = new HttpResponseMessage();
    response.Content = new StringContent(json);

    return response;
}

I hope this can help some people out.我希望这可以帮助一些人。

This is the solution that I use in my projects that has some desired plus (IMHO):这是我在我的项目中使用的解决方案,它有一些期望的优势(恕我直言):

  • Pretty clean JSON format非常干净的 JSON 格式
  • Recursive dumping of the inner exceptions内部异常的递归转储
using System.Text.Json.Serialization;

namespace MyAwesomeroject.Shared.Utils;

public static class ExceptionExtensions
{
    public class ExceptionInfo
    {
        public ExceptionInfo() { }

        internal ExceptionInfo(Exception exception, bool includeInnerException = true, bool includeStackTrace = false)
        {
            if (exception is null)
            {
                throw new ArgumentNullException(nameof(exception));
            }

            Type = exception.GetType().FullName;
            Message = exception.Message;
            Source = exception.Source;
            StackTrace = includeStackTrace ? exception.StackTrace : null;
            if (includeInnerException && exception.InnerException is not null)
            {
                InnerException = new ExceptionInfo(exception.InnerException, includeInnerException, includeStackTrace);
            }
        }

        public string Type { get; set; }
        public string Message { get; set; }
        public string Source { get; set; }
        public string StackTrace { get; set; }
        public ExceptionInfo InnerException { get; set; }
    }

    private static readonly JsonSerializerOptions _defaultJsonSerializerOptions = new()
    {
        DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
        WriteIndented = true,
    };

    /// <summary>
    /// Serialize the <see cref="Exception"/> to a JSON string.
    /// </summary>
    /// <param name="ex">The exception</param>
    /// <param name="includeInnerException">Control if to include inner exception</param>
    /// <param name="includeStackTrace">Control if to include stack trace</param>
    /// <param name="options">JSON options. By default nulls are not serialized and the string is indented</param>
    /// <returns></returns>
    public static string ToJson(
        this Exception ex,
        bool includeInnerException = true,
        bool includeStackTrace = false,
        JsonSerializerOptions options = null)
    {
        ArgumentNullException.ThrowIfNull(ex);
        var info = new ExceptionInfo(ex, includeInnerException, includeStackTrace);
        
        return JsonSerializer.Serialize(info, options ?? _defaultJsonSerializerOptions);
    }
}

That produces outputs like this:这会产生如下输出:

{
  "Type": "System.InvalidOperationException",
  "Message": "MyMessage",
  "Source": "MySource",
  "InnerException": {
    "Type": "System.ArgumentException",
    "Message": "MyInnerMessage",
    "Source": "MyAwesomeProject.Utils.Tests",
    "StackTrace": "   at MyAwesomeProject.Utils.Tests.ExceptionExtensionsTests.ShouldInclude_StackTrace_if_required() in /Users/jc/git/MyAwesomeProject/tests/Shared/Utils/ExceptionExtensionsTests.cs:line 41"
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM