在自定义中间件中访问TempData

时间:2017-07-26 14:36:36

标签: model-view-controller asp.net-core tempdata asp.net-core-middleware

我有自定义中间件,提供全局错误处理。如果发现异常,则应使用参考编号记录详细信息。然后,我想将用户重定向到错误页面,只显示参考号。我的研究表明TempData应该是理想的,但它似乎只能从控制器上下文中访问。我尝试将参考号添加到HttpContext.Items["ReferenceNumber"] = Guid.NewGuid(); 但是这个值会因重定向而丢失。

中间件如何通过重定向传递信息?我只需要将数字放在查询字符串中吗?

2 个答案:

答案 0 :(得分:2)

在中间件类中,您需要添加一个引用来访问所需的接口。我在一个单独的项目中有这个中间件,需要添加这个NuGet包。

using Microsoft.AspNetCore.Mvc.ViewFeatures;

然后,您可以在中间件中请求正确的服务。

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

拥有ITempDataDictionary后,您可以像在控制器中使用TempData一样使用它。

//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 :(得分:1)

您可以自己注册ITempDataProvider并在中间件中使用它。这是我在两个简单路径之间工作的一个小样本。如果您已经在使用MVC,则ITempDataProvider可能已经注册。我遇到的问题是编写的cookie的路径。它是/ page1所以/ page2无法访问cookie。所以我必须覆盖选项,如下面的代码所示。

我希望这会对你有所帮助:)。

Content += '<tbody>'; 
Content += '</tbody>'; 

这使我朝着正确的方向前进:https://docs.microsoft.com/en-us/aspnet/core/fundamentals/app-state#cookie-based-tempdata-provider

快乐的编码! :)