¿Cuál es la mejor manera de codificar en ServiceStack autohospedado cuando no podemos tener una sesión debido a una solicitud nula?

StackOverflow https://stackoverflow.com//questions/25049848

  •  21-12-2019
  •  | 
  •  

Pregunta

Estoy usando ServiceStack 3.9.71.Voy a optar por la ruta autohospedada para poder implementar en Linux y aun así poder evitar el Problemas de pérdida de memoria que afectan a Mono.

El problema con el servicio autohospedado es que ya no tenemos la solicitud.Sin él, tampoco tenemos sesión.Los intentos de obtener la sesión fallarán con

Solo se admiten solicitudes ASP.NET accesibles a través de Singletons

debido a un objeto de solicitud nulo.

Las preguntas son:

  1. ¿Alguien puede explicar por qué no podemos tener la solicitud en el servicio ServiceStack autohospedado?
  2. ¿Cómo lo solucionamos?

Por ejemplo, si el servicio necesita conocer los detalles del usuario (por ejemplo, qué tendríamos en ICustomAuthSession) que invocó la solicitud, ¿cómo lo hacemos?Puedo ver que la caché en realidad contiene la sesión, pero como no tenemos la solicitud, no hay ninguna clave de sesión que podamos usar para obtener la sesión de la caché.De alguna manera veo algunos discusión en él, pero no puedo entender qué hacer exactamente.

¿Fue útil?

Solución

Las aplicaciones ServiceStack autohospedadas tienen acceso a la Solicitud y a las Sesiones de la misma manera que las aplicaciones ServiceStack IIS.

Accediendo a la Solicitud

Las aplicaciones autohospedadas utilizan el HttpListenerRequest clase para manejar las solicitudes HTTP, pero ServiceStack abstrae esto en un IHttpRequest, que proporciona una forma coherente de acceder a los datos de la solicitud HTTP, ya sea entre IIS o aplicaciones autohospedadas.

Si está en un servicio ServiceStack, puede acceder al IHttpRequest a través de base.Request objeto. Ver ServiceBase.cs para los métodos proporcionados por la base de Service.

public class MyService : Service
{
    // Your action method
    public object Get(MyRequest request)
    {
        // Access to the request
        var request = base.Request;
    }
}

O el objeto de la solicitud se le proporciona durante los filtros de solicitud:

this.RequestFilters.Add((httpReq, httpResp, requestDto) => {

    // Access to the request through httpReq 

});

Es raro que necesites acceso a la solicitud subyacente original, ya que la abstracción proporcionada por IHttpRequest debería cubrirlo en la mayoría de los casos.Pero si desea, por ejemplo, acceder al certificado del cliente solicitado, puede obtenerlo de la solicitud subyacente.Puedes hacer esto lanzando el IHttpRequest.OriginalRequest:

var originalRequest = IHttpRequest.OriginalRequest as HttpListenerRequest;
if(originalRequest != null)
{
    // Example of accessing the client certificate
    var certificate = originalRequest.GetClientCertificate();
}   

Accediendo a la sesión

Parece que no estás accediendo a la sesión correctamente.Si está utilizando ServiceStack SessionFeature, que es utilizado por el AuthenticationFeature entonces no tiene que preocuparse por recuperar el SessionId y luego buscar valores del cliente de caché, ServiceStack tiene métodos integrados para manejar el acceso a la sesión.

Hay diferentes formas de acceder a la sesión dependiendo de si está utilizando la autenticación de ServiceStack, que proporciona su propio mecanismo de sesión de usuario, o si está utilizando el almacenamiento de valores clave simple análogo al almacén de sesión de valores clave estándar de ASP.NET.Puede aprende más sobre las sesiones aquí.

El caché simple respaldado Tienda de valores clave (Bolsa de sesión sin escribir):

public class MyService : Service
{
    public object Get(MyRequest request)
    {
        // Set
        Session.Set<int>("Age",123);

        // Retrieve
        var age = Session.Get<int>("Age");        
    }
}

Usando la sesión proporcionada por la función de autenticación de ServiceStack, es decir 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";
    }
}

Usar un tipo de sesión personalizado con la función de autenticación de ServiceStack (que parece ser lo que está intentando hacer).

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; }
}

Espero que esto ayude.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top