gpt4 book ai didi

asp.net-core - 自定义响应 header 未出现在 API 响应中

转载 作者:行者123 更新时间:2023-12-05 04:00:07 26 4
gpt4 key购买 nike

Visual Studio 2019 预览版 16.2.0 预览版 2.Net Core 3.0.0 预览版 6 内部版本 19307Windows 10 版本 1809 操作系统内部版本 17763.402

我遇到了一个问题,我的自定义响应 header 没有出现在 API 响应中,但它确实出现在 MVC 响应中。

我创建了以下类用作中间件。

public class HostHeaderMiddleware
{
private readonly RequestDelegate _next;

public HostHeaderMiddleware(RequestDelegate next)
{
_next = next;
}

public async Task Invoke(HttpContext context)
{
// process context.Request

// since we are adding to the response headers, we can't do that once the response
// has been started. we need to hook the event.
context.Response.OnStarting(() =>
{
context.Response.Headers.Add("X-Host", Environment.MachineName);
return Task.CompletedTask;
});

// let the next object in the pipeline handle the context.
await _next(context);

// process context.Response
}
}

public static class HostHeaderMiddlewareExtensions
{
public static IApplicationBuilder UseHostHeaders(this IApplicationBuilder builder)
{
return builder.UseMiddleware<HostHeaderMiddleware>();
}
}

对于我的启动类,我有以下内容:

using System;
using FluentValidation.AspNetCore;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;

namespace company.division.project.app
{
public static class Consts
{
/// <summary>
/// The pattern of a user id.
/// </summary>
public const string UserIdPattern = "[a-zA-Z0-9/-]{10,32}";

/// <summary>
/// The pattern of a list id.
/// </summary>
/// <remarks>A list id is a guid without all the formatting.</remarks>
public const string ListIdPattern = "[a-fA-F0-9]{32}";
}

public class MprStartup<TStartup>
{
protected bool UsingFluentValidations { get; }
protected bool RunAsService { get; }

protected Type ServiceType { get; }

public MprStartup(IConfiguration configuration)
{
Configuration = configuration;

UsingFluentValidations = Configuration.GetValue<bool>("UsingFluentValidations");
RunAsService = Configuration.GetValue<bool>("RunAsService");

if (RunAsService)
{
var aqn = Configuration["MprServiceType"];
if (!string.IsNullOrWhiteSpace(aqn))
ServiceType = Type.GetType(aqn);
}
}

protected IConfiguration Configuration { get; }
protected ILogger<TStartup> Logger { get; set; }

// This method gets called by the runtime. Use this method to add services to the container.
protected void ConfigureServices(IServiceCollection services)
{
services.Configure<MongoSettings>(Configuration.GetSection("MongoConnection"));
services.AddSingleton<MongoSettings>(sp => sp.GetRequiredService<IOptions<MongoSettings>>().Value);

services.Configure<RouteOptions>(options =>
{
options.ConstraintMap.Add("userid", typeof(UserIdRouteConstraint));
options.ConstraintMap.Add("listid", typeof(ListIdRouteConstraint));
});

if (RunAsService)
{
// this would normally be: services.TryAddEnumerable(ServiceDescriptor.Singleton<IHostedService, WorkerService>()
// since we are passing in a generic, the above call doesn't work, we need to duplicate the underlying call.
services.TryAddEnumerable(ServiceDescriptor.Singleton(typeof(IHostedService), ServiceType));
}

var mvcBuiilder = services.AddMvc(options => options.EnableEndpointRouting = false)
.ConfigureApiBehaviorOptions(options =>
{
options.InvalidModelStateResponseFactory = InvalidModelStateResponseFactoryExtension.BnInvalidModelStateResponse;
});

if (UsingFluentValidations)
mvcBuiilder.AddFluentValidation();

services.AddHttpContextAccessor();

services.AddControllers()
.AddNewtonsoftJson(options =>
{
options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
options.SerializerSettings.DefaultValueHandling = DefaultValueHandling.Ignore;
});

services.AddSwaggerGen(options =>
{
options.SwaggerDoc("v1",
new OpenApiInfo()
{
Title = "Mobile Personalized Recommendations API",
Version = "v1"
});

var xmlFile = Path.ChangeExtension(typeof(Startup).Assembly.Location, ".xml");
options.IncludeXmlComments(xmlFile);

options.SchemaGeneratorOptions.DescribeAllEnumsAsStrings = true;
options.SwaggerGeneratorOptions.DescribeAllParametersInCamelCase = true;
});
}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
protected void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
Logger = app.ApplicationServices.GetRequiredService<ILogger<TStartup>>();

if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}

beginConfigure?.Invoke(app, env);

app.ConfigureExceptionHandler();

app.UseRouting();

app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});

app.UseHostHeaders();

app.UseMvc();

var autoMapper = a.ApplicationServices.GetRequiredService<IMapper>();
autoMapper.ConfigurationProvider.AssertConfigurationIsValid();

app.UseSwagger();
app.UseSwaggerUI(options =>
{
options.DisplayOperationId();
options.SwaggerEndpoint("/swagger/v1/swagger.json", "Do something API, v1");
});
}
}
}

我没有明确启用 CORS。

我做错了什么,导致自定义 header 只显示 MVC 响应而不显示 API 响应?

谢谢

最佳答案

我看到您在 UseEndpoints() 之后调用了 HostHeaderMiddleware。请上移(至少需要在UseEndpoints()之前调用)

app.UseHostHeaders();app.UseEndpoints(endpoints =>{    endpoints.MapControllers();});
  
   app.UseHostHeaders();
  

一个工作演示

enter image description here


附带说明,您不需要 ASP.NET Core 3 中的 UseMvc()

关于asp.net-core - 自定义响应 header 未出现在 API 响应中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56672705/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com