Access TempData within custom middleware

你说的曾经没有我的故事 提交于 2019-12-12 20:24:23

问题


I have custom middleware that provides global error handling. If an exception is caught it should log the details with a reference number. I then want to redirect the user to an error page and only show the reference number. My research shows that TempData should be ideal for this but it only seems to be accessible from within a controller context. I tried adding the reference number to HttpContext.Items["ReferenceNumber"] = Guid.NewGuid(); But this value is lost through the redirect.

How can middleware pass information through a redirect? Do I just have to put the number in a querystring?


回答1:


Inside the middleware class you need to add a reference to get access to the required interfaces. I have this middleware in a separate project and needed to add this NuGet package.

using Microsoft.AspNetCore.Mvc.ViewFeatures;

This then allows you to request the correct services within the middleware.

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

After you have ITempDataDictionary you can use it like you would use TempData within a controller.

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

Now when I get the the controller after a redirect I have no issues pulling out the reference number and using it in my view.

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

Once you put this all together, you give users a reference number that they can give you to help troubleshoot the problem. But, you are not passing back potentially sensitive error information which could be misused.




回答2:


You can register an ITempDataProvider yourself and use it in your middleware. Here is a small sample I got working between two simple paths. If you are already using MVC the ITempDataProvider is probably already registered. The issue I faced was the path of the cookie that was written. It was /page1 so /page2 did not have access to the cookie. So I had to override the options as you can see in code below.

I hope this will help you :)

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

This led me in the right direction: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/app-state#cookie-based-tempdata-provider

Happy coding! :)



来源:https://stackoverflow.com/questions/45330103/access-tempdata-within-custom-middleware

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!