我有一个使用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。
它包含许多关于Owin信息的键(一些键是 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?
}
}
答案 0 :(得分:1)
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;
};
}
}
答案 1 :(得分:0)
实际上,问you mentioned有一些你可能错过的提示。
对于Nancy,您必须使用NancyContext来访问Items字典 并查找与该键对应的值 “OWIN_REQUEST_ENVIRONMENT”。对于SignalR,环境属性 IRequest允许您访问OWIN环境。 一旦你有了OWIN 在环境中,您可以使用环境创建一个新的OwinContext。
所以,一旦你调用了var owinEnvironment = Context.GetOwinEnvironment()
并获得了字典,那么就可以创建OwinContext(这只是这些字典值的包装)
它有一个构造函数OwinContext(IDictionary<String, Object>)
,我猜,这是你需要的。
此外,您可以从OwinContext
获取HttpContext
:
// get owin context
var owinContext = HttpContext.Current.GetOwinContext();
// get user manager
var userManager = owinContext.GetUserManager<YourUserManager>();
答案 2 :(得分:0)
我最终通过创建新的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的简单概述。