简体   繁体   English

为什么我的 header 数据从我的 Azure Function Http 从 HttpClient.GetAsync 调用时触发 in.Net 5

[英]Why is my header data missing from my Azure Function Http Trigger in .Net 5 when calling from HttpClient.GetAsync

I have a client using HttpClient.GetAsync to call into a Azure Function Http Trigger in.Net 5.我有一个客户端使用 HttpClient.GetAsync 调用 Azure Function Http 触发器 in.Net 5。

When I call the function using PostMan, I get my custom header data.当我使用 PostMan 调用 function 时,我得到了我的自定义 header 数据。

However, when I try to access my response object (HttpResponseMessage) that is returned from HttpClient.GetAsync, my header data empty.但是,当我尝试访问从 HttpClient.GetAsync 返回的响应 object (HttpResponseMessage) 时,我的 header 数据为空。

I have my Content data and my Status Code.我有我的内容数据和我的状态代码。 But my custom header data are missing.但是我自定义的header数据不见了。

Any insight would be appreciated since I have looking at this for hours.任何见解都将不胜感激,因为我已经看了好几个小时了。

Thanks for you help.谢谢你的帮助。

Edit: Here is the code where I am making the http call:编辑:这是我拨打 http 电话的代码:

        public async Task<HttpResponseMessage> GetQuotesAsync(int? pageNo, int? pageSize, string searchText)
        {
            var requestUri = $"{RequestUri.Quotes}?pageNo={pageNo}&pageSize={pageSize}&searchText={searchText}";
            return await _httpClient.GetAsync(requestUri);
        }

Edit 8/8/2021: See my comment below.编辑 8/8/2021:请参阅下面的评论。 The issue has something to do with using Blazor Wasm Client.该问题与使用 Blazor Wasm 客户端有关。

For anyone having problems after following the tips on this page, go back and check the configuration in the host.json file.对于按照本页提示操作后遇到问题的任何人,请返回 go 并检查 host.json 文件中的配置。 you need the Access-Control-Expose-Headers set to * or they won't be send even if you add them.您需要将 Access-Control-Expose-Headers 设置为 *,否则即使您添加它们也不会发送。 Note: I added the "extensions" node below and removed my logging settings for clarity.注意:为了清楚起见,我在下面添加了“扩展”节点并删除了我的日志记录设置。

host.json (sample file): host.json(示例文件):

{
  "version": "2.0",
  "extensions": {
    "http": {
      "customHeaders": {
        "Access-Control-Expose-Headers": "*"
      }
    }
  }
}

This is because HttpResponseMessage 's Headers property data type is HttpResponseHeaders but HttpResponseData 's Headers property data type is HttpHeadersCollection .这是因为HttpResponseMessageHeaders属性数据类型HttpResponseHeadersHttpResponseDataHeaders属性数据类型HttpHeadersCollection Since, they are different, HttpResponseHeaders could not bind to HttpHeadersCollection while calling HttpClient.GetAsync (as it returns HttpResponseMessage ).由于它们不同,因此HttpResponseHeaders在调用HttpClient.GetAsync时无法绑定到HttpHeadersCollection (因为它返回HttpResponseMessage )。

I could not find a way to read HttpHeadersCollection through HttpClient .我找不到通过HttpClient读取HttpHeadersCollection的方法。

As long as your Azure function code is emitting the header value, you should be able to read that in your client code from the Headers collection of HttpResponseMessage .只要您的 Azure function 代码发出 header 值,您就应该能够在客户端代码中从HttpResponseMessageHeaders集合中读取该值。 Nothing in your azure function ( which is your remote endpoint you are calling ) makes it any different.您的 azure function(这是您正在呼叫的远程端点)中没有任何不同之处。 Remember, your client code has no idea how your remote endpoint is implemented.请记住,您的客户端代码不知道您的远程端点是如何实现的。 Today it is azure functions, tomorrow it may be a full blown as.net core web api or a REST endpoint written in Node.js. Your client code does not care.今天它是 azure 功能,明天它可能是一个完整的 as.net 核心 web api 或 Node.js 中编写的 REST 端点。您的客户端代码不关心。 All it cares is whether the Http response it received has your expected header.它只关心它收到的 Http 响应是否有您预期的 header。

