Owin Selfhost用户上下文

时间:2015-10-03 11:34:54

标签: c# .net asp.net-web-api owin self-hosting

我使用常规的Microsoft asp webapi 2来创建web服务。 但是为了摆脱IIS-Express,我改用了owin-selfhost-package。

我现在唯一的问题是我找不到HTTPContext了。

在asp webapi 2中有效。

HttpContext.Current.Session;

现在

HttpContext.Current //is null

为空

我尝试了一些来自stackoverflow的建议,但没有使用它们。

例如:

var context = HttpContext.Current.GetOwinContext(); //Current is null
var context2 = Request.GetOwinContext();            //Request is null
var context3 = HttpContext.GetOwinContext();        //GetOwinContext is no known method
var Session    = HttpContext.Current.Session;       //Current is null

我做错了什么?

更新

我的Startup.cs

public class Startup
{
    private static readonly IUnityContainer _container = UnityHelpers.GetConfiguredContainer();

    public void Start()
    {
        UnityWebActivator.Start();
        var baseAddress = "http://localhost:10281/";
        var startupConfiguration = _container.Resolve<StartupConfiguration>();
        ConfigurationProvider.Init();

        // Start OWIN host
        using (WebApp.Start(baseAddress, startupConfiguration.Configuration))
        {
            Console.WriteLine("Host started and listens on {0}...", baseAddress);
            ////Create HttpCient and make a request to api/ values
            //var client = new HttpClient();

            //var response = client.GetAsync(baseAddress + "api/values").Result;

            //Console.WriteLine(response);
            //Console.WriteLine(response.Content.ReadAsStringAsync().Result);
            Console.ReadLine();
            UnityWebActivator.Shutdown();
        }

    }
}

我的StartupConfiguration.cs

public class StartupConfiguration
{
    private HttpConfiguration _config;

   public void Configuration(IAppBuilder appBuilder)
    {
        Console.WriteLine("Config started...");
        _config = new HttpConfiguration();

        // Add Unity filters provider
        RegisterFilterProviders(_config);

        ConfigureRoutes();
        ConfigureJsonSerialization();
        ConfigureFileSystemUse(appBuilder);


        appBuilder.UseWebApi(_config);

    }

   private static void RegisterFilterProviders(HttpConfiguration config)
   {
       config.DependencyResolver = new UnityDependencyResolver(UnityHelpers.GetConfiguredContainer());

       // Add Unity filters provider
       var providers = config.Services.GetFilterProviders().ToList();
       config.Services.Add(typeof(System.Web.Http.Filters.IFilterProvider), new WebApiUnityActionFilterProvider(UnityHelpers.GetConfiguredContainer()));
       var defaultprovider = providers.First(p => p is ActionDescriptorFilterProvider);
       config.Services.Remove(typeof(System.Web.Http.Filters.IFilterProvider), defaultprovider);
   }

    private void ConfigureRoutes()
    {
        _config.Routes.MapHttpRoute(
           name: "DefaultApi",
           routeTemplate: "{controller}/{id}", //routeTemplate: "api/{controller}/{id}",
           defaults: new { id = RouteParameter.Optional }
       );


        _config.MapHttpAttributeRoutes();
    }

    private void ConfigureJsonSerialization()
    {
        //JSon-Support
        _config.Formatters.Clear();
        _config.Formatters.Add(new JsonMediaTypeFormatter());
        _config.Formatters.JsonFormatter.SerializerSettings = new JsonSerializerSettings();
    }

    private void ConfigureFileSystemUse(IAppBuilder appBuilder)
    {
        var directories = new List<string>
        {
            "web",
            "../../web",
            "../../../webservice/web"
        };

        var path = "";
        foreach (var directory in directories)
        {
            if (Directory.Exists(directory))
            {
                path = directory;
                break;
            }
        }

        var fileSystem = new PhysicalFileSystem(path);

        var options = new FileServerOptions
        {
            EnableDirectoryBrowsing = true,
            EnableDefaultFiles = true,
            DefaultFilesOptions = { DefaultFileNames = { "index.html" } },
            FileSystem = fileSystem,
            StaticFileOptions =
            {
                ServeUnknownFileTypes = true,
                FileSystem = fileSystem

            }
        };

        appBuilder.UseFileServer(options);
    }

}

1 个答案:

答案 0 :(得分:3)

我终于找到了解决这个问题的方法(谢谢罗伯特!)。

按照Robert发布​​的https://stackoverflow.com/a/27826059/2843504

链接

以下是链接内容的副本:

创建这些类:

public class CurrentRequest
{
    public HttpRequestMessage Value { get; set; }
}

public class CurrentRequestHandler : DelegatingHandler
{
    protected async override System.Threading.Tasks.Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
    {
        var scope = request.GetDependencyScope();
        var currentRequest = (CurrentRequest)scope.GetService(typeof(CurrentRequest));
        currentRequest.Value = request;
        return await base.SendAsync(request, cancellationToken);
    }
}

然后你只需要注册DelegatingHandler:

httpConfiguration.MessageHandlers.Insert(0, new CurrentRequestHandler());

在Container

中注册CurrentRequest和IOwinContext
container.RegisterType<CurrentRequest>(
            new HierarchicalLifetimeManager());

container.RegisterType<IOwinContext>(
    new HierarchicalLifetimeManager(),
    new InjectionFactory(c => c.Resolve<CurrentRequest>().Value.GetOwinContext()));

httpConfiguration.DependencyResolver = new UnityHierarchicalDependencyResolver(container);

除了自定义委托处理程序之外,还有其他地方可以挂钩到Web.API来捕获HttpRequestMessage,例如,您可以创建自己的IHttpControllerActivator并使用如下所述的ExecuteAsync方法:ASP.NET Web API 2中的依赖注入