Azure-Web App-神秘消息作为响应

时间:2018-09-17 16:42:44

标签: c# azure encoding .net-core asp.net-core-webapi

简介

我正在使用 .NET Core 2.1 Web API ,该API托管在 Azure 上作为应用程序服务

UserService <PackageReference Include="Microsoft.AspNetCore.App" Version="2.1.0" /> 服务1 <PackageReference Include="Microsoft.AspNetCore.App" Version="2.1.2" />

服务1 基本上是通过同步http调用来调用 UserService

对于我的HttpClient,我实现了一个非常简单的包装器类,您可以在这里看到它(仅是相关的GET实现):

服务1

    public async Task<T> GetAsync<T>(string relativeUri, string accessToken)
    {
        var result = default(T);

        try
        {
            var httpRequestMessage = CreateHttpRequestMessage(HttpMethod.Get, relativeUri, accessToken);

            // SendAsync is supposed to be thread safe
            var response = await _httpClient.SendAsync(httpRequestMessage);
            response.EnsureSuccessStatusCode();

            // TODO : Only for debugging purposes
            var content = await response.Content.ReadAsStringAsync();
            _customHttpClientLogger.LogInformation(content);

            using (var stream = await response.Content.ReadAsStreamAsync())
            {
                using (var reader = new JsonTextReader(new StreamReader(stream)))
                {
                    result = _jsonSerializer.Deserialize<T>(reader);

                    _customHttpClientLogger.LogInformation("HTTP GET to {url} was successful.", relativeUri);
                }
            }

            return result;
        }
        catch (Exception ex)
        {
            _customHttpClientLogger.LogError(ex, "HTTP GET to {url} received an error.", relativeUri);
            throw;
        }
    }

    private HttpRequestMessage CreateHttpRequestMessage(HttpMethod httpMethod, string relativeUri, string accessToken, string authenticationSchema = BEARER)
    {
        var request = new HttpRequestMessage()
        {
            RequestUri = new Uri(relativeUri, UriKind.Relative),
            Method = httpMethod,
        };

        // Has to be added on a per-request basis, otherwise it would be shared with other requests.
        request.Headers.Add("Authorization", $"{authenticationSchema} {accessToken}");
        request.Headers.Add("Accept", "application/json");
        request.Headers.Add("Accept-Encoding", "gzip");

        return request;
    }

HttpClient注册

            services.AddHttpClient<UserServiceHttpClient>()
                .ConfigureHttpMessageHandlerBuilder(c => new HttpClientHandler()
                {
                    UseProxy = false,
                    AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
                })
                .AddHttpMessageHandler<CorrelationIdDelegatingHandler>();

服务2(UserService)

    [HttpGet("api/user")]
    [MapToApiVersion("1.0")]
    [Produces("application/json")]
    [SwaggerResponse((int)HttpStatusCode.OK, Type = typeof(List<User>), Description = "A list of user entities.")]
    [SwaggerResponse((int)HttpStatusCode.InternalServerError, Description = "An error occured.")]
    public async Task<IActionResult> GetAllAsync()
    {
        try
        {
            var users = await _userService.GetAllAsync();
            return Ok(users);
        }
        catch (Exception ex)
        {
            _userControllerLogger.LogError(ex.InnerException ?? ex,
                "An error occcured in the method {method}() in the class '{class}'.", nameof(GetAllAsync), nameof(UserController));
        }

        return StatusCode(StatusCodes.Status500InternalServerError);
    }

问题

这里的所有内容在我的 localhost 环境中都可以很好地运行,并且请求由 Service 1 处理。不幸的是,一旦我将其托管在Azure上,对api /api/user的调用就会返回类似以下内容的HttpContent

var content = await response.Content.ReadAsStringAsync();
_customHttpClientLogger.LogInformation(content);

? ?I?%&/m?{J?J??t?? $?@ ????????? iG#)?* ?? eVe] f @ ???? {??? {???;?N'???? \ fdl ?? J ??!???????〜|?“ ???? * f =?}?n ?? E ??? z ?? <[6?u ????? O?j?U?v: / ?? v?v ??????????? [???????? EV ?? Y?7?G ???} ?? 9}?i?:?[?? ??? q ?? ??X?T3??????E{MIg??h?????O??_]L????>Z??yQ?g??^dm???IQ]??j gi?

有趣的是,如果我直接通过 Postman 调用 UserService /api/user),那么我确实会收到适当的json响应。我还确保使用与代码中完全相同的HttpHeaders

image

image

执行路径

本地主机:

  • 邮递员=> UserService(API /用户)=> (有效)
  • 邮递员=>服务1 UserService(API /用户)=> (有效)
  • WebApplication => Service1 => UserService(API /用户)=> (有效)

天蓝色:

  • 邮递员=> UserService(API /用户)=> (有效)
  • 邮递员=>服务1 => UserService(API /用户)=> (无效)
  • WebApplication => Service1 => UserService(API /用户)=> (不起作用)

摘要

无论采用哪种执行路径(也是无效的执行路径),都会始终调用用户服务,并返回成功响应。我可以通过远程调试来验证用户服务始终返回OK()响应。

我真的很努力地找出编码部分可能出了错。

Azure 中的 UserService 似乎可以正常工作,但是一旦我从 Service 1 调用它,它似乎就不再起作用

是不是某些HttpMessageHandlerMiddleware干扰了请求?

听起来很奇怪,此问题仅在 Azure 中托管时出现。

是否有任何Azure特定的出站规则或拦截器会篡改我的请求?

以下是我用于服务1 NuGet软件包

<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="2.6.0" />
<PackageReference Include="Microsoft.AspNetCore.App" Version="2.1.2" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Versioning" Version="2.3.0" />
<PackageReference Include="Microsoft.Extensions.Logging.AzureAppServices" Version="2.1.1" />
<PackageReference Include="Microsoft.Extensions.PlatformAbstractions" Version="1.1.0" />
<PackageReference Include="Microsoft.VisualStudio.Web.BrowserLink" Version="2.1.1" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.1.1" />
<PackageReference Include="Serilog" Version="2.7.1" />
<PackageReference Include="Serilog.AspNetCore" Version="2.1.1" />
<PackageReference Include="Serilog.Enrichers.Environment" Version="2.1.2" />
<PackageReference Include="Serilog.Sinks.RollingFile" Version="3.3.0" />
<PackageReference Include="Serilog.Sinks.Seq" Version="4.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="3.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="2.1.1" PrivateAssets="All" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.1.1" PrivateAssets="All" />

我将非常感谢能为我指明正确方向的一切。

谢谢!

0 个答案:

没有答案