0

私はグローバルなエラー処理を提供するカスタムミドルウェアを持っています。例外が捕捉された場合は、参照番号で詳細を記録する必要があります。私はその後、エラーページにユーザーをリダイレクトし、参照番号のみを表示したい。私の研究によると、TempDataはこれには理想的だが、コントローラのコンテキスト内からはアクセス可能なように見えるだけである。私は参照番号をHttpContext.Items["ReferenceNumber"] = Guid.NewGuid();に追加しようとしました しかし、この値はリダイレクトによって失われます。カスタムミドルウェア内のTempDataへのアクセス

どのようにミドルウェアはリダイレクトを介して情報を渡すことができますか?数字をクエスチョンに入れるだけですか?

答えて

0

ミドルウェアクラスの内部では、必要なインターフェイスへのアクセスを得るために参照を追加する必要があります。このミドルウェアは別のプロジェクトにあり、このNuGetパッケージを追加する必要がありました。

using Microsoft.AspNetCore.Mvc.ViewFeatures; 

これにより、ミドルウェア内で正しいサービスを要求することができます。あなたはコントローラ内TempDataをを使用するように

//get TempData handle 
ITempDataDictionaryFactory factory = httpContext.RequestServices.GetService(typeof(ITempDataDictionaryFactory)) as ITempDataDictionaryFactory; 
ITempDataDictionary tempData = factory.GetTempData(httpContext); 

あなたはITempDataDictionaryを持った後、あなたはそれを使用することができます。

//pass reference number to error controller 
Guid ReferenceNum = Guid.NewGuid(); 
tempData["ReferenceNumber"] = ReferenceNum.ToString(); 

//log error details 
logger.LogError(eventID, exception, ReferenceNum.ToString() + " - " + exception.Message); 

は今、私は、参照番号を引き抜くと、私の見解では、それを使って何の問題を持っていない、リダイレクト後にコントローラを得るとき。

//read value in controller 
string refNum = TempData["ReferenceNumber"] as string; 
if (!string.IsNullOrEmpty(refNum)) 
    ViewBag.ReferenceNumber = refNum; 

@*display reference number if one was provided*@ 
@if (ViewBag.ReferenceNumber != null){<p>Reference Number: @ViewBag.ReferenceNumber</p>} 

これをまとめて入力すると、問題のトラブルシューティングに役立つ参照番号がユーザーに表示されます。しかし、潜在的に機密性の高いエラー情報を誤って渡すことはありません。

1

自分でITempDataProviderを登録し、ミドルウェアで使用することができます。ここで私は2つの単純なパスの間で作業している小さなサンプルです。すでにMVCを使用している場合、ITempDataProviderはすでに登録されている可能性があります。私が直面した問題は、書かれたクッキーのパスでした。/page1 so/page2はCookieにアクセスできませんでした。だから私はあなたが下のコードで見ることができるようにオプションをオーバーライドしなければならなかった。私は、これはあなたを助けることを願っています

:)

public void ConfigureServices(IServiceCollection services) 
{ 

    services.AddSingleton<IDataProtectionProvider>(s => DataProtectionProvider.Create("WebApplication2")); 

    services.Configure<CookieTempDataProviderOptions>(options => 
    { 
     options.Path = "/"; 
    }); 
    services.AddSingleton<ITempDataProvider, CookieTempDataProvider>(); 
} 

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ITempDataProvider tempDataProvider) 
{ 
    if (env.IsDevelopment()) 
    { 
     app.UseDeveloperExceptionPage(); 
    } 

    app.Map("/page1", (app1) => 
    { 
     app1.Run(async context => 
     { 
      tempDataProvider.SaveTempData(context, new Dictionary<string, object> { ["Message"] = "Hello from page1 middleware" }); 
      await context.Response.WriteAsync("Hello World! I'm page1"); 
     }); 
    }); 

    app.Map("/page2", (app1) => 
    { 
     app1.Run(async context => 
     { 
      var loadTempData = tempDataProvider.LoadTempData(context); 
      await context.Response.WriteAsync("Hello World! I'm page2: Message from page1: " + loadTempData["Message"]); 
     }); 
    }); 
} 

これは正しい方向に私を導いた:コーディングhttps://docs.microsoft.com/en-us/aspnet/core/fundamentals/app-state#cookie-based-tempdata-provider

ハッピー! :)

関連する問題