简化自定义错误页,非开发环境时使用;

使用自己的异常处理页,后续必须再次UseRouting;
This commit is contained in:
大石头 2020-08-23 12:38:54 +08:00
parent 2a0c57669d
commit a5eef8ba2a
8 changed files with 118 additions and 56 deletions

View File

@ -1,5 +1,6 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using NewLife.Cube;
@ -14,15 +15,20 @@ namespace CubeDemoNC
{
public class Startup
{
public Startup() { }
public IConfiguration Configuration { get; }
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public void ConfigureServices(IServiceCollection services)
{
// APM跟踪器
var tracer = new StarTracer("http://star.newlifex.com:6600") { Log = XTrace.Log };
DefaultTracer.Instance = tracer;
ApiHelper.Tracer = tracer;
DAL.GlobalTracer = tracer;
//ApiHelper.Tracer = tracer;
//DAL.GlobalTracer = tracer;
OAuthClient.Tracer = tracer;
TracerMiddleware.Tracer = tracer;
@ -33,20 +39,35 @@ namespace CubeDemoNC
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// 使用Cube前添加自己的管道
if (env.IsDevelopment())
var set = Setting.Current;
if (env.IsDevelopment() || set.Debug)
{
app.UseDeveloperExceptionPage();
}
else
app.UseExceptionHandler("/CubeHome/Error");
{
//app.UseExceptionHandler("/CubeHome/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
//// 启用https
//app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseMiddleware<TracerMiddleware>();
app.UseStaticFiles();
app.UseCube(env);
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
}
}

View File

@ -1,6 +1,7 @@
#if __CORE__
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using NewLife.Cube.ViewModels;
#else
using System.Web;
using System.Web.Mvc;
@ -30,14 +31,13 @@ namespace NewLife.Cube.Controllers
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
var context = HttpContext.Items["ExceptionContext"] as ExceptionContext;
var model = HttpContext.Items["Exception"] as ErrorModel;
if (IsJsonRequest)
{
if (context?.Exception != null)
return Json(500, null, context.Exception, new { action = context.ActionDescriptor.DisplayName });
if (model?.Exception != null) return Json(500, null, model.Exception);
}
return View("Error", context);
return View("Error", model);
}
#endif
}

View File

@ -72,8 +72,8 @@ namespace NewLife.Cube
// 模型绑定
opt.ModelBinderProviders.Insert(0, new EntityModelBinderProvider());
// 过滤器
opt.Filters.Add<GlobalExceptionFilter>();
//// 过滤器
//opt.Filters.Add<GlobalExceptionFilter>();
//opt.EnableEndpointRouting = false;
@ -172,12 +172,20 @@ namespace NewLife.Cube
#endregion
#region 使
/// <summary>使用魔方</summary>
/// <summary>使用魔方放在UseRouting之后UseEndpoints之前</summary>
/// <param name="app"></param>
/// <param name="env"></param>
/// <returns></returns>
public static IApplicationBuilder UseCube(this IApplicationBuilder app, IWebHostEnvironment env = null)
{
// 使用Cube前添加自己的管道
if (env != null)
{
// 使用自己的异常处理页后续必须再次UseRouting
if (!env.IsDevelopment())
app.UseExceptionHandler("/CubeHome/Error");
}
// 配置静态Http上下文访问器
app.UseStaticHttpContext();
@ -187,7 +195,7 @@ namespace NewLife.Cube
if (set.EnableCompress) app.UseResponseCompression();
// 注册中间件
app.UseStaticFiles();
//app.UseStaticFiles();
app.UseCookiePolicy();
app.UseSession();
@ -197,9 +205,10 @@ namespace NewLife.Cube
if (set.SslMode > SslModes.Disable) app.UseHttpsRedirection();
app.UseAuthentication();
//app.UseAuthentication();
app.UseRouting();
// 设置默认路由
app.UseEndpoints(endpoints =>
{
@ -210,9 +219,8 @@ namespace NewLife.Cube
"Default",
"{controller=CubeHome}/{action=Index}/{id?}"
);
endpoints.MapRazorPages();
})
.Build();
//endpoints.MapRazorPages();
});
// 使用管理提供者
app.UseManagerProvider();
@ -220,15 +228,6 @@ namespace NewLife.Cube
// 自动检查并添加菜单
AreaBase.RegisterArea<Admin.AdminArea>();
// 使用Cube前添加自己的管道
if (env != null)
{
if (!env.IsDevelopment())
app.UseDeveloperExceptionPage();
else
app.UseExceptionHandler("/CubeHome/Error");
}
return app;
}
#endregion

View File

