一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - ASP.NET教程 - ASP.NET Core應(yīng)用錯誤處理之DeveloperExceptionPageMiddleware中間件呈現(xiàn)“開發(fā)者異常頁面”

ASP.NET Core應(yīng)用錯誤處理之DeveloperExceptionPageMiddleware中間件呈現(xiàn)“開發(fā)者異常頁面”

2020-06-06 16:17大內(nèi)老A ASP.NET教程

這篇文章主要給大家介紹了關(guān)于ASP.NET Core應(yīng)用錯誤處理之DeveloperExceptionPageMiddleware中間件呈現(xiàn)“開發(fā)者異常頁面”的相關(guān)資料,需要的朋友可以參考下

前言

在《ASP.NET Core應(yīng)用的錯誤處理[1]:三種呈現(xiàn)錯誤頁面的方式》中,我們通過幾個簡單的實(shí)例演示了如何呈現(xiàn)一個錯誤頁面,這些錯誤頁面的呈現(xiàn)分別由三個對應(yīng)的中間件來完成,接下來我們將對這三個中間件進(jìn)行詳細(xì)介紹。在開發(fā)環(huán)境呈現(xiàn)的異常頁面是通過一個類型為DeveloperExceptionPageMiddleware中間件實(shí)現(xiàn)的。

?
1
2
3
4
5
6
public class DeveloperExceptionPageMiddleware
{
public DeveloperExceptionPageMiddleware(RequestDelegate next, IOptions<DeveloperExceptionPageOptions> options,
 ILoggerFactory loggerFactory, IHostingEnvironment hostingEnvironment, DiagnosticSource diagnosticSource);
public Task Invoke(HttpContext context);
}

如上面的代碼片段所示,當(dāng)我們創(chuàng)建一個DeveloperExceptionPageMiddleware對象的時候需要以參數(shù)的形式提供一個IOptions<DeveloperExceptionPageOptions>對象,而DeveloperExceptionPageOptions對象攜帶我們?yōu)檫@個中間件指定的配置選項(xiàng),具體的配置選項(xiàng)體現(xiàn)在如下另個屬性(FileProvider和SourceCodeLineCount)。

?
1
2
3
4
5
public class DeveloperExceptionPageOptions
{
 public IFileProvider  FileProvider { get; set; }
 public int    SourceCodeLineCount { get; set; }
}

一般來說我們總是通過調(diào)用ApplicationBuilder的擴(kuò)展方法UseDeveloperExceptionPage方法來注冊這個DeveloperExceptionPageMiddleware中間件,這兩個擴(kuò)展方法重載采用如下的方式創(chuàng)建并注冊這個DeveloperExceptionPageMiddleware中間件。

?
1
2
3
4
5
6
7
8
9
10
11
public static class DeveloperExceptionPageExtensions
{
 public static IApplicationBuilder UseDeveloperExceptionPage(this IApplicationBuilder app)
 {
  return app.UseMiddleware<DeveloperExceptionPageMiddleware>();
 }
 public static IApplicationBuilder UseDeveloperExceptionPage(this IApplicationBuilder app,DeveloperExceptionPageOptions options)
 {
  return app.UseMiddleware<DeveloperExceptionPageMiddleware>(Options.Create(options));
 }
}

在《ASP.NET Core應(yīng)用的錯誤處理[1]:三種呈現(xiàn)錯誤頁面的方式》實(shí)例演示中,我們并不曾使用過DeveloperExceptionPageOptions這個對象,對于定義在這個類型中的這兩個屬性,我想很多人都不知道它們究竟可以用作哪方面的配置。要很清楚地解答這個問題,就需要從 DeveloperExceptionPageMiddleware中間件處理的兩種異常類型說起。總的來說,該中間件處理的異常大體上可以分為兩類,它們分別是“運(yùn)行時異常”和“編譯異常”,后者類型實(shí)現(xiàn)了ICompilationException接口,如下的代碼片段基本上體現(xiàn)了異常處理在DeveloperExceptionPageMiddleware中間件中的實(shí)現(xiàn)。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class DeveloperExceptionPageMiddleware
{
 private RequestDelegate _next;
 public async Task Invoke(HttpContext context)
 {
  try
  {
   await _next(context);
  }
  catch(Exception ex)
  {
   context.Response.Clear();
   context.Response.StatusCode = 500;
 
   ICompilationException compilationException = ex as ICompilationException;
   if (null != compilationException)
   {
    await DisplayCompilationException(context, compilationException);
   }
   else
   {
    await DisplayRuntimeException(context, ex);
   }
  }
 }
 
 private Task DisplayRuntimeException(HttpContext context, Exception ex);
 private Task DisplayCompilationException(HttpContext context,ICompilationException compilationException) ;
}

