在 NancyContext 中找不到 OwinContext
Can't find OwinContext in NancyContext
我有一个使用 Nancy 的自托管 Owin 应用程序。在其中一个 NancyModules 中,我需要获取 IOwinContext
.
的实例
这个问题涉及主题,但没有解决方案:Get current owin context in self host mode
它说对于 Nancy,您必须使用 NancyContext 获取 Items 字典并查找与键 "OWIN_REQUEST_ENVIRONMENT" 对应的值。
我可以访问 NancyContext,我可以看到 Items 字典,它包含一个名为 "OWIN_REQUEST_ENVIRONMENT" 的键。 (我也可以调用 NancyContext.GetOwinEnvironment()
扩展,它给出相同的结果
但是,当我获得该密钥时,它不包含实际的 IOwinContext。
里面包含了很多关于欧文信息的keys(部分keys是owin.RequestPath,owin.RequestMethod、owin.CallCancelled 等),但不是实际的上下文对象。而且它实际上只是一个具有各种键的字典,所以我也不能将它转换为 IOwinContext。
如何从 NancyContext 获取 IOwinContext 对象?
public class MyStartup
{
public void Start()
{
var options = new StartOptions()
options.Urls.Add(new Uri("http://*:8084"));
options.AppStartup(this.GetType().AssemblyQualifiedName;
var host = WebApp.Start(options, Configuration);
}
public void Configuration(IAppBuilder app)
{
app.UseNancy();
}
}
public class MyModule : NancyModule
{
Get["/", true] = async(x, ct) =>
{
var owinEnvironment = Context.GetOwinEnvironment();
// Now what?
}
}
实际上,问题 you mentioned 有一些您可能错过的提示。
For Nancy, you have to use NancyContext to get to the Items dictionary
and look for the value corresponding to the key
"OWIN_REQUEST_ENVIRONMENT". For SignalR, Environment property of
IRequest gives you access to OWIN environment. Once you have the OWIN
environment, you can create a new OwinContext using the environment.
因此,一旦您调用 var owinEnvironment = Context.GetOwinEnvironment()
并获得字典,您就可以创建 OwinContext(它只是这些字典值的包装器)
它有一个构造函数 OwinContext(IDictionary<String, Object>)
,我想这就是您所需要的。
此外,您可以从 HttpContext
:
得到 OwinContext
// get owin context
var owinContext = HttpContext.Current.GetOwinContext();
// get user manager
var userManager = owinContext.GetUserManager<YourUserManager>();
我最终通过创建新的 Owin 中间件解决了这个问题。在中间件中,您可以访问当前的 Owin 上下文,这使您可以访问 Owin 环境。
当您有权访问 Owin 环境时,只需将 Owin 上下文添加到环境中即可。当上下文在环境中时,您可以在 NancyModule 中检索它。
像这样检索它之后,我还可以访问上下文中的 GetUserManager() 方法,这样我就可以获得我的 AspNetIdentity 管理器(正如我在对另一个答案的评论中提到的)。请记住,中间件必须在 Nancy 之前添加到 Owin 管道。
启动
public class Startup
{
public void Start()
{
var options = new StartOptions()
options.Urls.Add(new Uri("http://*:8084"));
options.AppStartup(this.GetType().AssemblyQualifiedName;
var host = WebApp.Start(options, Configuration);
}
public void Configuration(IAppBuilder app)
{
app.Use(typeof(OwinContextMiddleware));
app.UseNancy();
}
}
中间件
public class OwinContextMiddleware : OwinMiddleware
{
public OwinContextMiddleware(OwinMiddleware next)
: base(next)
{
}
public async override Task Invoke(IOwinContext context)
{
context.Environment.Add("Context", context);
await Next.Invoke(context);
}
}
NancyModule
public class MyModule : NancyModule
{
public MyModule()
{
Get["/", true] = async(x, ct) =>
{
IDictionary<string, object> environment = Context.GetOwinEnvironment();
IOwinContext context = (IOwinContext)environment["Context"]; // The same "Context" as added in the Middleware
}
}
警告
上面列出的中间件未经测试,因为我拥有的中间件更复杂,而且我没有时间创建工作示例。我找到了关于如何创建 Owin 中间件的简单概述 on this page。
var owinContext = new OwinContext(Context.GetOwinEnvironment());
示例:
public class SecurityApi : NancyModule
{
public SecurityApi()
{
Post["api/admin/register", true] = async (_, ct) =>
{
var body = this.Bind<RegisterUserBody>();
var owinContext = new OwinContext(Context.GetOwinEnvironment());
var userManager = owinContext.GetUserManager<ApplicationUserManager>();
var user = new User {Id = Guid.NewGuid().ToString(), UserName = body.UserName, Email = body.Email};
var result = await userManager.CreateAsync(user, body.Password);
if (!result.Succeeded)
{
return this.BadRequest(string.Join(Environment.NewLine, result.Errors));
}
return HttpStatusCode.OK;
};
}
}
我有一个使用 Nancy 的自托管 Owin 应用程序。在其中一个 NancyModules 中,我需要获取 IOwinContext
.
这个问题涉及主题,但没有解决方案:Get current owin context in self host mode
它说对于 Nancy,您必须使用 NancyContext 获取 Items 字典并查找与键 "OWIN_REQUEST_ENVIRONMENT" 对应的值。
我可以访问 NancyContext,我可以看到 Items 字典,它包含一个名为 "OWIN_REQUEST_ENVIRONMENT" 的键。 (我也可以调用 NancyContext.GetOwinEnvironment()
扩展,它给出相同的结果
但是,当我获得该密钥时,它不包含实际的 IOwinContext。
里面包含了很多关于欧文信息的keys(部分keys是owin.RequestPath,owin.RequestMethod、owin.CallCancelled 等),但不是实际的上下文对象。而且它实际上只是一个具有各种键的字典,所以我也不能将它转换为 IOwinContext。
如何从 NancyContext 获取 IOwinContext 对象?
public class MyStartup
{
public void Start()
{
var options = new StartOptions()
options.Urls.Add(new Uri("http://*:8084"));
options.AppStartup(this.GetType().AssemblyQualifiedName;
var host = WebApp.Start(options, Configuration);
}
public void Configuration(IAppBuilder app)
{
app.UseNancy();
}
}
public class MyModule : NancyModule
{
Get["/", true] = async(x, ct) =>
{
var owinEnvironment = Context.GetOwinEnvironment();
// Now what?
}
}
实际上,问题 you mentioned 有一些您可能错过的提示。
For Nancy, you have to use NancyContext to get to the Items dictionary and look for the value corresponding to the key "OWIN_REQUEST_ENVIRONMENT". For SignalR, Environment property of IRequest gives you access to OWIN environment. Once you have the OWIN environment, you can create a new OwinContext using the environment.
因此,一旦您调用 var owinEnvironment = Context.GetOwinEnvironment()
并获得字典,您就可以创建 OwinContext(它只是这些字典值的包装器)
它有一个构造函数 OwinContext(IDictionary<String, Object>)
,我想这就是您所需要的。
此外,您可以从 HttpContext
:
OwinContext
// get owin context
var owinContext = HttpContext.Current.GetOwinContext();
// get user manager
var userManager = owinContext.GetUserManager<YourUserManager>();
我最终通过创建新的 Owin 中间件解决了这个问题。在中间件中,您可以访问当前的 Owin 上下文,这使您可以访问 Owin 环境。
当您有权访问 Owin 环境时,只需将 Owin 上下文添加到环境中即可。当上下文在环境中时,您可以在 NancyModule 中检索它。
像这样检索它之后,我还可以访问上下文中的 GetUserManager() 方法,这样我就可以获得我的 AspNetIdentity 管理器(正如我在对另一个答案的评论中提到的)。请记住,中间件必须在 Nancy 之前添加到 Owin 管道。
启动
public class Startup
{
public void Start()
{
var options = new StartOptions()
options.Urls.Add(new Uri("http://*:8084"));
options.AppStartup(this.GetType().AssemblyQualifiedName;
var host = WebApp.Start(options, Configuration);
}
public void Configuration(IAppBuilder app)
{
app.Use(typeof(OwinContextMiddleware));
app.UseNancy();
}
}
中间件
public class OwinContextMiddleware : OwinMiddleware
{
public OwinContextMiddleware(OwinMiddleware next)
: base(next)
{
}
public async override Task Invoke(IOwinContext context)
{
context.Environment.Add("Context", context);
await Next.Invoke(context);
}
}
NancyModule
public class MyModule : NancyModule
{
public MyModule()
{
Get["/", true] = async(x, ct) =>
{
IDictionary<string, object> environment = Context.GetOwinEnvironment();
IOwinContext context = (IOwinContext)environment["Context"]; // The same "Context" as added in the Middleware
}
}
警告
上面列出的中间件未经测试,因为我拥有的中间件更复杂,而且我没有时间创建工作示例。我找到了关于如何创建 Owin 中间件的简单概述 on this page。
var owinContext = new OwinContext(Context.GetOwinEnvironment());
示例:
public class SecurityApi : NancyModule
{
public SecurityApi()
{
Post["api/admin/register", true] = async (_, ct) =>
{
var body = this.Bind<RegisterUserBody>();
var owinContext = new OwinContext(Context.GetOwinEnvironment());
var userManager = owinContext.GetUserManager<ApplicationUserManager>();
var user = new User {Id = Guid.NewGuid().ToString(), UserName = body.UserName, Email = body.Email};
var result = await userManager.CreateAsync(user, body.Password);
if (!result.Succeeded)
{
return this.BadRequest(string.Join(Environment.NewLine, result.Errors));
}
return HttpStatusCode.OK;
};
}
}