Как получить доступ к текущему объекту HttpRequestMessage во всем мире?
У меня есть метод, который создает HttpResponseMessage, содержащий объект Error, который будет возвращен на основе форматера текущего типа запроса.
В настоящее время я жестко закодировал XmlMediaTypeFormatter, но мне бы хотелось найти текущий запрос MediaTypeFormatter во время выполнения, но у меня нет доступа к текущему объекту запроса, так как мой ниже код существует в отдельной библиотеке классов.
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;
}
Как получить доступ к текущему объекту HttpRequestMessage глобально? что-то вроде HttpContext.Current.Request
Если это невозможно, как реализовать описанный выше метод, чтобы он знал, какой форматтер он должен использовать для текущего запроса?
Ответы
Ответ 1
Это не невозможно, как я недавно узнал. Он фактически добавлен в свойство Items текущего HttpContext (если он есть) = [
HttpRequestMessage httpRequestMessage = HttpContext.Current.Items["MS_HttpRequestMessage"] as HttpRequestMessage
Edit:
Это касается WebAPI v2.. Я не могу быть уверен в предыдущих версиях.
Ответ 2
Почему бы не сделать то, что команда веб-API сделала с помощью метода CreateResponse? Сделайте его методом расширения контроллера. Таким образом, вы все равно можете иметь код в отдельной библиотеке классов, но ваш метод будет иметь доступ к экземпляру контроллера и, следовательно, ко всей информации о конфигурации.
И в несколько иной заметке я бы предложил вам изучить некоторые из мер по стандартизации для ответов об ошибках, а не изобретать свои собственные.
например:.
Ответ 3
Вы можете попробовать заархивировать его с помощью Autofac, например
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;
}
}
Этот класс может быть зарегистрирован с временем жизни InstancePerRequest.
builder.RegisterType<MyPrincipal>().As<IPrincipal>().InstancePerRequest();