一、 處理編譯異常

我想很多人會很疑惑:我們編寫一個ASP.NET Core應(yīng)用應(yīng)該是先編譯成程序集,然后再部署并啟動執(zhí)行,為什么運(yùn)行過程中還會出現(xiàn)“編譯異常”呢?從ASP.NET Core應(yīng)用層面來說,我們采用的是“預(yù)編譯”,也就說我們部署的不是源代碼而是編譯好的程序集,所以運(yùn)行過程中根本就不存在“編譯異常”一說。但是不要忘了在一個ASP.NET Core MVC應(yīng)用中,視圖文件(.cshtml)是支持“動態(tài)編譯”的。也就是說我們可以直接部署視圖源文件,應(yīng)用在執(zhí)行過程中是可以動態(tài)地編譯它們的。換句話說,由于視圖文件支持動態(tài)編譯,我們是可以在部署環(huán)境直接修改視圖文件的。

對于DeveloperExceptionPageMiddleware中間件來說,對于普通的運(yùn)行時異常,它會采用HTML文檔的形式將異常自身的詳細(xì)信息和當(dāng)前請求的信息以HTML文檔的形式呈現(xiàn)出來,我們前面演示的實(shí)例已經(jīng)很好的說明了這一點(diǎn)。如果應(yīng)用在動態(tài)編譯視圖文件中出現(xiàn)了編譯異常,最終呈現(xiàn)出來的錯誤頁面將具有不同的結(jié)構(gòu)和內(nèi)容,我們不防也通過一個簡單的實(shí)例來演示一下DeveloperExceptionPageMiddleware中間件針對編譯異常的處理。

我們通過如下所示的代碼啟動了一個ASP.NET Core MVC應(yīng)用,并通過調(diào)用ApplicationBuilder的擴(kuò)展方法UseDeveloperExceptionPage注冊了DeveloperExceptionPageMiddleware中間件。對應(yīng)定義在HomeController中的Action方法Index來說,它會負(fù)責(zé)將對應(yīng)的視圖呈現(xiàn)出來。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class Program
 {
  public static void Main()
  {
   new WebHostBuilder()
    .UseKestrel()
    .UseContentRoot(Directory.GetCurrentDirectory())
    .ConfigureServices(svcs => svcs.AddMvc())
    .Configure(app => app
     .UseDeveloperExceptionPage()
     .UseMvc())
    .Build()
    .Run();
  }
 }
 
 public class HomeController : Controller
 {
  [HttpGet("/")]
  public IActionResult Index()
  {
   return View();
  }
}

根據(jù)約定,Action方法Index呈現(xiàn)出來的視圖文件對應(yīng)的路徑應(yīng)該是“~/views/home/index.cshtml”,我們?yōu)榇嗽谶@個路徑下創(chuàng)建這個視圖文件。為了能夠在動態(tài)編譯過程中出現(xiàn)編譯異常,我們在這個視圖文件中編寫了如下三行代碼,F(xiàn)oobar是一個尚未被創(chuàng)建的類型。

?
1
2
3
@{
 var value = new Foobar();
}

