Multithreading Blazor Wasm HttpClientInterceptor线程问题
使用最新的NET5托管Blazor WASM 我正在使用HttpClientInterceptor捕获从服务器返回的错误。 所有内部错误都会被捕获并记录在服务器上,错误对象会返回到Blazor客户端 我将错误对象保存在本地存储器中,然后导航到错误页面。 问题是调用e.GetCapturedContentAsync()会以某种方式多次触发HttpClientInterceptor类。Multithreading Blazor Wasm HttpClientInterceptor线程问题,multithreading,blazor-webassembly,Multithreading,Blazor Webassembly,使用最新的NET5托管Blazor WASM 我正在使用HttpClientInterceptor捕获从服务器返回的错误。 所有内部错误都会被捕获并记录在服务器上,错误对象会返回到Blazor客户端 我将错误对象保存在本地存储器中,然后导航到错误页面。 问题是调用e.GetCapturedContentAsync()会以某种方式多次触发HttpClientInterceptor类。 下图是对服务器的一个调用,该调用返回一个带有错误对象的500。 其中一个条目保存来自服务器的数据,其余的一定是执行
下图是对服务器的一个调用,该调用返回一个带有错误对象的500。 其中一个条目保存来自服务器的数据,其余的一定是执行异步工作的某种副作用 当我不调用e.GetCapturedContentAsync()时,一切正常 这是我的HttpInterceptorService
public class HttpInterceptorService
{
private readonly HttpClientInterceptor _interceptor;
private readonly NavigationManager _navManager;
private readonly ILocalStorageService _localStorageService;
public HttpInterceptorService(HttpClientInterceptor interceptor, NavigationManager navManager,
ILocalStorageService localStorageService)
{
_interceptor = interceptor;
_navManager = navManager;
_localStorageService = localStorageService;
}
public void MonitorEvent() => _interceptor.AfterSendAsync += InterceptResponse;
private async Task InterceptResponse(object sender, HttpClientInterceptorEventArgs e)
{
if (e?.Response == null || e.Response.IsSuccessStatusCode) return;
await _localStorageService.RemoveItemAsync("apiError");
var responseCode = e.Response.StatusCode;
ApiError apiError;
var message = "Something went wrong, please contact Administrator";
string detail;
switch (responseCode)
{
case HttpStatusCode.NotFound:
message = "The requested resource was not found.";
detail = "The resource was not found. Please report the error if the problem persists.";
apiError = new ApiError {Title = message, Status = (short) responseCode, Detail = detail};
await _localStorageService.SetItemAsync("apiError", apiError);
_navManager.NavigateTo("/ErrorPage");
break;
case HttpStatusCode.Unauthorized:
case HttpStatusCode.Forbidden:
message = "You are not authorized to access this resource. ";
detail = "Please contact Helpdesk and the can help you get access to the resource.";
apiError = new ApiError {Title = message, Status = (short) responseCode, Detail = detail};
await _localStorageService.SetItemAsync("apiError", apiError);
_navManager.NavigateTo("/ErrorPage");
break;
case HttpStatusCode.InternalServerError:
apiError = await GetApiError500FromContent(e) ?? new ApiError();
if (string.IsNullOrEmpty(apiError.Id))
{
apiError.Status = (short) responseCode;
apiError.Title = "Internal server error";
}
await _localStorageService.SetItemAsync($"apiError_{Guid.NewGuid()}", apiError);
_navManager.NavigateTo("/ErrorPage");
break;
default:
message = "Something went wrong, please contact Administrator";
detail = "Please report the error if the problem persists.";
apiError = new ApiError {Title = message, Status = (short) responseCode, Detail = detail};
await _localStorageService.SetItemAsync($"apiError", apiError);
_navManager.NavigateTo("/ErrorPage");
break;
}
throw new HttpRequestException(message);
}
private static async Task<ApiError> GetApiError500FromContent(HttpClientInterceptorEventArgs e)
{
try
{
var capturedContent = await e.GetCapturedContentAsync();
var apiError = await capturedContent.ReadFromJsonAsync<ApiError>();
if (apiError != null && !string.IsNullOrEmpty(apiError.Id))
{
return apiError;
}
}
catch
{
}
return null;
}
public void DisposeEvent() => _interceptor.AfterSendAsync -= InterceptResponse;
}
公共类HttpInterceptorService
{
专用只读HttpClientInterceptor\u拦截器;
专用只读导航管理器_navManager;
专用只读ILocalStorageService\u localStorageService;
公共HttpInterceptor服务(HttpClientInterceptor interceptor、NavigationManager、navManager、,
ILocalStorageService(本地存储服务)
{
_拦截器=拦截器;
_navManager=navManager;
_localStorageService=localStorageService;
}
public void monitorent()=>\u interceptor.AfterSendAsync+=InterceptResponse;
专用异步任务侦听器响应(对象发送器,HttpClientInterceptorevenTarget)
{
如果(e?.Response==null | | e.Response.IsSuccessStatusCode)返回;
wait_localStorageService.removietemasync(“APIRROR”);
var responseCode=e.Response.StatusCode;
APIRERROR APIRROR;
var message=“出现问题,请与管理员联系”;
字符串细节;
开关(响应代码)
{
案例HttpStatusCode.NotFound:
message=“未找到请求的资源。”;
detail=“未找到资源。如果问题仍然存在,请报告错误。”;
APIRROR=新APIRROR{Title=消息,Status=(短)responseCode,Detail=Detail};
wait_localStorageService.SetItemAsync(“APIRROR”,APIRROR);
_navManager.NavigateTo(“/ErrorPage”);
打破
案例HttpStatusCode。未经授权:
案例HttpStatusCode。禁止:
message=“您无权访问此资源。”;
detail=“请联系帮助台,帮助您访问资源。”;
APIRROR=新APIRROR{Title=消息,Status=(短)responseCode,Detail=Detail};
wait_localStorageService.SetItemAsync(“APIRROR”,APIRROR);
_navManager.NavigateTo(“/ErrorPage”);
打破
案例HttpStatusCode.InternalServerError:
APIRROR=等待GetAPIRROR500FromContent(e)??新建APIRROR();
if(string.IsNullOrEmpty(apierro.Id))
{
APIRERROR.Status=(短)响应代码;
apierro.Title=“内部服务器错误”;
}
wait localStorageService.SetItemAsync($“APIRROR”{Guid.NewGuid()}),APIRROR);
_navManager.NavigateTo(“/ErrorPage”);
打破
违约:
message=“出现问题,请与管理员联系”;
detail=“如果问题仍然存在,请报告错误。”;
APIRROR=新APIRROR{Title=消息,Status=(短)responseCode,Detail=Detail};
wait\u localStorageService.SetItemAsync($“APIRROR”,APIRROR);
_navManager.NavigateTo(“/ErrorPage”);
打破
}
抛出新的HttpRequestException(消息);
}
私有静态异步任务GetApiError500FromContent(HttpClientInterceptorEventArgs e)
{
尝试
{
var capturedContent=wait e.GetCapturedContentAsync();
var apierro=wait capturedContent.ReadFromJsonAsync();
if(apierro!=null&&!string.IsNullOrEmpty(apierro.Id))
{
返回错误;
}
}
抓住
{
}
返回null;
}
public void DisposeEvent()=>\u interceptor.afterendasync-=InterceptResponse;
}
简单回答(:每次api调用后我忘记调用dispose