Я понимаю, что сессия и REST точно не идут рука об руку, но нельзя ли получить доступ к состоянию сеанса с помощью нового Web API? HttpContext.Current.Session
всегда ноль.
asp.net
asp.net-web-api
отметка
источник
источник
[SessionState(SessionStateBehavior.Required)]
наApiController
делает трюк (или,.ReadOnly
где это уместно).Ответы:
Для проекта MVC внесите следующие изменения (ответ WebForms и Dot Net Core ниже):
WebApiConfig.cs
Global.asax.cs
Это решение имеет дополнительный бонус, который мы можем получить базовый URL в JavaScript для выполнения вызовов AJAX:
_Layout.cshtml
и затем в наших файлах / коде Javascript мы можем сделать наши вызовы webapi, которые могут получить доступ к сеансу:
Выполните вышеописанное, но измените функцию WebApiConfig.Register, чтобы вместо нее использовать RouteCollection:
А затем вызовите следующее в Application_Start:
Добавьте пакет Microsoft.AspNetCore.Session NuGet и внесите следующие изменения в код:
Startup.cs
Вызовите методы AddDistributedMemoryCache и AddSession для объекта служб в функции ConfigureServices:
и в функции Configure добавьте вызов UseSession :
SessionController.cs
В вашем контроллере добавьте оператор использования вверху:
и затем используйте объект HttpContext.Session в вашем коде следующим образом:
теперь вы должны быть в состоянии ударить:
и затем, перейдя по этому URL, вытащите его:
Здесь можно найти больше информации о доступе к данным сеанса в ядре dot net: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/app-state.
Прочитайте ответ Саймона Уивера ниже относительно производительности. Если вы обращаетесь к данным сеанса внутри проекта WebApi, это может иметь очень серьезные последствия для производительности - я видел, как ASP.NET применяет задержку 200 мс для одновременных запросов. Это может привести к катастрофическим последствиям, если у вас много одновременных запросов.
Убедитесь, что вы блокируете ресурсы для каждого пользователя - аутентифицированный пользователь не должен иметь возможность получать данные из вашего WebApi, к которым у них нет доступа.
Прочитайте статью Microsoft по аутентификации и авторизации в ASP.NET Web API - https://www.asp.net/web-api/overview/security/authentication-and-authorization-in-aspnet-web-api.
Прочитайте статью Microsoft о том, как избежать хакерских атак на межсайтовые запросы. (Короче, проверьте метод AntiForgery.Validate) - https://www.asp.net/web-api/overview/security/preventing-cross-site-request-forgery-csrf-attacks
источник
Вы можете получить доступ к состоянию сеанса с помощью пользовательского RouteHandler.
Найдено здесь: http://techhasnoboundary.blogspot.com/2012/03/mvc-4-web-api-access-session.html
источник
Почему бы не использовать Session в WebAPI?
Производительность, производительность, производительность!
Есть очень хорошая и часто упускаемая из виду причина, по которой вам вообще не следует использовать Session в WebAPI.
ASP.NET работает, когда Session используется, чтобы сериализовать все запросы, полученные от одного клиента . Сейчас я не говорю о сериализации объектов - но запускаю их в порядке поступления и жду завершения каждого из них, прежде чем запускать следующий. Это делается для того, чтобы избежать неприятных условий потока / гонки, если два запроса каждый пытаются получить доступ к Сессии одновременно.
Так что же это значит для веб-API? Если у вас есть приложение, выполняющее много запросов AJAX, тогда только ОДИН сможет работать одновременно. Если у вас более медленный запрос, он будет блокировать всех остальных от этого клиента, пока он не будет завершен. В некоторых приложениях это может привести к очень заметному снижению производительности.
Поэтому вам, вероятно, следует использовать контроллер MVC, если вам абсолютно необходимо что-то из пользовательского сеанса и избежать ненужного снижения производительности при включении его для WebApi.
Вы можете легко проверить это сами, просто
Thread.Sleep(5000)
вставив метод WebAPI и включив Session. Выполните 5 запросов к нему, и на их выполнение уйдет всего 25 секунд. Без сеанса они займут чуть более 5 секунд.(То же самое относится и к SignalR).
источник
Ну, вы правы, REST без гражданства. Если вы используете сеанс, обработка станет с состоянием, последующие запросы смогут использовать состояние (из сеанса).
Для того, чтобы сеанс был перегидратирован, вам нужно будет предоставить ключ, чтобы связать состояние. В обычном приложении asp.net этот ключ предоставляется с помощью cookie (cookie-сессий) или параметра url (сессий без cookie).
Если вам нужен сеанс, забудьте про отдых, сеансы не имеют отношения к проектам на основе REST. Если вам нужен сеанс для проверки, используйте токен или авторизуйтесь по IP-адресам.
источник
Марк, если вы посмотрите на пример MVC nerddinner, логика будет почти такой же.
Вам нужно только извлечь cookie и установить его в текущем сеансе.
Global.asax.cs
Вы должны будете определить свой класс "SampleIdentity", который вы можете позаимствовать из проекта nerddinner .
источник
Чтобы исправить проблему:
в Global.asax.cs
источник
Последний сейчас не работает, возьми этот, он работал для меня.
в WebApiConfig.cs на App_Start
Global.asax
Четвертый здесь: http://forums.asp.net/t/1773026.aspx/1
источник
Исходя из ответа LachlanB, если ваш ApiController не находится в определенном каталоге (например, / api), вы можете вместо этого протестировать запрос, используя RouteTable.Routes.GetRouteData, например:
источник
У меня была такая же проблема в asp.net mvc, я исправил ее, поместив этот метод в свой базовый контроллер API, от которого наследуются все мои контроллеры API:
Затем в вызове API вы хотите получить доступ к сеансу, который вы просто делаете:
У меня также есть это в моем файле Global.asax.cs, как и другие люди, не уверен, если вам все еще нужно, используя метод, описанный выше, но здесь это на всякий случай:
Вы также можете просто создать собственный атрибут фильтра, который вы можете прикрепить к вызовам API, для которого вам нужен сеанс, затем вы можете использовать сеанс в вызове API, как обычно, через HttpContext.Current.Session ["SomeValue"]:
Надеюсь это поможет.
источник
Я следовал подходу @LachlanB, и действительно, сессия была доступна, когда в запросе присутствовал сессионный cookie. Недостающая часть - как файл cookie сеанса отправляется клиенту в первый раз?
Я создал HttpModule, который не только включает доступность HttpSessionState, но и отправляет cookie клиенту при создании нового сеанса.
источник
В ответе @LachlanB нужно упомянуть одну вещь.
Если вы пропустите строку
if (IsWebApiRequest())
Весь сайт будет иметь проблемы с медлительностью загрузки страницы, если ваш сайт смешан со страницами веб-формы.
источник
Да, сессия не идет рука об руку с Rest API, и мы также должны избегать этой практики. Но в соответствии с требованиями нам нужно как-то поддерживать сеанс так, чтобы в каждом запросе клиентский сервер мог обмениваться или поддерживать состояние или данные. Таким образом, лучший способ достичь этого без нарушения протоколов REST - это общение через токен, такой как JWT.
https://jwt.io/
источник
Возвращаясь к основам, почему бы не сделать это простым и сохранить значение Session в скрытом значении html для передачи вашему API?
контроллер
cshtml
Javascript
$ (документ) .ready (function () {
}
источник