Как лучше всего закодировать в автономном ServiceStack, когда мы не можем провести сеанс из-за нулевого запроса?
-
21-12-2019 - |
Вопрос
Я использую ServiceStack 3.9.71.Я перехожу на автономный маршрут, чтобы иметь возможность развертывать в Linux и при этом избегать проблемы с утечкой памяти, изводящие Mono.
Проблема с автономным сервисом заключается в том, что у нас больше нет запроса.Без этого у нас тоже не будет сеанса.Попытки получить сеанс завершатся неудачей с
Поддерживаются только ASP.NET Запросы, доступные через синглтоны
из-за нулевого объекта запроса.
Вопросы таковы:
- Кто-нибудь может объяснить, почему мы не можем получить запрос в автономной службе ServiceStack?
- Как нам это обойти?
Например, если службе необходимо знать данные пользователя (например, что у нас было бы в ICustomAuthSession), который вызвал запрос, как нам это сделать?Я вижу, что кэш на самом деле содержит сеанс, но поскольку у нас нет запроса, то нет ключа сеанса, который мы могли бы использовать для извлечения сеанса из кэша.Я в некотором роде вижу некоторые обсуждение работаю над этим, но не могу до конца понять, что именно нужно делать.
Решение
Автономные приложения ServiceStack имеют доступ к запросу и сеансам таким же образом, как и приложения ServiceStack IIS.
Доступ к запросу
Автономные приложения используют HttpListenerRequest
класс для обработки HTTP-запросов, но ServiceStack абстрагирует это в IHttpRequest
, который обеспечивает согласованный способ доступа к данным HTTP-запроса либо между IIS, либо между автономными приложениями.
Если вы находитесь в сервисе ServiceStack, то вы можете получить доступ к IHttpRequest
через base.Request
объект. Видеть ServiceBase.cs для методов, предусмотренных базой данных Service
.
public class MyService : Service
{
// Your action method
public object Get(MyRequest request)
{
// Access to the request
var request = base.Request;
}
}
Или объект запроса предоставляется вам во время фильтры запросов:
this.RequestFilters.Add((httpReq, httpResp, requestDto) => {
// Access to the request through httpReq
});
Редко бывает, чтобы вам понадобился доступ к исходному базовому запросу, поскольку абстракция, предоставляемая IHttpRequest
должно охватывать вас в большинстве случаев.Но если вы хотите, например, получить доступ к сертификату клиента requests, вы можете получить это из базового запроса.Вы можете сделать это, приведя в действие IHttpRequest.OriginalRequest
:
var originalRequest = IHttpRequest.OriginalRequest as HttpListenerRequest;
if(originalRequest != null)
{
// Example of accessing the client certificate
var certificate = originalRequest.GetClientCertificate();
}
Доступ к сеансу
Похоже, вы неправильно обращаетесь к сеансу.Если вы используете Servicestack's SessionFeature
, который используется AuthenticationFeature
тогда вам не нужно беспокоиться о получении SessionID и последующем поиске значений из клиента кэша, ServiceStack имеет встроенные методы для обработки доступа к сеансу.
Существуют различные способы доступа к сеансу в зависимости от того, используете ли вы аутентификацию ServiceStack, которая предоставляет собственный механизм сеанса пользователя, или используете простое хранилище значений ключей, аналогичное стандартному хранилищу значений ключей ASP.NET .Ты можешь узнайте больше о сеансах здесь.
Простой кэш с резервной копией Хранилище значений ключей (Нетипизированный пакет сеансов):
public class MyService : Service
{
public object Get(MyRequest request)
{
// Set
Session.Set<int>("Age",123);
// Retrieve
var age = Session.Get<int>("Age");
}
}
Используя сеанс, предоставляемый функцией аутентификации ServiceStack, т.е. IAuthSession
:
public class MyService : Service
{
public object Get(MyRequest request)
{
// Provides access to the IAuthSession user session (if you are using the authentication feature)
var session = base.GetSession();
session.FirstName = "John";
}
}
Используя пользовательский тип сеанса с функцией аутентификации ServiceStack (что, по-видимому, является тем, что вы пытаетесь сделать).
public class MyService : Service
{
public object Get(MyRequest request)
{
var mySession = SessionAs<MySession>();
mySession.FirstName = "Clark";
mySession.LastName = "Kent";
mySession.SuperheroIdentity = "Superman";
}
}
public class MySession : AuthUserSession
{
public string SuperheroIdentity { get; set; }
}
Я надеюсь, что это поможет.