@ -29,17 +29,17 @@ namespace NewLife.Cube.Extensions
/// <param name="options"></param>
public void PostConfigure(String name, StaticFileOptions options)
{
name = name ?? throw new ArgumentException(nameof(name));
options = options ?? throw new ArgumentException(nameof(options));
if (name.IsNullOrEmpty()) throw new ArgumentException(nameof(name));
if (options == null) throw new ArgumentException(nameof(options));
// 如果没有被其他组件初始化,在这里初始化
options.ContentTypeProvider = options.ContentTypeProvider ?? new FileExtensionContentTypeProvider();
options.ContentTypeProvider ??= new FileExtensionContentTypeProvider();
if (options.FileProvider == null && Environment.ContentRootFileProvider == null)
{
throw new InvalidOperationException("缺少FileProvider");
}
options.FileProvider = options.FileProvider ?? Environment.ContentRootFileProvider;
options.FileProvider ??= Environment.ContentRootFileProvider;
// 添加我们的文件提供者
// 第二个参数指定开始查找的文件夹比如文件都放在wwwroot就填“wwwroot”

View File

@ -42,6 +42,7 @@
<WarningLevel>3</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Compile Remove="Common\GlobalExceptionFilter.cs" />
<Compile Remove="Session\ISession2.cs" />
<Compile Remove="Session\MemorySession.cs" />
<Compile Remove="Session\MemorySessionStore.cs" />

View File

@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace NewLife.Cube.ViewModels
{
/// <summary>错误模型</summary>
public class ErrorModel
{
public String RequestId { get; set; }
public Uri Uri { get; set; }
public Exception Exception { get; set; }
}
}

View File

@ -1,4 +1,5 @@
@model ExceptionContext;
@model ErrorModel;
@using NewLife.Cube.ViewModels;
@using Microsoft.AspNetCore.Mvc.Filters
@{
//Layout = "_Ace_Layout.cshtml";
@ -6,32 +7,29 @@
//Layout = NewLife.Cube.Setting.Current.Layout;
ViewBag.Title = "处理你的请求时出错";
//var ex = ViewBag.Exception ?? (Model == null ? null : Model.Exception);
Exception ex = null;
var info = "";
var error = "没有捕捉到异常信息";
var context = Model ?? this.Context.Items["ExceptionContext"] as ExceptionContext;
if (context != null && context.Exception != null)
var ex = Model?.Exception;
if (ex != null)
{
// 由于nginx的配置导致出现奇葩错误
ex = context.Exception;
info = context.ActionDescriptor?.DisplayName;
if (NewLife.Cube.Setting.Current.Debug)
{
error = ex + "";
}
else
{
error = "内部错误:" + ex.GetTrue().GetType().FullName;
}
error = error?.Replace("--->", "--->" + Environment.NewLine);
}
if (NewLife.Cube.Setting.Current.Debug)
{
error = ex + "";
}
else
{
error = ex?.GetTrue().Message;
}
error = error?.Replace("--->", "--->" + Environment.NewLine);
}
<div class="panel panel-default">
<div class="panel-body">
<strong>
<pre class="info">@info</pre>
<pre class="alert info">RequestId: @Model?.RequestId</pre>
</strong>
<strong>
<pre class="alert info">Uri: @Model?.Uri</pre>
</strong>
<strong>
<pre class="alert alert-danger" role="alert">@error</pre>

View File

@ -6,13 +6,18 @@ using System.Threading.Tasks;
using System.Web;
using Microsoft.AspNetCore.Http;
using NewLife.Common;
using NewLife.Cube.ViewModels;
using NewLife.Log;
using NewLife.Reflection;
using NewLife.Security;
using NewLife.Web;
using XCode.DataAccessLayer;
using XCode.Membership;
using HttpContext = Microsoft.AspNetCore.Http.HttpContext;
namespace NewLife.Cube.WebMiddleware
{
/// <summary>页面查询执行时间中间件</summary>
/// <summary>运行时中间件。页面查询执行时间、异常拦截</summary>
public class RunTimeMiddleware
{
private readonly RequestDelegate _next;
@ -56,6 +61,27 @@ namespace NewLife.Cube.WebMiddleware
{
await _next.Invoke(ctx);
}
catch (Exception ex)
{
var uri = ctx.Request.GetRawUrl();
var ps = uri.AbsolutePath.Split('/');
XTrace.Log.Error("[{0}]的错误[{1}] {2}", uri, ManageProvider.UserHost, ctx.TraceIdentifier);
LogProvider.Provider?.WriteLog("访问", "错误", false, uri + Environment.NewLine + ex.GetMessage());
XTrace.WriteException(ex);
// 传递给异常处理页面
ctx.Items["Exception"] = new ErrorModel
{
RequestId = DefaultSpan.Current?.TraceId ?? Activity.Current?.Id ?? ctx.TraceIdentifier,
Uri = uri,
Exception = ex
};
throw;
}
finally
{
sw.Stop();
@ -71,7 +97,7 @@ namespace NewLife.Cube.WebMiddleware
/// <summary>获取执行时间和查询次数等信息</summary>
/// <param name="ctx"></param>
/// <returns></returns>
public static String GetInfo(HttpContext ctx)
public static String GetInfo(Microsoft.AspNetCore.Http.HttpContext ctx)
{
var rtinf = ctx.Items[nameof(RunTimeInfo)] as RunTimeInfo;
if (rtinf == null) return null;