當(dāng)我們利用瀏覽器訪問HomeController的Action方法Index的時候,應(yīng)用會動態(tài)編譯目標(biāo)視圖,由于視圖文件中使用了一個不曾不定義的類型,動態(tài)編譯會失敗,響應(yīng)的錯誤信息會以如圖7所示的形式出現(xiàn)在瀏覽器上。可以看出錯誤頁面顯示的內(nèi)容和結(jié)構(gòu)與前面演示的實(shí)例是完全不一樣的,我們不僅可以從這個錯誤頁面中得到導(dǎo)致編譯失敗的視圖文件的路徑(“Views/Home/Index.cshtml”),還可以直接看到導(dǎo)致編譯失敗的那一行代碼。不僅如此,這個錯誤頁面還直接將參與編譯的源代碼(不是定義在.cshtml文件中的原始代碼,而是經(jīng)過轉(zhuǎn)換處理生成的C#代碼)。毫無疑問,這個如此詳盡的錯誤頁面對于相信開發(fā)人員的糾錯針對是非常有價(jià)值的。

ASP.NET Core應(yīng)用錯誤處理之DeveloperExceptionPageMiddleware中間件呈現(xiàn)“開發(fā)者異常頁面”

一般來說,動態(tài)編譯的整個過程由兩個步驟組成,它先是將源代碼(類似于.cshtml這樣的模板文件)轉(zhuǎn)換成針對某種.NET語言(比如C#)的代碼,然后進(jìn)一步地編譯成IL代碼。動態(tài)編譯過程中拋出的異常類型一般會實(shí)現(xiàn)ICompilationException接口。如下面的代碼片段所示,該接口值具有一個唯一的屬性CompilationFailures,它返回一個元素類型為CompilationFailure的集合。編譯失敗的相關(guān)信息被封裝在一個CompilationFailure對象之中,我們可以利用它得到源文件的路徑(SourceFilePath)和內(nèi)容(SourceFileContent),以及源代碼轉(zhuǎn)換后交付編譯的內(nèi)容。如果在內(nèi)容轉(zhuǎn)換過程就已經(jīng)發(fā)生錯誤,那么SourceFileContent屬性可能返回Null。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
public interface ICompilationException
{
 IEnumerable<CompilationFailure> CompilationFailures { get; }
}
 
public class CompilationFailure
{
 public string        SourceFileContent { get; }
 public string        SourceFilePath { get; }
 public string        CompiledContent { get; }
 public IEnumerable<DiagnosticMessage>  Messages { get; }
 
}

CompilationFailure類型還具有一個名為Messages的只讀屬性,它返回一個元素類型為DiagnosticMessage的集合,一個DiagnosticMessage對象承載著一些描述編譯錯誤的診斷信息。我們不僅可以借助DiagnosticMessage對象的相關(guān)屬性得到描述編譯錯誤的消息(Message和FormattedMessage),還可以得到發(fā)生編譯錯誤所在源文件的路徑(SourceFilePath)以及范圍,StartLine、StartColumn、EndLine和EndColumn屬性分別表示導(dǎo)致編譯錯誤的源代碼在源文件中開始和結(jié)束的行與列(行數(shù)和列數(shù)分別從1和0開始計(jì)數(shù))。

?
1
2
3
4
5
6
7
8
9
10
11
12
public class DiagnosticMessage
{
 public string  SourceFilePath { get; }
 public int  StartLine { get; }
 public int  StartColumn { get; }
 public int  EndLine { get; }
 public int  EndColumn { get; }
 
 public string  Message { get; } 
 public string  FormattedMessage { get; }
}

從上圖可以看出,錯誤頁面會直接將導(dǎo)致編譯失敗的相關(guān)源代碼顯示出來。具體來說,它不僅僅會將直接導(dǎo)致失敗的源代碼實(shí)現(xiàn)出來,還會同時顯示前后相鄰的源代碼。至于相鄰源代碼應(yīng)該顯示多少行,實(shí)際上是通過DeveloperExceptionPageOptions的SourceCodeLineCount屬性控制的。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Program
{
 public static void Main()
 {
  new WebHostBuilder()
   .UseKestrel()
   .UseContentRoot(Directory.GetCurrentDirectory())
   .ConfigureServices(svcs => svcs.AddMvc())
   .Configure(app => app
    .UseDeveloperExceptionPage(new DeveloperExceptionPageOptions { SourceCodeLineCount = 3 })
    .UseMvc())
   .Build()
   .Run();
 }
}

對于前面演示的這個實(shí)例來說,如果我們希望前后相鄰的三行代碼被顯示在錯誤頁面上,我們可以采用如上的方式為注冊的DeveloperExceptionPageMiddleware中間件指定一個DeveloperExceptionPageOptions對象,并將它的SourceCodeLineCount屬性設(shè)置為3。與此同時,我們將視圖文件(index.cshtml)改寫成如下的形式,即在導(dǎo)致編譯失敗的那一行代碼前后分別添加了4行代碼。

?
1
2
3
4
5
6
7
8
9
1:
2:
3:
4:
5:@{ var value = new Foobar();}
6:
7:
8:
9:

對于定義在視圖文件中的共計(jì)9行代碼,根據(jù)在注冊DeveloperExceptionPageMiddleware中間件時指定的規(guī)則,最終顯示在錯誤頁面上的應(yīng)該是第2行到第8行。如果利用瀏覽器訪問相同的地址,我們會看到這7行代碼會以下圖的形式出現(xiàn)在錯誤頁面上。值得一提的是,如果我們沒有對SourceCodeLineCount屬性作顯式設(shè)置,它的默認(rèn)值為6。

ASP.NET Core應(yīng)用錯誤處理之DeveloperExceptionPageMiddleware中間件呈現(xiàn)“開發(fā)者異常頁面”

二、處理運(yùn)行時異常

對于DeveloperExceptionPageMiddleware中間件來說,任何類型沒有實(shí)現(xiàn)ICompilationException接口的異常都被視為“運(yùn)行時異常”。通過ASP.NET Core應(yīng)用的錯誤處理[1]:三種呈現(xiàn)錯誤頁面的方式》演示的實(shí)例我們已經(jīng)知道,DeveloperExceptionPageMiddleware中間件在處理運(yùn)行時異常時不僅僅會將異常的詳細(xì)信息顯示在錯誤頁面中,該頁面中還會包含于當(dāng)前請求相關(guān)的信息,包括查詢字符串、Cookie和請求報(bào)頭集合。現(xiàn)在我們關(guān)心的是另一個問題,我們利用DeveloperExceptionPageOptions的供的這個FileProvider對象就是出于什么目的呢?

對于錯誤頁面呈現(xiàn)的描述異常的詳細(xì)信息,除了類型和消息這些基本的信息之外,異常的堆棧追蹤(Stack Trace)也會出現(xiàn)在該頁面中。不僅如此,如果堆棧追蹤包含源代碼的信息(比如源文件路徑以及對應(yīng)源代碼所在的行和列),DeveloperExceptionPageMiddleware中間件還會試著加載源文件,并將導(dǎo)致異常的源代碼原封不動的顯示出來。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class Program
{
 public static void Main()
 {
  new WebHostBuilder()
   .UseKestrel()
   .Configure(app => app
    .UseDeveloperExceptionPage()
    .Run(Invoke))
   .Build()
   .Run();
 }
 private static Task Invoke(HttpContext context)
 {
  throw new InvalidOperationException("Manually thrown exception");
 }
}

我們將前面演示的代碼改寫成如上的形式,并在本地以Debug模式運(yùn)行該程序,將會得到如下圖所示的錯誤頁面。我們會看到由于異常的堆棧追蹤信息中包含源代碼的相關(guān)信息(源文件路徑和行號),所以導(dǎo)致異常的那一行代碼可以原封不動地顯示出來。與編譯異常處理方式一樣,一并顯示出來的還包括與之相鄰的代碼,至于具體會顯示多少行相鄰代碼,自然也是通過DeveloperExceptionPageOptions的SourceCodeLineCount屬性來控制的。

ASP.NET Core應(yīng)用錯誤處理之DeveloperExceptionPageMiddleware中間件呈現(xiàn)“開發(fā)者異常頁面”

DeveloperExceptionPageOptions的FileProvider提供FileProvider對象的目的就是幫助讀取源文件的內(nèi)容,或者說它為我們的糾錯調(diào)試提供源文件。如果我們在創(chuàng)建DeveloperExceptionPageMiddleware中間件的時候沒有顯式提供這么一個FileProvider,那么默認(rèn)情況下會使用指向ContentRoot目錄的這個PhysicalFileProvider。值得一提的是,如果異常的追蹤堆棧中出現(xiàn)了源文件的路徑,DeveloperExceptionPageMiddleware中間件總是會試圖先從本地文件系統(tǒng)去加載這個文件,只有在本地文件加載失敗的情況下它才會利用指定的FileProvider去讀取文件。

總結(jié)

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問大家可以留言交流,謝謝大家對服務(wù)器之家的支持。

原文鏈接:http://www.cnblogs.com/artech/p/error-handling-in-asp-net-core-2.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 亚洲视频在线一区二区三区 | 欧美久在线观看在线观看 | 91精品天美精东蜜桃传媒免费 | 国产成人h综合亚洲欧美在线 | 亚洲入口 | 亚洲激情网 | 女人张开腿 让男人桶个爽 免费观看 | 成人免费在线视频观看 | 欧美在线播放成人免费 | 成人免费视频一区 | 精品久久久久国产免费 | 草莓视频深夜释放 | 韩剧消失的眼角膜免费完整版 | 国产女主播在线播放一区二区 | 国产精品一区二区久久 | 日本中文字幕一区二区高清在线 | 香蕉久久一区二区三区啪啪 | 欧美黑人性猛交╳xx╳动态图 | 18性夜影院午夜寂寞影院免费 | 91庥豆果冻天美精东蜜桃传媒 | 果冻传媒林予曦图片 | 日本一区三区 | 亚洲一级片在线播放 | 范冰冰a级一级特级毛片 | 二区免费视频 | 日韩亚洲人成在线综合 | 日本精品中文字幕在线播放 | 日韩欧美一区二区三区 | 天堂网在线.www天堂在线资源 | 欧美成人香蕉在线观看 | 精品人人视屏 | 国产精品久久久久这里只有精品 | 草莓视频首页 | 国产欧美视频在线观看 | 91大神在线观看精品一区 | www.国产自拍 | 成年人免费在线看的惊悚动作片 | 欧美高清videosex极品 | 猛h辣h高h文湿校园1v1 | 国内精品伊人久久大香线焦 | 久久精品视频免费 |