如何在ASP.NET应用程序中序列化我的异常?

时间:2016-05-03 07:13:28

标签: c# asp.net json asp.net-web-api

这是我到目前为止所尝试的内容:

 public async Task<IHttpActionResult> Post([FromBody]Word word)
    {
        try
        {
            db.Words.Add(word);

            await db.SaveChangesAsync(User, DateTime.UtcNow);
            return Ok(word);
        }
        catch (Exception ex)
        {
            return BadRequest(new JavaScriptSerializer().Serialize(ex));
        }
    }

当我尝试序列化时,我收到以下错误:

  

{&#34; message&#34;:&#34;发生了错误。&#34;,&#34; exceptionMessage&#34;:&#34;一个通告   序列化类型的对象时检测到引用   。&#39; Entities.Models.Core.Word&#39;&#34;&#34; exceptionType&#34;:&#34; System.InvalidOperationException&#34;&#34;堆栈跟踪&#34;:& #34;   在......

我想返回ex.Message和InnerException。但是,我不知道是否会有一个或多个内部异常。

2 个答案:

答案 0 :(得分:1)

从你的expcetion问题是你试图保存Entities.Models.Core.Word的对象,它可能有其他东西的参考,你正在使用延迟加载。因此,当序列化程序尝试对您的对象进行串行分析时,它会失败 解决这个问题的方法很少。

在application_start中的global.asax中添加

GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;

第二个选项不是将所有内容序列化,而是根据你的需要进行序列化

return BadRequest(new JavaScriptSerializer().Serialize(new
            {
                ex.Message,
                ex.StackTrace
            }));

答案 1 :(得分:1)

我通常使用辅助函数处理Web API项目中的异常处理。我将作为参数抛出的异常传递给它,然后返回一个HttpResponseException并抛出它。

抛出的异常将自动序列化为Http动词函数的返回类型。在我的示例中,我返回一个Task,因为它将任何.Net类型序列化为通用对象。

如果您查看下面的示例,您会看到我有一个名为Get的方法,其返回类型设置为Task。如果前端应用程序执行HTTP GET(在您的情况下为POST)并且Accept标头设置为&#39; application / json&#39;,当方法返回时,对象类型将被序列化为JSON。 ll将任务的返回类型序列化为json。这也适用于text / xml的Accept类型。

我建议您在帮助方法中过滤特定数据。你可能不希望人们消费你的API来获得完整的堆栈跟踪等等,但显然这符合你的要求。

public async Task<Object> Get()
{
    object result = null;
    try
    {
        result = await methodThatThrowsException();
    }
    catch (Exception ex)
    {
        throw CreateHttpResponseException(ex);
    }
        return result;
}

帮手方法

private HttpResponseException CreateHttpResponseException(Exception ex)
{
    HttpResponseMessage message;
    if (ex.GetType() == typeof(FaultException<LoginFault>))
    {
        message = new HttpResponseMessage(HttpStatusCode.Forbidden);
    }
    else
    {
        message = new HttpResponseMessage(HttpStatusCode.InternalServerError);
    }

    message.Content = new StringContent(ex.Message);
    return new HttpResponseException(message);
}

在帮助器方法中,使用StringBuilder构建要在前端显示的内容。根据需要连接并格式化错误消息,然后将字符串值分配给MessageResponseMessage.Content字段。

您需要迭代Exception InnerException并检查它是否为null,连接异常消息等......如您所示。

您可以使用类似

的内容迭代内部异常
StringBuilder exceptionMessage = new StringBuilder();
Exception inner = ex.InnerException;
while (inner != null)
{
    exceptionMessage.Append(inner.Message)
                    .Append(Environment.NewLine);
    inner = inner.InnerException;
}