c# - Angular:无法通过 HttpResponse 返回自定义错误消息

标签 c# angular asp.net-core angular-http-interceptors asp.net-core-middleware

我一直在谷歌上搜索解决方法,并看到了当我们在 controller action 中返回错误文本作为 ActionResult/JsonResult 或使用 HttpRequest 方法如下

HttpContext.Current.Response.Status = "error text";

对于我的后端应用程序,我使用 ASP.NET Core 2.1.1 并且 .Status 属性在 HttpResponse 类中丢失。

此外,我找不到任何可能包含我的自定义错误消息的属性。

我使用中间件类获取异常描述并将其作为 JSON 传递

Startup.cs

app.UseMiddleware<ExceptionHandleMiddleware>();

类本身

public class ExceptionHandleMiddleware
{
    private readonly RequestDelegate next;

    public ExceptionHandleMiddleware(RequestDelegate next)
    {
        this.next = next ?? throw new ArgumentNullException(nameof(next));
    }

    public async Task Invoke(HttpContext context)
    {
        try
        {
            await next(context);
        }
        catch (Exception ex)
        {
            context.Response.Clear();
            context.Response.Headers.Add("Access-Control-Allow-Origin", "*");
            context.Response.ContentType = "application/json";
            context.Response.StatusCode = StatusCodes.Status500InternalServerError;

            await context.Response.WriteAsync(JsonConvert.SerializeObject(new { error = $"{ex.GetType().FullName}: '{ex.Message}'" }));
        }
    }
}

看看这条线

context.Response.StatusCode = StatusCodes.Status500InternalServerError;

这是必需的,因为在我的 Angular 6 应用程序 中,我使用了 HttpInterceptor,为了捕获错误,您应该返回一个 HTTP 错误(否则 .catch(...) block 未在 Angular 拦截器中触发)。

这是我的 Angular 应用程序的一部分

@Injectable()
export class ErrorHandlerInterceptor implements HttpInterceptor {

    constructor(
        private notify: NgNotify,
    ) { }

    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        return next
            .handle(req)
            .catch(this.handleError)
    }
    ...

尽管 context.Response.WriteAsync(...)确实返回 异常文本,但我无法在 .catch(.. .) 拦截器 block 。

public handleError = (error: Response) => {

这是打印为 JSONerror(请注意,它缺少显示 “最后一次输入” 的错误消息)

{  
    "headers":{  
       "normalizedNames":{  

       },
       "lazyUpdate":null
    },
    "status":500,
    "statusText":"OK",
    "url":"https://localhost:44305/api/Entry/GetNext?id=11962",
    "ok":false,
    "name":"HttpErrorResponse",
    "message":"Http failure response for https://localhost:44305/api/Entry/GetNext?id=11962: 500 OK",
    "error":{  

    }
 }

不过,如果我打开 chrome 的 Network 选项卡,我可以看到以下内容

enter image description here

所以,我似乎无法从 error: Response 中获取此错误文本。

也许有人知道将错误传递给 Angular 客户端并在那里获取错误的更好方法?

更新 1 - 错误处理程序(我把断点放在那里只是为了调查错误的内容)

public handleError = (error: Response) => {
    debugger
    return Observable.throw(error)
}

最佳答案

我的疏忽。

如果您查看返回的 JSON

  ....

  "message":"Http failure response for https://localhost:44305/api/Entry/GetNext?id=11962: 500 OK",
  "error":{  

  }
}

error 似乎是一个空对象

事实上 error 是一个 Blob,我们应该按以下方式读取它

intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    return next
        .handle(req)
        .catch(this.handleError)
}

public handleError = (error: Response) => {

    let reader = new FileReader();

    let ngNotify = this._ngNotify;

    reader.onload = function () {

        var result = JSON.parse(this.result);

        ngNotify.nofity('Error', result.error);
    };

    reader.readAsText(error['error']);

    return Observable.throw(error)
}

就是这样。

关于c# - Angular:无法通过 HttpResponse 返回自定义错误消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51541365/

相关文章:

c# - 即使使用 ConfigureAwait(false),HttpClient 的 PostAsync 方法也会阻塞

c# - C# XAMARIN.FORMS 中的超链接按钮

c# - 如何以编程方式将代码插入程序集

Angular2 无法在 promise 回调中访问它

c# - 如何在 Singleton 服务中使用 Scoped Service

Azure AD - 即使配置为允许访问,对 Blazor 应用程序的跨租户访问也会被拒绝

c# - 在 Excel 中粘贴值 C#

java - 如何使用 Spring Boot 和 Angular 自动运行日常 PL/SQL 脚本(Oracle)?

javascript - 如何阻止可拖动恢复到原始位置

c# - 具有 Action 的自动映射器 map 集合