设置堆栈跟踪格式以手动返回 API 响应

use*_*346 5 c# asp.net-mvc .net-core

目前,它返回一个难以理解的块,由多个这些东西粘在一起组成,如下所示:

在 C:\\Repositories\\projectx\\src\\ProyectX.Services\\Service.cs 中的 ProyectX.Services.Service.Validate(IList 1 myParam):第 116 行\r\n 在 ProyectX.Services.Service.Validate (IList 1 myParam) 在 C:\\Repositories\\projectx\\src\\ProyectX.Services\\Service.cs:第 116 行\r\n

目标:

在 C:\Repositories\projectx\src\ProyectX.Services\Service.cs 中的 ProyectX.Services.Service.Validate(IList 1 myParam):第 116 行

在 C:\Repositories\projectx\src\ProyectX.Services\Service.cs 中的 ProyectX.Services.Service.Validate(IList 1 myParam):第 116 行

我尝试过

Regex.Unescape(exception.StackTrace)

JsonSerializer.Serialize(exception.StackTrace, new JsonSerializerOptions() {WriteIndented = true });
Run Code Online (Sandbox Code Playgroud)

中间件位于Startup.cs中

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseMiddleware<ErrorHandlerMiddleware>();
Run Code Online (Sandbox Code Playgroud)

中间件:

using System;
using System.Collections.Generic;
using System.Net;
using System.Text.Json;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Hosting;
using ProyectX.Domain.Exceptions;
using ProyectX.Domain.Models;

namespace ProyectX.API.Middleware
{
    public class ErrorHandlerMiddleware
    {
        private readonly RequestDelegate _next;

        public ErrorHandlerMiddleware(RequestDelegate next)
        {
            _next = next;
        }

        public async Task Invoke(HttpContext context, IWebHostEnvironment env)
        {
            try
            {
                await _next(context);
            }
            catch (Exception exception)
            {
                var response = context.Response;
                response.ContentType = "application/json";

                switch (exception)
                {
                    case InvalidOperationException:
                        response.StatusCode = (int)HttpStatusCode.BadRequest;
                        break;
                    default:
                        response.StatusCode = (int)HttpStatusCode.InternalServerError;
                        break;
                }

                var details = new Dictionary<string, string>
                {
                    { "Message", exception.Message },
                };

                if (env.IsDevelopment())
                {
                    details.Add("StackTrace", exception.StackTrace);
                }

                var errorResponse = new ErrorResponseModel(exception, details);
                var result = JsonSerializer.Serialize(errorResponse);

                await response.WriteAsync(result);
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

错误响应模型

using System;
using System.Collections.Generic;

namespace ProyectX.Domain.Models
{
    public class ErrorResponseModel
    {
        public ErrorResponseModel(Exception ex, Dictionary<string, string> details)
        {
            Type = ex.GetType().Name;
            Details = details;
        }

        public string Type { get; set; }

        public IDictionary<string, string> Details { get; set; }
    }
}
Run Code Online (Sandbox Code Playgroud)

may*_*ʎɐɯ 4

我建议您对ErrorResponseModel类进行更改,以便您的字典接受对象类型作为值,例如Dictionary<string, object>. 这里的想法是,对于对象类型,字典值可以接受添加字符串或字符串数​​组。

因此,对于您的StackTrace,您可以使用 split by "\r\n" 将其拆分为多行,并获取它的字符串数组,我可以将其传递给我的StackTrace值。

那么让我们来看看你的模型:

public class ErrorResponseModel
{
    public ErrorResponseModel(Exception ex, Dictionary<string, object> details)
    {
        Type = ex.GetType().Name;
        Details = details;
    }

    public string Type { get; set; }

    public IDictionary<string, object> Details { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

这是处理异常的部分:

var details = new Dictionary<string, object>
{
    { "Message", exception.Message} ,
};

var lines = exception.StackTrace?.Split("\r\n").Select(e => e.TrimStart());
details.Add("StackTrace", lines);

var errorResponse = new ErrorResponseModel(exception, details);

var result = JsonSerializer.Serialize(errorResponse, new JsonSerializerOptions() { WriteIndented = true });
Run Code Online (Sandbox Code Playgroud)

所有这些都会返回以下结果:

在此输入图像描述