0

Ich habe benutzerdefinierte Middleware, die globale Fehlerbehandlung bietet. Wenn eine Ausnahme abgefangen wird, sollte sie die Details mit einer Referenznummer protokollieren. Ich möchte dann den Benutzer auf eine Fehlerseite umleiten und nur die Referenznummer anzeigen. Meine Forschung zeigt, dass TempData ideal dafür sein sollte, aber es scheint nur innerhalb eines Controllerkontexts zugänglich zu sein. Ich habe versucht, die Referenznummer zu HttpContext.Items["ReferenceNumber"] = Guid.NewGuid(); hinzufügen, aber dieser Wert ist durch die Umleitung verloren.Access TempData in benutzerdefinierten Middleware

Wie kann Middleware Informationen über eine Weiterleitung weitergeben? Muss ich die Nummer einfach in einen Querystring setzen?

Antwort

0

Innerhalb der Middleware-Klasse müssen Sie eine Referenz hinzufügen, um Zugriff auf die erforderlichen Schnittstellen zu erhalten. Ich habe diese Middleware in einem separaten Projekt und musste dieses NuGet-Paket hinzufügen.

using Microsoft.AspNetCore.Mvc.ViewFeatures; 

Dies ermöglicht Ihnen dann, die richtigen Dienste innerhalb der Middleware anzufordern.

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

Nachdem Sie ITempDataDictionary haben, können Sie es verwenden, wie Sie TempData innerhalb eines Controllers verwenden würde.

//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); 

Nun, wenn ich den Controller nach einer Umleitung ich keine Probleme haben die Referenznummer herausziehen und es in meiner Ansicht verwenden.

//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>} 

Sobald Sie dies alles zusammen, geben Sie den Benutzern eine Referenznummer, die sie Ihnen geben kann, um das Problem zu beheben. Sie geben jedoch keine potenziell sensiblen Fehlerinformationen zurück, die missbraucht werden könnten.

1

Sie können einen ITempDataProvider selbst registrieren und in Ihrer Middleware verwenden. Hier ist ein kleines Beispiel, das ich zwischen zwei einfachen Pfaden bearbeitet habe. Wenn Sie MVC bereits verwenden, ist der ITempDataProvider wahrscheinlich bereits registriert. Das Problem, dem ich gegenüberstand, war der Weg des Kekses, der geschrieben wurde. Es war/page1, also hatte/page2 keinen Zugriff auf den Cookie. Also musste ich die Optionen überschreiben, wie Sie unten im Code sehen können.

Ich hoffe, dies wird Ihnen helfen :)

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"]); 
     }); 
    }); 
} 

Das bin ich in die richtige Richtung geführt: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/app-state#cookie-based-tempdata-provider

Glücklich Codierung! :)