- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我有一个 ASP.NET Core 中间件调用另一个 HTTP 服务来检查用户是否有权继续请求。目前它取决于提供的自定义 header ,称为 X-Parameter-Id
。
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
namespace ParameterAuthorization.Middleware
{
public class ParameterAuthorizationMiddleware
{
private readonly RequestDelegate _next;
private readonly IParameterAuthorizationService _parameterAuthorizationService;
public ParameterAuthorizationMiddleware(RequestDelegate next, IParameterAuthorizationService parameterAuthorizationService)
{
_next = next ?? throw new ArgumentNullException(nameof(next));
_parameterAuthorizationService = parameterAuthorizationService ?? throw new ArgumentNullException(nameof(parameterAuthorizationService));
}
public async Task InvokeAsync(HttpContext httpContext, IConfiguration configuration)
{
if (httpContext is null)
{
throw new ArgumentNullException(nameof(httpContext));
}
if (parameterRequestContext is null)
{
throw new ArgumentNullException(nameof(parameterRequestContext));
}
if (!(httpContext.Request.Headers.ContainsKey("X-Parameter-Id") && httpContext.Request.Headers.ContainsKey("Authorization")))
{
await ForbiddenResponseAsync(httpContext);
}
var parameterIdHeader = httpContext.Request.Headers["X-Parameter-Id"].ToString();
if (!int.TryParse(parameterIdHeader, out var parameterId) || parameterId < 1)
{
await ForbiddenResponseAsync(httpContext);
}
var authorizationHeader = httpContext.Request.Headers["Authorization"].ToString();
var parameterResponse = await _parameterAuthorizationService.AuthorizeUserParameterAsync(parameterId, authorizationHeader);
if (string.IsNullOrWhiteSpace(parameterResponse))
{
await ForbiddenResponseAsync(httpContext);
}
await _next.Invoke(httpContext);
}
private static async Task ForbiddenResponseAsync(HttpContext httpContext)
{
httpContext.Response.StatusCode = StatusCodes.Status403Forbidden;
await httpContext.Response.WriteAsync("Forbidden");
return;
}
}
}
这就是 HTTP 调用实现:
using System;
using System.IO;
using System.Net.Http;
using System.Threading.Tasks;
using Newtonsoft.Json;
namespace ParameterAuthorization.Middleware.Http
{
public class ParameterAuthorizationService : IParameterAuthorizationService
{
private readonly HttpClient _httpClient;
private readonly JsonSerializer _jsonSerializer;
public ParameterAuthorizationService(HttpClient httpClient, JsonSerializer jsonSerializer)
{
_httpClient = httpClient ?? throw new ArgumentNullException(nameof(httpClient));
_jsonSerializer = jsonSerializer ?? throw new ArgumentNullException(nameof(jsonSerializer));
}
public async Task<string> AuthorizeUserParameterAsync(int parameterId, string authorizationHeader)
{
var request = CreateRequest(parameterId, authorizationHeader);
var result = await _httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
if (!result.IsSuccessStatusCode)
{
return string.Empty;
}
using (var responseStream = await result.Content.ReadAsStreamAsync())
using (var streamReader = new StreamReader(responseStream))
using (var jsonTextReader = new JsonTextReader(streamReader))
{
return _jsonSerializer.Deserialize<ParameterResponse>(jsonTextReader).StringImInterestedIn;
}
}
private static HttpRequestMessage CreateRequest(int parameterId, string authorizationHead1er)
{
var parameterUri = new Uri($"parameters/{parameterId}", UriKind.Relative);
var message = new HttpRequestMessage(HttpMethod.Get, parameterUri);
message.Headers.Add("Authorization", authorizationHead1er);
return message;
}
}
}
这是名为 HttpClient 的 DI 的样板代码
sc.TryAddSingleton<JsonSerializer>();
sc.AddHttpClient<IParameterAuthorizationService, ParameterAuthorizationService>(client =>
{
client.BaseAddress = authorizationServiceUri;
client.DefaultRequestHeaders.Add("Accept", "application/json");
});
authorizationServiceUri
是我通过自定义扩展方法提供的内容。
问题是我对该服务的调用会随机花费 7 秒、10 秒甚至 20 秒,然后它会变得很快,然后又变慢。我从 Postman 中调用这个确切的 ParameterAuthorizationService
,持续不到 50 毫秒。
我附上了 Application Insights 的屏幕截图,显示了整个事件序列。
这两种服务都作为 Azure 应用服务部署在同一应用服务计划的同一订阅下。
代码工作得很好,但我已经抓狂了,不知道是什么导致了这些性能异常。
我还检查了 Azure 应用服务中的 TCP 连接,它都是绿色的。
某些 HTTP 调用真的很慢的原因可能是什么?
我的应用服务在 S1 应用服务计划上运行。 https://azure.microsoft.com/en-us/pricing/details/app-service/windows/
最佳答案
如果您写入 httpContent,您应该将管道短路。参见 Aspnet Core Middleware documentation :
Don't call next.Invoke after the response has been sent to the client.
使用这样的东西:
if (string.IsNullOrWhiteSpace(parameterResponse))
{
await ForbiddenResponseAsync(httpContext);
}
else
{
await _next.Invoke(httpContext);
}
还考虑使用从 aspnet 核心继承的中间件处理身份验证 AuthenticationHandler类以利用所有 aspnet 核心身份验证/授权设施。这是一个 BasicAuthentification handler 的实现示例为简单起见。
您的 ParameterAuthorizationService 看起来不错。我不认为这是您缓慢请求调用的来源。可以肯定的是,您可以 track the entire service call通过测量花费的时间并在 appinsights 中发布:
public class ParameterAuthorizationService : IParameterAuthorizationService
{
//...
private readonly TelemetryClient _telemetryClient;
public ParameterAuthorizationService(HttpClient httpClient, JsonSerializer jsonSerializer)
{
//...
_telemetryClient = new TelemetryClient();
}
public async Task<string> AuthorizeUserParameterAsync(int parameterId, string authorizationHeader)
{
var startTime = DateTime.UtcNow;
var timer = Stopwatch.StartNew();
var isSuccess = true;
try
{
return await AuthorizeUserParameterImpl(parameterId, authorizationHeader);
}
catch (Exception ex)
{
timer.Stop();
isSuccess = false;
_telemetryClient.TrackException(ex);
_telemetryClient.TrackDependency("Http", nameof(ParameterAuthorizationService), nameof(AuthorizeUserParameterAsync),
startTime, timer.Elapsed, isSuccess);
throw;
}
finally
{
if (timer.IsRunning)
timer.Stop();
if (isSuccess)
_telemetryClient.TrackDependency(
"Http", nameof(ParameterAuthorizationService), nameof(AuthorizeUserParameterAsync),
startTime, timer.Elapsed, isSuccess);
}
}
private async Task<string> AuthorizeUserParameterImpl(int parameterId, string authorizationHeader)
{
//Your original code
}
}
关于c# - ASP.NET Core 对 Azure 应用服务的缓慢 HTTP 请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57225809/
创建使用.NET框架的asp.net页面时,访问该页面的客户端是否需要在其计算机上安装.NET框架? IE。用户访问www.fakesite.com/default.aspx,如果他们没有安装框架,他
我阅读了很多不同的博客和 StackOverflow 问题,试图找到我的问题的答案,但最后我找不到任何东西,所以我想自己问这个问题。 我正在构建一个应用程序,其中有一个长时间运行的工作线程,它执行一些
已锁定。这个问题及其答案是locked因为这个问题是题外话,但却具有历史意义。目前不接受新的答案或互动。 我一直想知道为什么微软为这样一个伟大的平台选择了一个如此奇怪的、对搜索引擎不友好的名称。他们就
.Net Framework .Net .NET Standard的区别 1、.NET Framework 在未来.NET Framework或许成为过去时,目前还是有很多地方在使用的。这一套
如果有选择的话,您会走哪条路? ASP.NET Webforms + ASP.NET AJAX 或 ASP.NET MVC + JavaScript Framework of your Choice
我有一个 Web 服务,它通过专用连接通过 https 使用第三方 Web 服务,我应用了 ServicePointManager.ServerCertificateValidationCallbac
为什么我应该选择ASP.NET Web Application (.NET Framework)而不是ASP.NET Core Web Application (.NET Framework)? 我在
我在网络上没有找到任何关于包含 .NET Standard、.NET Core 和 .NET Framework 项目的 .NET 解决方案的公认命名约定。 就我而言,我们在 .NET 框架项目中有以
.NET Compact 是 .NET 的完美子集吗? 假设我考虑了屏幕大小和其他限制并避免了 .NET Compact 不支持的类和方法,或者 .NET Compact 是一个不同且不兼容的 GUI
我已经阅读了所有我能找到的关于 connectionManagement 中的 maxconnection 设置的文章:即 http://support.microsoft.com/kb/821268
我现在正在使用asp.net mvc,想知道使用内置的Json或 Json.Net哪个是更好的选择,但我不确定一个人是否比另一个人有优势。 另外,如果我确实选择沿用Json.Net的路线,那么我应该选
在 Visual Studio 中,您至少可以创建三种不同类型的类库: 类库(.NET Framework) 类库(.NET 标准) 类库(.NET Core) 虽然第一个是我们多年来一直使用的,但我
.NET 和 ASP.NET 之间有什么区别?它们有什么关系? 最佳答案 ASP.Net 基于 .Net 框架构建,提供有关 Web 开发的附加功能。 你可以去看看wikipedia article
在安装更高版本(3.0)之前,我需要安装.net框架1.1和2.0吗?或者单独安装 3.0 框架就足够了,并为在早期框架版本上编写的软件提供支持?谢谢 ,丽然 最佳答案 不,您不必安装以前的框架。 我
我正在开发一个项目,人们可以“更新”类别,例如更改类别的名称。我收到以下消息 This is called after clicking update 按钮 with the SQL statemen
.NET 类 System.Net.CookieContainer 线程安全吗? --更新:交 key 答复-- 是否有任何方法可以确保异步请求期间修改的变量(即 HttpWebRequest.Coo
我正在使用 JScript.NET 在我编写的 C# WinForms 应用程序中编写脚本。它工作得很好,但我只是尝试在脚本中放置一些异常处理,但我无法弄清楚如何判断我的 C# 代码抛出了哪种类型的异
我需要你的帮助, 比如我有一个小数类型的变量,我想这样取整。 例如 3.0 = 3 3.1 = 4 3.2 = 4 3.3 = 4 3.4 = 4 3.5 = 4 3.6 = 4 3.7 = 4 3.
我使用过这样的代码:http://msdn.microsoft.com/en-us/library/dw70f090.aspx在 ASP.NET 中工作之前访问数据库(2-3 年前)。我没有意识到我正
自 ConfigurationManager .NET Standard 中不存在,检索正在执行的程序集的应用程序设置的最佳方法是什么,无论是 web.config或 appSettings.{env
我是一名优秀的程序员,十分优秀!