WebApi无法序列化派生类在Exception中声明的属性

时间:2017-05-29 00:33:57

标签: c# asp.net-web-api2

在调用Get api方法时,我无法获取在BaseException上创建的属性值。知道为什么吗?

public class BaseException : Exception
{
    public  string ExType { get; set; }

    public JObject Properties { get; set; }

    public Guid ErrorCodeId { get; set; }

    public BaseException(string message): base(message) { }
}

public class BadRequestException : BaseException
{
    public BadRequestException(string message) : base(message) { }
}

// GET: api/<controller>
public virtual IHttpActionResult Get()
{
    IHttpActionResult result = null;
    try
    {
        throw new Exception("Error description here");
        result = Ok();
    }
    catch (Exception ex)
    {
        result = ResponseMessage(Request.CreateResponse(HttpStatusCode.BadRequest, new BadRequestException(ex.Message)
        {
            ExType = "Any exception type"//Can't get this value in the output JSON
        }));
    }
    return result;
}

未显示ExType值。我得到的结果如下:

{
  "ClassName": "BadRequestException",
  "Message": "Error description here",
  "Data": null,
  "InnerException": null,
  "HelpURL": null,
  "StackTraceString": null,
  "RemoteStackTraceString": null,
  "RemoteStackIndex": 0,
  "ExceptionMethod": null,
  "HResult": -2146233088,
  "Source": null,
  "WatsonBuckets": null
}

有什么方法可以获得我自己的属性的实现价值吗?

1 个答案:

答案 0 :(得分:0)

关于这个答案What is the correct way to make a custom .NET Exception serializable?

在从Exception序列化自定义继承类的对象时,需要显式添加新属性。 为此,我们应该覆盖 GetObjectData 方法,并将所有要序列化的属性和值放入信息中。

public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
    base.GetObjectData(info, context);
}

很好,所以要自动化,我们可以使用如下反射

public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
    //Getting first from base
    base.GetObjectData(info, context);

    if (info != null)
    {
        foreach (PropertyInfo property in this.GetType().GetProperties())
        {
            //Adding only properties that not already declared on Exception class
            if (property.DeclaringType.Name != typeof(Exception).Name)
            {
                info.AddValue(property.Name, property.GetValue(this));
            }
        }
    }
}

然后在输出中序列化所有自定义属性。