web-dev-qa-db-fra.com

Comment accéder globalement à l'objet HttpRequestMessage actuel?

J'ai une méthode qui crée un HttpResponseMessage contenant un objet Error qui sera renvoyé en fonction du formateur de type de support de demande actuel.

Actuellement, j'ai codé en dur le XmlMediaTypeFormatter, mais j'aimerais pouvoir trouver la requête actuelle MediaTypeFormatter au moment de l'exécution, mais je n'ai pas accès à l'objet de requête actuel car mon code ci-dessous existe sur une bibliothèque de classes distincte.

private HttpResponseMessage Create(HttpStatusCode statusCode, string errorCode, string errorMessage)
{
    var result = new HttpResponseMessage(statusCode)
        {
            Content = new ObjectContent<Error>(new Error()
            {
                Code = errorCode,
                Message = errorMessage
            }, new XmlMediaTypeFormatter())
        };
    return result;
}

Comment accéder globalement à l'objet HttpRequestMessage actuel? quelque chose comme HttpContext.Current.Request

Si cela est impossible, comment implémenter la méthode ci-dessus afin qu'il sache quel formateur il doit utiliser pour la requête en cours?

38
The Light

Ce n'est pas impossible comme je viens de le découvrir. Il est en fait ajouté à la propriété Items du HttpContext actuel (s'il y en a un) = [

HttpRequestMessage httpRequestMessage = HttpContext.Current.Items["MS_HttpRequestMessage"] as HttpRequestMessage

Modifier:

C'est à partir de WebAPI v2 .. Je ne peux pas être sûr des versions précédentes.

72
dariusc

Pourquoi ne pas faire ce que l'équipe d'API Web a fait avec sa méthode CreateResponse? Faites-en une méthode d'extension de Controller. De cette façon, vous pouvez toujours avoir le code dans une bibliothèque de classes distincte, mais votre méthode aura accès à l'instance de contrôleur et donc à toutes les informations de configuration.

Et sur une note légèrement différente, je vous suggère de vous pencher sur certains des efforts de normalisation des réponses d'erreur plutôt que d'inventer les vôtres.

par exemple.:

1
Darrel Miller

Vous pouvez essayer de l'archiver avec Autofac, par exemple

public class MyPrincipal : IPrincipal
    {
        private readonly IPrincipal principal_;

        public MyPrincipal(ILifetimeScope scope)
        {
            if (scope.Tag == null || scope.Tag != MatchingScopeLifetimeTags.RequestLifetimeScopeTag)
            {
                throw new Exception("Invalid scope");
            }

            principal_ = scope.Resolve<HttpRequestMessage>().GetRequestContext().Principal;
        }
}

Cette classe peut être enregistrée avec la durée de vie InstancePerRequest.

   builder.RegisterType<MyPrincipal>().As<IPrincipal>().InstancePerRequest();
0
Lonli-Lokli