【发布时间】:2019-07-23 14:03:22
【问题描述】:
当我尝试访问 localhost:5000/hangfire 时,我被重定向到错误页面(我有一个返回相关状态页面的控制器(400,404 等))
我想 /hangfire 不存在。它所指的“HandeErrorCode”来自我的控制器。
[Route ("Error/{statusCode}")]
public IActionResult HandleErrorCode (int statusCode) {
var statusCodeData =
HttpContext.Features.Get<IStatusCodeReExecuteFeature> ();
switch (statusCode) {
case 404:
return View("Status404");
case 401:
return View("Status401");
case 400:
return View("Status400");
case 500:
return View("Status500");
}
return View ();
}
启动.cs
配置服务
services.AddHangfire(configuration=>{
configuration.UsePostgreSqlStorage(connectionString);
});
配置
app.UseHangfireDashboard("/hangfire");
app.UseHangfireServer();
编辑: 整个 Startup.cs
public class Startup {
public Startup (IHostingEnvironment env) {
Console.WriteLine ("startin app {0}, which uses env {1} and has root {2}", env.ApplicationName, env.EnvironmentName, env.ContentRootPath);
Configuration = new ConfigurationBuilder ()
.SetBasePath (env.ContentRootPath)
.AddJsonFile ("appsettings.json", optional : true, reloadOnChange : true)
.AddJsonFile ($"appsettings.{env.EnvironmentName}.json", optional : true)
.AddEnvironmentVariables ()
.Build ();
Console.WriteLine ("Current env variables are as follows: ");
var enumerator = Environment.GetEnvironmentVariables ().GetEnumerator ();
while (enumerator.MoveNext ()) {
Console.WriteLine ($"{enumerator.Key,5}:{enumerator.Value,100}");
}
}
public IConfigurationRoot Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices (IServiceCollection services) {
services.AddMvc ();
// Add framework services.
var connectionString = Configuration["ConnectionStrings:DefaultConnection"];
Console.WriteLine ("using conn str: {0}", connectionString);
services.AddEntityFrameworkNpgsql ()
.AddDbContext<EntityContext> (
options => options.UseNpgsql (connectionString)
);
services.AddIdentity<User, Role> (config => {
config.SignIn.RequireConfirmedEmail = true;
})
.AddEntityFrameworkStores<EntityContext> ()
.AddDefaultTokenProviders ();
services.Configure<IdentityOptions> (options => {
options.Password.RequireDigit = false;
options.Password.RequiredLength = 5;
options.Password.RequireLowercase = false;
options.Password.RequireNonAlphanumeric = false;
options.Password.RequireUppercase = false;
});
services.ConfigureApplicationCookie (options => options.LoginPath = "/account/login");
services.AddAuthentication (CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie (options => {
options.LoginPath = "/Account/Login";
options.LogoutPath = "/Account/Logout";
});
// SERVICE FILTERS
services.AddScoped<ActivePackageFilterAttribute, ActivePackageFilterAttribute> ();
services.AddScoped<ActiveUserFilterAttribute, ActiveUserFilterAttribute> ();
services.AddSingleton<AccountBilling, AccountBilling> ();
services.AddMemoryCache ();
services.AddHangfire (configuration => {
configuration.UsePostgreSqlStorage (connectionString);
});
services.AddMvc (config => {
config.ModelBinderProviders.Insert (0, new InvariantDecimalModelBinderProvider ());
//config.Filters.Add(typeof(RedirectActionFilter));
})
.SetCompatibilityVersion (CompatibilityVersion.Version_2_2)
.AddJsonOptions (options => {
options.SerializerSettings.ContractResolver = new DefaultContractResolver ();
options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
})
.AddViewLocalization (LanguageViewLocationExpanderFormat.Suffix, opts => { opts.ResourcesPath = "Resources"; })
.AddDataAnnotationsLocalization ();
//services.AddScoped<RedirectActionFilter>();
services.AddAutoMapper ();
services.AddSingleton<AutoMapper.IConfigurationProvider> (Automapper.AutoMapperConfig.RegisterMappings ());
//services.AddSingleton(Mapper.Configuration);
services.AddScoped<IMapper> (sp => new Mapper (sp.GetRequiredService<AutoMapper.IConfigurationProvider> (), sp.GetService));
services.AddDistributedMemoryCache (); // Adds a default in-memory implementation of IDistributedCache
services.AddSession ();
// Add application services.
services.AddTransient<IEmailSender, AuthMessageSender> ();
services.AddTransient<ISmsSender, AuthMessageSender> ();
services.AddScoped<IRepository, Repository> ();
services.AddScoped<Context, Context> ();
services.AddScoped<IAccountBilling, AccountBilling> ();
services.Configure<AdministratorEmailAddress> (Configuration);
services.Configure<AuthMessageSenderOptions> (Configuration);
services.Configure<TBCPaymentOptions> (Configuration);
services.AddScoped<ViewRender, ViewRender> ();
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor> ();
services.Configure<RequestLocalizationOptions> (opts => {
var supportedCultures = new [] {
new CultureInfo ("en"),
new CultureInfo ("ka"),
new CultureInfo ("ru")
};
opts.DefaultRequestCulture = new RequestCulture ("ka");
// Formatting numbers, dates, etc.
opts.SupportedCultures = supportedCultures;
// UI strings that we have localized.
opts.SupportedUICultures = supportedCultures;
});
// Add converter to DI
//services.AddSingleton(typeof(IConverter), new BasicConverter(new PdfTools()));
services.AddSingleton<ITemplateService, TemplateService> ();
services.AddSingleton (typeof (IConverter), new SynchronizedConverter (new PdfTools ()));
services.AddScoped<MailComposer> ();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure (IApplicationBuilder app, IHostingEnvironment env) {
if (env.IsDevelopment ()) {
app.UseDeveloperExceptionPage ();
app.UseDatabaseErrorPage ();
} else {
app.UseStatusCodePagesWithReExecute ("/Error/{0}");
}
app.UseStaticFiles ();
app.UseAuthentication ();
app.UseForwardedHeaders (new ForwardedHeadersOptions {
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});
var options = app.ApplicationServices.GetService<IOptions<RequestLocalizationOptions>> ();
app.UseRequestLocalization (options.Value);
app.UseSession ();
// app.UseHangfireDashboard ("/hangfire", new DashboardOptions {
// Authorization = new [] { new HangFireAuthorization () }
// });
app.UseHangfireDashboard ();
app.UseHangfireServer ();
RecurringJob.AddOrUpdate<IAccountBilling> (a => a.CheckUserPayment (), Cron.Minutely);
RecurringJob.AddOrUpdate<IAccountBilling> ("CalculateUserCharge", a => a.CalculateUserCharge (DateTime.Today.AddDays (-1)), Cron.Daily (21, 00), TimeZoneInfo.Utc);
//RecurringJob.AddOrUpdate<IAccountBilling>("CalculateUserCharge",a=>a.CalculateUserCharge(DateTime.Today.AddDays(-1)),Cron.Minutely);
app.UseMvc (routes => {
routes.MapRoute (
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
} }
HangfireAuthorization.cs
public class HangFireAuthorization: IDashboardAuthorizationFilter{
public bool Authorize([NotNull] DashboardContext context)
{
return context.GetHttpContext().User.IsInRole("Administrator");
}
}
如何访问hangfire 仪表板?
【问题讨论】:
-
调试您的代码以检查
statusCode的值是多少?与我们分享您的 vs 输出窗口中的内容。有任何错误信息吗?注释掉这行app.UseStatusCodePagesWithRedirects("/StatusCode?code={0}");并使用app.UseDeveloperExceptionPage();查看详细的错误信息。 -
@TaoZhou 在注释掉 UseStatusCodePagesWithRedirects 之前,我在控制器中放置了一个断点。我得到的 statusCode 是 403。我没有该代码的任何特定视图,所以它转到 IActionResult 的视图。当我注释掉你的建议时,它只是说我没有访问该页面的授权。
-
与我们分享您当前的
Startup.cs。您是否在项目中启用了任何安全架构? -
@TaoZhou 我编写了自定义授权过滤器,它工作正常。我只是好奇为什么当我应该可以访问仪表板时它会引发错误。 app.UseHangfireDashboard();不工作。然而,app.UseHangfireDashboard("/hangfire", new DashboardOptions { Authorization = new [] { new HangFireAuthorization () } });工作。我将发布整个 startup.cs
-
HangFireAuthorization是您自己的继承自IDashboardAuthorizationFilter的实现吗?
标签: c# asp.net-core