Asumming you have an azure function like this where you are adding a header called total-count to the response.假设您有一个像这样的 azure function,您要在响应中添加一个名为total-count的 header。

[Function("quotes")]
public static async Task<HttpResponseData> RunAsync(
             [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequestData req,
             FunctionContext executionContext)
{
    var logger = executionContext.GetLogger("Quotes");
    logger.LogInformation("C# HTTP trigger function processed a request for Quotes.");

    var quotes = new List<Quote>
    {
        new Quote { Text = "Hello", ViewCount = 100},
        new Quote { Text = "Azure Functions", ViewCount = 200}
    };

    var response = req.CreateResponse(HttpStatusCode.OK);
    response.Headers.Add("total-count", quotes.Count.ToString());
    await response.WriteAsJsonAsync(quotes);

    return response;
}

Your existing client code should work as long as you read the Headers property.只要您阅读Headers属性,您现有的客户端代码就应该可以工作。

public static async Task<HttpResponseMessage> GetQuotesAsync()
{
    var requestUri = "https://shkr-playground.azurewebsites.net/api/quotes";
    return await _httpClient.GetAsync(requestUri);
}

Now your GetQuotesAsync method can be called somewhere else where you will use the return value of it (HttpResponseMessage instance) and read the headers.现在可以在其他地方调用您的GetQuotesAsync方法,您将在其他地方使用它的返回值(HttpResponseMessage 实例)并读取标头。 In the below example, I am reading that value and adding to a string variable.在下面的示例中,我正在读取该值并将其添加到字符串变量中。 HttpResponseMessage implements IDisposable. HttpResponseMessage 实现 IDisposable。 So I am using a using construct to implicitly call the Dispose method.所以我使用using构造来隐式调用Dispose方法。

var msg = "Total count from response headers:";

using (var httpResponseMsg = await GetQuotesAsync())
{
    if (httpResponseMsg.Headers.TryGetValues("total-count", out var values))
    {
        msg += values.FirstOrDefault(); 
    }
}
// TODO: use "msg" variable as needed.

The types which Azure function uses for dealing with response headers is more of an implementation concern of azure functions. Azure function 用于处理响应标头的类型更多是 azure 函数的实现关注点。 It has no impact on your client code where you are using HttpClient and HttpResponseMessage.它对您使用 HttpClient 和 HttpResponseMessage 的客户端代码没有影响。 Your client code is simply dealing with standard http call response (response headers and body)您的客户端代码只是处理标准的 http 呼叫响应(响应标头和正文)

The issue is not with Blazor WASM, rather if that header has been exposed on your API Side.问题不在于 Blazor WASM,而是 header 是否已暴露在您的 API 端。 In your azure function, add the following -在您的 azure function 中,添加以下内容 -

Note: Postman will still show the headers even if you don't expose the headers like below.注意: Postman 仍然会显示标题,即使您没有像下面那样公开标题。 That's because, Postman doesn't care about CORS headers.那是因为 Postman 不关心 CORS 标头。 CORS is just a browser concept and not a strong security mechanism. CORS 只是一个浏览器概念,并不是一个强大的安全机制。 It allows you to restrict which other web apps may use your backend resources and that's all.它允许您限制哪些其他 web 应用程序可以使用您的后端资源,仅此而已。

First create a Startup File to inject the HttpContextAccessor首先创建一个启动文件来注入HttpContextAccessor

Package Required: Microsoft.Azure.Functions.Extensions Package 必需:Microsoft.Azure.Functions.Extensions

[assembly: FunctionsStartup(typeof(FuncAppName.Startup))]

namespace FuncAppName
{
    public class Startup : FunctionsStartup
    {
        public override void Configure(IFunctionsHostBuilder builder)
        {
            builder.Services.AddScoped<HttpContextAccessor>();
        }
    }
}

Next, inject it into your main Function -接下来,将其注入您的主 Function -

using Microsoft.AspNetCore.Http;
namespace FuncAppName
{
    public class SomeFunction
    {
        private readonly HttpContext _httpContext;
        public SomeFunction(HttpContextAccessor contextAccessor)
        {
             _httpContext = contextAccessor.HttpContext;
        }

        [FunctionName("SomeFunc")]
        public override Task<IActionResult> Run([HttpTrigger(AuthorizationLevel.Anonymous, new[] { "post" }, Route = "run")] HttpRequest req)
        {
            var response = "Some Response"
            _httpContext.Response.Headers.Add("my-custom-header", "some-custom-value");
            _httpContext.Response.Headers.Add("my-other-header", "some-other-value");
            _httpContext.Response.Headers.Add("Access-Control-Expose-Headers", "my-custom-header, my-other-header");
            return new OkObjectResult(response)
        }

If you want to allow all headers you can use wildcard (I think, not tested) -如果您想允许所有标头,您可以使用通配符(我认为,未经测试)-

_httpContext.Response.Headers.Add("Access-Control-Expose-Headers", "*");

You still need to add your web-app url to the azure platform CORS. You can add * wildcard, more info here - https://iotespresso.com/allowing-all-cross-origin-requests-azure-functions/您仍然需要将您的网络应用程序 url 添加到 azure 平台 CORS。您可以在此处添加 * 通配符,更多信息 - https://iotespresso.com/allowing-all-cross-origin-requests-azure-functions/

to enable CORS for Local Apps during development - https://stackoverflow.com/a/60109518/9276081在开发期间为本地应用启用 CORS - https://stackoverflow.com/a/60109518/9276081

Now to access those headers in your Blazor WASM, as an eg you can -现在访问您的 Blazor WASM 中的这些标头,例如您可以 -

protected override async Task OnInitializedAsync()
{
    var content = JsonContent.Create(new { query = "" });
    using (var client = new HttpClient())
    {
        var result = await client.PostAsync("https://func-app-name.azurewebsites.net/api/run", content);
        var headers = result.Headers.ToList();
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 调用 Azure Function(队列触发器)不起作用,但是当我从 azure 门户发送消息时它起作用 - Calling Azure Function ( Queue Trigger) Doesnt work , but it does when i send i message from azure portal HTTP 触发器 azure function 从 blob 存储错误获取图像 - HTTP trigger azure function get image from blob storage error 从Azure数据工厂调用Azure Function报404错误 - Calling Azure Function from Azure Data Factory Gives 404 Error 从另一个 Azure Function 呼叫 Azure Function - Calling Azure Function from another Azure Function 当我使用 http.get() 从 API 获取数据时出现错误 - i get errors when I fetch my data from an API using http.get() 为什么我的安全组规则在从私有 su.net 调用公共 su.net 时不起作用? - Why does my security group rule not work when calling from the private to public subnet? Azure function (out of process) HTTP Trigger Post request 数据限制 - Azure function (out of process) HTTP Trigger Post request Data limitation 将我的 Azure Function 从 .net Core 3.1 升级到 .net Core 7.0。 错误“'无法加载文件或程序集'Microsoft.Extensions.Configuration.Abstraction - Upgrade my Azure Function from .net Core 3.1 to .net Core 7.0. Error "'Could not load file or assembly 'Microsoft.Extensions.Configuration.Abstraction 从 ASP.Net Core 调用 Microsoft Graph 时缺少必需的范围 Web Api - Missing Scopes Required when calling Microsoft Graph from ASP .Net Core Web Api 如何将 CosmosDB 依赖项跟踪数据从 Azure Function 事件中心触发器发送到 Application Insights - How to send CosmosDB dependency tracking data to Application Insights from Azure Function Event Hub Trigger
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM