Przepraszam za poprzednią odpowiedź, Głupio założyłem, że właśnie rzuciłem WebOperationContext, aby uzyskać w OperationContext, niestety prawdziwa odpowiedź jest o wiele bardziej brzydka.
Pozwolę sobie z tym opowiedzieć, musi być lepszy sposób!
Najpierw utworzyłem własny obiekt kontekstu, który można dołączyć do istniejącego obiektu OperationContext.
public class TMRequestContext : IExtension<OperationContext> {
private OperationContext _Owner;
public void Attach(OperationContext owner) {
_Owner = owner;
}
public void Detach(OperationContext owner) {
_Owner = null;
}
public static TMRequestContext Current {
get {
if (OperationContext.Current != null) {
return OperationContext.Current.Extensions.Find<TMRequestContext>();
} else {
return null;
}
}
}
}
Aby móc uzyskać dostęp do tego nowego obiektu kontekstowego, należy dodać go jako rozszerzenie do bieżącego obiektu. Zrobiłem to, tworząc klasę inspektorów wiadomości.
public class TMMessageInspector : IDispatchMessageInspector {
public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext) {
OperationContext.Current.Extensions.Add(new TMRequestContext());
return null;
}
}
Aby inspektor komunikatów zadziałał, musisz utworzyć nowe "zachowanie". Zrobiłem to za pomocą następującego kodu.
public class TMServerBehavior : IServiceBehavior {
public void AddBindingParameters(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase, System.Collections.ObjectModel.Collection<ServiceEndpoint> endpoints, System.ServiceModel.Channels.BindingParameterCollection bindingParameters) {
//Do nothing
}
public void ApplyDispatchBehavior(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase) {
foreach (ChannelDispatcher chDisp in serviceHostBase.ChannelDispatchers) {
foreach (EndpointDispatcher epDisp in chDisp.Endpoints) {
epDisp.DispatchRuntime.MessageInspectors.Add(new TMMessageInspector());
}
}
}
}
Zachowanie powinny być w stanie dodać w pliku konfiguracyjnym, choć zrobiłem to poprzez stworzenie nowego gospodarza i dodanie obiektu zachowanie ręcznie w metodzie OnOpening. Skończyło się na użyciu tych klas o wiele więcej niż tylko dostęp do obiektu OperationContext. Użyłem ich do rejestrowania i przesłonięcia obsługi błędów i dostępu do obiektu żądania http, itp. A więc nie jest to aż tak absurdalne rozwiązanie, jak się wydaje. Prawie, ale nie do końca!
Naprawdę nie pamiętam, dlaczego nie mogłem uzyskać dostępu bezpośrednio do OperationContext.Current. Mam mgliste wspomnienie, że zawsze było puste i ten paskudny proces był jedynym sposobem, w jaki mogłem uzyskać instancję, która faktycznie zawiera prawidłowe dane.
Witam Darrel, Wypróbowałem twoją sugestię i wpadłem na kilka problemów. Kiedy użyłem twojego dokładnego kodu, dostałem ten błąd (podczas kompilacji): Nie można przekonwertować typu "System.ServiceModel.Web.WebOperationContext" na "System.ServiceModel.OperationContext" I kiedy zmieniłem go na ten kod: ciąg znaków = OperationContext.Current.RequestContext.RequestMessage.ToString(); Ciało było pustym ciągiem podczas uruchamiania. Jakieś pomysły? Dzięki, Uri – urini