Asp.net core .NET核心中间件-在控制器中访问IApplicationBuilder?
我需要访问控制器内的IApplicationBuilder 我尝试过的:- 我已经编写了中间件(app.UseMyMiddleware),如下所示Asp.net core .NET核心中间件-在控制器中访问IApplicationBuilder?,asp.net-core,httpcontext,Asp.net Core,Httpcontext,我需要访问控制器内的IApplicationBuilder 我尝试过的:- 我已经编写了中间件(app.UseMyMiddleware),如下所示 // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env, I
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, IHttpContextAccessor httpContextAccessor)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseMyMiddleware();
app.UseAuthentication();
app.UseSession();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
public class MyMiddleware
{
private readonly RequestDelegate _next;
public MyMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
///TODO - Pass IApplicationBuilder to HttpContext
await _next(context);
}
}
public static class MiddlewareExtensions
{
public static IApplicationBuilder UseMyMiddleware(this IApplicationBuilder builder)
{
return builder.UseMiddleware<MyMiddleware>();
}
}
public class HangfireSqlServerStorageExtension : Hangfire.JobStorage
{
private readonly HangfireSqlServerStorage _hangfireSqlServerStorage = new HangfireSqlServerStorage();
public HangfireSqlServerStorageExtension(string nameOrConnectionString)
{
_hangfireSqlServerStorage.SqlServerStorageOptions = new SqlServerStorageOptions();
_hangfireSqlServerStorage.SqlServerStorage = new SqlServerStorage(nameOrConnectionString, _hangfireSqlServerStorage.SqlServerStorageOptions);
}
public HangfireSqlServerStorageExtension(string nameOrConnectionString, SqlServerStorageOptions options)
{
_hangfireSqlServerStorage.SqlServerStorageOptions = options;
_hangfireSqlServerStorage.SqlServerStorage = new SqlServerStorage(nameOrConnectionString, _hangfireSqlServerStorage.SqlServerStorageOptions);
}
public void UpdateConnectionString(string nameOrConnectionString)
{
_hangfireSqlServerStorage.SqlServerStorage = new SqlServerStorage(nameOrConnectionString, _hangfireSqlServerStorage.SqlServerStorageOptions);
}
public override IStorageConnection GetConnection()
{
return _hangfireSqlServerStorage.SqlServerStorage.GetConnection();
}
public override IMonitoringApi GetMonitoringApi()
{
return _hangfireSqlServerStorage.SqlServerStorage.GetMonitoringApi();
}
}
public class Startup
{
///Other necessary code here
public static HangfireSqlServerStorageExtension HangfireSqlServerStorageExtension { get; private set; }
public void ConfigureServices(IServiceCollection services)
{
///Other necessary code here
HangfireSqlServerStorageExtension = new HangfireSqlServerStorageExtension("DBConnecttionString"));
services.AddSingleton<HangfireSqlServerStorageExtension>(HangfireSqlServerStorageExtension);
services.AddHangfire(configuration => configuration.SetDataCompatibilityLevel(CompatibilityLevel.Version_170));
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, IHttpContextAccessor httpContextAccessor)
{
//Other necessary code here
app.UseHangfireDashboard("/Dashboard", new DashboardOptions(), HangfireSqlServerStorageExtension);
//Other necessary code here
}
}
//此方法由运行时调用。使用此方法配置HTTP请求管道。
公共无效配置(IApplicationBuilder应用程序、IHostingEnvironment环境、IHttpContextAccessor httpContextAccessor)
{
if(env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
其他的
{
app.UseExceptionHandler(“/Home/Error”);
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseMyMiddleware();
app.UseAuthentication();
app.UseSession();
app.UseMvc(路由=>
{
routes.MapRoute(
名称:“默认”,
模板:“{controller=Home}/{action=Index}/{id?}”);
});
}
公共类中间件
{
private readonly RequestDelegate\u next;
公共MyMiddleware(RequestDelegate下一步)
{
_下一个=下一个;
}
公共异步任务调用(HttpContext上下文)
{
///TODO-将IApplicationBuilder传递给HttpContext
等待下一步(上下文);
}
}
公共静态类MiddlewareExtensions
{
公共静态IAApplicationBuilder UseMyMiddleware(此IAApplicationBuilder)
{
返回builder.UseMiddleware();
}
}
但我不知道如何在Invoke方法中将IAApplicationBuilder传递给HttpContext。所以,我可以在控制器中使用它。
我还提到了以下问题的答案
问题:-
在完成应用程序构建阶段后(运行
Configure
方法后),您不能访问iaapplicationbuilder
的任何位置。根本无法注射。
但是,为了在运行时根据请求数据(从HttpContext
)插入或配置中间件,您可以使用.UseWhen
。另一个终端中间件是.MapWhen
,但我认为这不适合您的情况。以下是.UseWhen
的示例:
public static class MiddlewareExtensions
{
public static IApplicationBuilder UseMyMiddleware(this IApplicationBuilder builder)
{
var allOptions = new [] {"option 1","option 2"};
foreach(var option in allOptions){
var currentOption = option;
builder.UseWhen(context => {
//suppose you can get the user's selected option from query string
var selectedOption = context.Request.Query["option_key"];
return selectedOption == currentOption;
}, app => {
//your MyMiddleware is supposed to accept one argument
app.UseMiddleware<MyMiddleware>(currentOption);
});
}
return builder;
}
}
您必须决定如何从用户处获取所选选项(在上面的示例中,我是从
查询字符串
获取的)。您也可以从Cookie
获取它(以记住用户的选择),或者从其他来源获取它,例如路由数据、头、表单、请求正文。我认为这是另一个问题,因此,如果您对此有问题,请提出另一个问题。IApplicationBuilder的设计不是为了按您希望的方式工作。相反,如果您在构建时创建了一些数据,并且希望这些数据可用于中间件,请向服务中添加一个单例,并将该单例注入中间件。首先感谢@Kingking和@GlennSills提供的解决方案和有价值的评论
我已经解决了这个问题
创建了一个继承自Hangfire.JobStorage的类,如下所示
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, IHttpContextAccessor httpContextAccessor)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseMyMiddleware();
app.UseAuthentication();
app.UseSession();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
public class MyMiddleware
{
private readonly RequestDelegate _next;
public MyMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
///TODO - Pass IApplicationBuilder to HttpContext
await _next(context);
}
}
public static class MiddlewareExtensions
{
public static IApplicationBuilder UseMyMiddleware(this IApplicationBuilder builder)
{
return builder.UseMiddleware<MyMiddleware>();
}
}
public class HangfireSqlServerStorageExtension : Hangfire.JobStorage
{
private readonly HangfireSqlServerStorage _hangfireSqlServerStorage = new HangfireSqlServerStorage();
public HangfireSqlServerStorageExtension(string nameOrConnectionString)
{
_hangfireSqlServerStorage.SqlServerStorageOptions = new SqlServerStorageOptions();
_hangfireSqlServerStorage.SqlServerStorage = new SqlServerStorage(nameOrConnectionString, _hangfireSqlServerStorage.SqlServerStorageOptions);
}
public HangfireSqlServerStorageExtension(string nameOrConnectionString, SqlServerStorageOptions options)
{
_hangfireSqlServerStorage.SqlServerStorageOptions = options;
_hangfireSqlServerStorage.SqlServerStorage = new SqlServerStorage(nameOrConnectionString, _hangfireSqlServerStorage.SqlServerStorageOptions);
}
public void UpdateConnectionString(string nameOrConnectionString)
{
_hangfireSqlServerStorage.SqlServerStorage = new SqlServerStorage(nameOrConnectionString, _hangfireSqlServerStorage.SqlServerStorageOptions);
}
public override IStorageConnection GetConnection()
{
return _hangfireSqlServerStorage.SqlServerStorage.GetConnection();
}
public override IMonitoringApi GetMonitoringApi()
{
return _hangfireSqlServerStorage.SqlServerStorage.GetMonitoringApi();
}
}
public class Startup
{
///Other necessary code here
public static HangfireSqlServerStorageExtension HangfireSqlServerStorageExtension { get; private set; }
public void ConfigureServices(IServiceCollection services)
{
///Other necessary code here
HangfireSqlServerStorageExtension = new HangfireSqlServerStorageExtension("DBConnecttionString"));
services.AddSingleton<HangfireSqlServerStorageExtension>(HangfireSqlServerStorageExtension);
services.AddHangfire(configuration => configuration.SetDataCompatibilityLevel(CompatibilityLevel.Version_170));
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, IHttpContextAccessor httpContextAccessor)
{
//Other necessary code here
app.UseHangfireDashboard("/Dashboard", new DashboardOptions(), HangfireSqlServerStorageExtension);
//Other necessary code here
}
}
HangfireSqlServerStorage.cs
在上面的HangfireSqlServerStorageExtension类中使用
public class HangfireSqlServerStorage
{
public SqlServerStorage SqlServerStorage { get; set; }
public SqlServerStorageOptions SqlServerStorageOptions { get; set; }
}
Startup.cs
在启动文件中,为HangfireSqlServerStorageExtension实例添加singleton服务,并按如下方式配置hangfire仪表板
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, IHttpContextAccessor httpContextAccessor)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseMyMiddleware();
app.UseAuthentication();
app.UseSession();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
public class MyMiddleware
{
private readonly RequestDelegate _next;
public MyMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
///TODO - Pass IApplicationBuilder to HttpContext
await _next(context);
}
}
public static class MiddlewareExtensions
{
public static IApplicationBuilder UseMyMiddleware(this IApplicationBuilder builder)
{
return builder.UseMiddleware<MyMiddleware>();
}
}
public class HangfireSqlServerStorageExtension : Hangfire.JobStorage
{
private readonly HangfireSqlServerStorage _hangfireSqlServerStorage = new HangfireSqlServerStorage();
public HangfireSqlServerStorageExtension(string nameOrConnectionString)
{
_hangfireSqlServerStorage.SqlServerStorageOptions = new SqlServerStorageOptions();
_hangfireSqlServerStorage.SqlServerStorage = new SqlServerStorage(nameOrConnectionString, _hangfireSqlServerStorage.SqlServerStorageOptions);
}
public HangfireSqlServerStorageExtension(string nameOrConnectionString, SqlServerStorageOptions options)
{
_hangfireSqlServerStorage.SqlServerStorageOptions = options;
_hangfireSqlServerStorage.SqlServerStorage = new SqlServerStorage(nameOrConnectionString, _hangfireSqlServerStorage.SqlServerStorageOptions);
}
public void UpdateConnectionString(string nameOrConnectionString)
{
_hangfireSqlServerStorage.SqlServerStorage = new SqlServerStorage(nameOrConnectionString, _hangfireSqlServerStorage.SqlServerStorageOptions);
}
public override IStorageConnection GetConnection()
{
return _hangfireSqlServerStorage.SqlServerStorage.GetConnection();
}
public override IMonitoringApi GetMonitoringApi()
{
return _hangfireSqlServerStorage.SqlServerStorage.GetMonitoringApi();
}
}
public class Startup
{
///Other necessary code here
public static HangfireSqlServerStorageExtension HangfireSqlServerStorageExtension { get; private set; }
public void ConfigureServices(IServiceCollection services)
{
///Other necessary code here
HangfireSqlServerStorageExtension = new HangfireSqlServerStorageExtension("DBConnecttionString"));
services.AddSingleton<HangfireSqlServerStorageExtension>(HangfireSqlServerStorageExtension);
services.AddHangfire(configuration => configuration.SetDataCompatibilityLevel(CompatibilityLevel.Version_170));
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, IHttpContextAccessor httpContextAccessor)
{
//Other necessary code here
app.UseHangfireDashboard("/Dashboard", new DashboardOptions(), HangfireSqlServerStorageExtension);
//Other necessary code here
}
}
iaapplicationbuilder
设计用于在启动时构建应用程序,运行一次,而不是在以后运行时运行。因此,我认为它不能为您提供任何运行时服务或API,您想要它做什么?这比如何使其可用更重要。@KingKing我想使用此IApplicationBuilder在控制器中配置Hangfire。您可以参考问题了解更多详细信息您以后无法访问iaapplicationbuilder
,但您可以在运行时使用useawhen
插入中间件。但是,筛选条件不能利用您的MVC模型绑定
,因为您只有HttpContext
作为输入,您自己从原始源(查询字符串、路由数据、标题、表单、请求正文)提取请求数据。你可以通过某种方式实现一个设置,记住或发送每个请求的所选选项)。@KingKing你能给我一个例子吗?我该怎么做?@KingKing谢谢!对于您的努力,我会检查并让您知道。谢谢您提供的信息。有没有其他办法来解决这个问题?我尝试了以下答案中提供的KingKing方法,但使用该方法,我无法根据“builder.UseWhen”条件更改“app.UseHangfireDashboard”的配置。(它仅在应用程序启动时配置)。查看一个关于如何在控制器中使用IApplicationBuilder的示例将非常有用。如果您告诉我,我可能可以为您提供一个解决方案。@开发者我很确定您不知道如何应用我的解决方案,。使用when
是您可以尝试的唯一选项。但看起来你不需要解决它,好吧。许多用户通过来回响应来获得最终解决方案,但您只是保持沉默,这样就没有机会让其他人提供帮助。“那只是你的选择。”金金对迟迟不答复深表歉意。我已经使用了您的解决方案,但使用该解决方案,我无法根据条件(使用.UseWhen)更改hangfire配置(表示hangfire连接字符串)。现在,我补充了我的答案。感谢您的努力,很抱歉延迟回复。