Пользовательский контекст Owin Selfhost

Я использовал обычный Microsoft asp webapi 2 для создания веб-сервиса. Но чтобы избавиться от IIS-Express, я переключился на использование пакета owin-selfhost.

Моя единственная проблема сейчас в том, что я больше не могу найти 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);
    }

}

person Tobias Koller    schedule 03.10.2015    source источник
comment
Как вы настроили конфигурацию OWIN? Можете ли вы предоставить фрагмент кода для вашего класса Startup и т. д.?   -  person Robert Foster    schedule 03.10.2015
comment
привет Роберт. Пожалуйста, смотрите мой обновленный вопрос. спасибо   -  person Tobias Koller    schedule 03.10.2015
comment
Ознакомьтесь с этим ответом Stackoverflow — stackoverflow.com/a/27826059/2843504 — возможно, у вас есть некоторые подсказки. Кроме того, было бы полезно знать, где вы пытаетесь получить контекст.   -  person Robert Foster    schedule 03.10.2015
comment
Спасибо за линик. Я пытаюсь получить доступ к контексту в моем конструкторе-контроллере.   -  person Tobias Koller    schedule 03.10.2015


Ответы (1)


Наконец-то я нашел решение этой проблемы (спасибо, Роберт!).

Перейдите по ссылке, опубликованной Робертом 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());

И зарегистрируйте 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, как описано здесь: Внедрение зависимостей в веб-API ASP.NET 2

person Tobias Koller    schedule 04.10.2015