如何使用中间件代替控制器初始化?

时间:2017-02-16 12:23:18

标签: c# asp.net asp.net-core

我正在将我的ASP.Net应用程序迁移到ASP.Net核心,我所拥有的一个功能是我的所有控制器都继承自我所做的基本控制器:

protected override void Initialize(HttpControllerContext controllerContext)
{
    base.Initialize(controllerContext);

    string token = controllerContext.Request.Properties["token"] as string;
    user = UserCache.Get(token);

    //Called by derived controllers
    //to set their repository user
    SetInfo();
}

我是否需要将上述代码移至中间件?中间件是否允许我调用控制器的SetInfo()方法?

2 个答案:

答案 0 :(得分:1)

在第一部分中,您似乎正在提取用于身份验证的令牌。可以将中间件配置为在控制器操作之前运行,但这是如何将信息传递给控制器​​的问题。例如,身份验证中间件只需设置HttpRequest的Principal,然后可以在控制器执行期间重用它。

关于SetInfo,如果明确取决于信息的性质,是否使用中间件来做这件事是个好主意,但它是可行的。例如,在我的情况下,为了在开发中调试原因,我有一个中间件通过在HttpContext中添加它来传输我的会话何时到期我的控制器的信息。我不是说这是一个很好的做法。

context.Request.HttpContext.Items.Add(ExpiresUTCEntry, context.Properties.ExpiresUtc);

答案 1 :(得分:0)

为什么不将它变成懒惰的控制器属性?

它很好,因为如果你不使用它,现在你不会让用户退出缓存。

private User _user;
public User user { get { return _user ?? (_user = UserCache.Get(this.Request.Properties["token"])); } }

在构造函数

上调用初始值设定项

关于SetInfo()

我建议将此代码移动到构造函数或其他位置(取决于此函数的内容)。 Controller在Router完成工作后创建。由IControllerFactory。您可以延长DefaultControllerFactory。该类负责创建控制器实例。 (请务必在IServiceCollection中注册,否则您的课程不是已解决的课程。

在你的情况下,我认为最好在这里重新思考你的架构,并专注于尽可能无状态,而不是使用下面描述的反模式之一。

信息MVC请求管道

这就是请求管道在mvc中的工作方式(并且仍在aspnetCore中工作)。 enter image description here 来自dotnetCurry

的图片

在管道中更早地访问用户

如果您想在请求管道中早些时候访问用户,我建议:

  • @dabouls回答:添加中间件以在Http.Items中注入它
  • 创建一个UserRepository类并将其注册到Ioc容器中的请求范围。 +使用HttpContextAccessor,但访问HttpContext.Current通常是一种反模式,不鼓励。