在 asp.net 5.0 web api 项目中访问中间件中的 TempData
Accessing TempData in Middleware in a asp.net 5.0 web api project
我同时有两个应用程序 运行在一起。我试图找到一种能够在我自己的 class 类型中使用 TempData
的方法,在阅读它之后,我在我的中间件中为我的 MVC 项目实现了它,它运行顺利。但是,当我将中间件代码从我的 MVC 项目复制到我的 asp.net web api 项目的中间件时,它不起作用。当我 运行 程序在一起时,当它调用网络时 api 项目它 returns 下面的网络 api (MVC 工作正常我没有得到任何错误):
InvalidOperationException: Unable to resolve service for type 'Microsoft.AspNetCore.Mvc.ViewFeatures.ITempDataDictionaryFactory' while attempting to activate 'AddressService.API.Middleware.CorrelationIdMiddleware'.
在我的 web api 项目的中间件中实现 TempData (ITempDataDictionaryFactory
) 之前它运行良好...但是在实现 ITempDataDictionaryFactory
之后,它给了我那个错误.我必须做些什么才能让它像在我的 MVC 项目的中间件中那样工作吗?
Middleware
在我的网站 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();
});
}
}
解决这个问题的方法之一应该是:
services.AddControllersWithViews();
或
services.AddMvc();
而不是services.AddControllers();
。
我同时有两个应用程序 运行在一起。我试图找到一种能够在我自己的 class 类型中使用 TempData
的方法,在阅读它之后,我在我的中间件中为我的 MVC 项目实现了它,它运行顺利。但是,当我将中间件代码从我的 MVC 项目复制到我的 asp.net web api 项目的中间件时,它不起作用。当我 运行 程序在一起时,当它调用网络时 api 项目它 returns 下面的网络 api (MVC 工作正常我没有得到任何错误):
InvalidOperationException: Unable to resolve service for type 'Microsoft.AspNetCore.Mvc.ViewFeatures.ITempDataDictionaryFactory' while attempting to activate 'AddressService.API.Middleware.CorrelationIdMiddleware'.
在我的 web api 项目的中间件中实现 TempData (ITempDataDictionaryFactory
) 之前它运行良好...但是在实现 ITempDataDictionaryFactory
之后,它给了我那个错误.我必须做些什么才能让它像在我的 MVC 项目的中间件中那样工作吗?
Middleware
在我的网站 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();
});
}
}
解决这个问题的方法之一应该是:
services.AddControllersWithViews();
或
services.AddMvc();
而不是services.AddControllers();
。