在 asp.net 5.0 web api 项目中访问中间件中的 TempData

Posted

技术标签:

【中文标题】在 asp.net 5.0 web api 项目中访问中间件中的 TempData【英文标题】:Accessing TempData in Middleware in a asp.net 5.0 web api project 【发布时间】:2021-10-16 02:35:40 【问题描述】:

我有两个应用程序同时运行。我试图找到一种能够在我自己的类中使用TempData 的方法,在阅读它之后,我在我的中间件中为我的 MVC 项目实现了它,该项目运行顺利。但是,当我将 MVC 项目中的中间件代码复制到我的 asp.net web api 项目的中间件时,它不起作用。当我一起运行程序时,当它调用 web api 项目时,它返回以下 web api(MVC 工作正常,我没有得到任何错误):

InvalidOperationException:尝试激活“AddressService.API.Middleware.CorrelationIdMiddleware”时,无法解析“Microsoft.AspNetCore.Mvc.ViewFeatures.ITempDataDictionaryFactory”类型的服务。

在我在我的 web api 项目的中间件中实现 TempData (ITempDataDictionaryFactory) 之前,它运行良好......但在实现 ITempDataDictionaryFactory 之后,它给了我这个错误。我必须做些什么才能让它像在我的 MVC 项目的中间件中那样工作吗?

Middleware 在我的 web api 项目中:

    public class CorrelationIdMiddleware
    
        private readonly RequestDelegate _next;
        private readonly ILogger _logger;
        private readonly ITempDataDictionaryFactory _tempDataDictionaryFactory;
        public CorrelationIdMiddleware(RequestDelegate next, ILoggerFactory loggerFactory, ITempDataDictionaryFactory tempDataDictionaryFactory)
        
            _next = next;
            _logger = loggerFactory.CreateLogger<CorrelationIdMiddleware>();
            _tempDataDictionaryFactory = tempDataDictionaryFactory;
        

        public async Task Invoke(HttpContext context)
        
            string correlationId = null;
            string userName;
            string ipAddress;

            var tempData = _tempDataDictionaryFactory.GetTempData(context);

            var key = context.Request.Headers.Keys.FirstOrDefault(n => n.ToLower().Equals("x-correlation-id"));
            if (!string.IsNullOrWhiteSpace(key))
            
                correlationId = context.Request.Headers[key];
                _logger.LogInformation("Header contained CorrelationId: @CorrelationId", correlationId);
            
            else
            
                if (tempData.ContainsKey("username") && tempData.ContainsKey("ipaddress"))
                
                    userName = tempData.Peek("username").ToString();

                    ipAddress = tempData.Peek("ipaddress").ToString();

                    context.Response.Headers.Append("X-username", userName);
                    context.Response.Headers.Append("X-ipAddress", ipAddress);
                

                correlationId = Guid.NewGuid().ToString();
                _logger.LogInformation("Generated new CorrelationId: @CorrelationId", correlationId);
            
            context.Response.Headers.Append("x-correlation-id", correlationId);
            using (LogContext.PushProperty("CorrelationId", correlationId))
            
                await _next.Invoke(context);
            
        

CorrelationIdExtensions.cs(用于在启动时调用app.UseCorrelationId()):

public static class CorrelationIdExtensions

    public static IApplicationBuilder UseCorrelationId(this IApplicationBuilder builder)
    
        return builder.UseMiddleware<CorrelationIdMiddleware>();
    

Startup.cs:

    public class Startup
    
        public Startup(IConfiguration configuration)
        
            Configuration = configuration;
        

        public IConfiguration Configuration  get; 

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        
            services.AddControllers();
            services.AddSwaggerGen(c =>
            
                c.SwaggerDoc("v1", new OpenApiInfo  Title = "AddressService.API", Version = "v1" );
            );

           services.AddHttpContextAccessor();
        

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        
            app.UseCorrelationId();

            if (env.IsDevelopment())
            
                app.UseDeveloperExceptionPage();
                app.UseSwagger();
                app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "AddressService.API v1"));
            

            app.UseHttpsRedirection();

            app.UseRouting();

            app.UseAuthorization();

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

【问题讨论】:

【参考方案1】:

解决这个问题的方法之一应该是使用:

services.AddControllersWithViews();

services.AddMvc();

而不是services.AddControllers();

【讨论】:

我用第一种方法试了一下,效果很好!谢谢!

以上是关于在 asp.net 5.0 web api 项目中访问中间件中的 TempData的主要内容,如果未能解决你的问题,请参考以下文章

在 ASP.NET Core 5.0 Web API 中实现 DelegatingHandler?

不可接受的响应 (406) 消息 Asp.NET 代码 Web API (C#) - .NET 5.0

EF Core 5.0 - 更新 ASP.NET Core Web API 中的多对多实体

Asp.Net Core Web API 5.0 和 Angular 中基于自定义角色的授权

为啥 ASP.NET web api 3 项目在 ASP.NET web api 2 执行时没有请求就无法启动?

试图从asp.net web api self host中的请求中获取用户代理