Я предпочитаю использовать исключения для обработки ошибок и возвращаемых значений (или параметры) как нормальный результат функции. Это дает легкую и последовательную схему обработки ошибок, и, если сделано правильно она делает для намного более чисто выглядящего кода.
Приношу свои извинения за предыдущий ответ, я глупо предположил, что я только что применил WebOperationContext, чтобы добраться до OperationContext, к сожалению, реальный ответ гораздо более уродливый.
Позвольте мне предварять это следующим: должен быть способ получше!
Сначала я создал свой собственный объект контекста, который можно было бы присоединить к существующему объекту 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;
}
}
}
}
Чтобы иметь возможность получить доступ к этому новому объекту контекста, вам нужно добавить его как расширение до текущего. Я сделал это, создав класс инспектора сообщений.
public class TMMessageInspector : IDispatchMessageInspector {
public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext) {
OperationContext.Current.Extensions.Add(new TMRequestContext());
return null;
}
}
Чтобы инспектор сообщений работал, вам нужно создать новое «поведение». Я сделал это с помощью следующего кода.
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());
}
}
}
}
Поведение, которое вы должны иметь возможность добавить в файл конфигурации, хотя я сделал это, создав новый хост и добавив объект поведения вручную в методе OnOpening. В итоге я использовал этот класс не только для доступа к объекту OperationContext. Я использовал их для регистрации и переопределения обработки ошибок и доступа к объекту HTTP-запроса и т. Д. Так что это не такое уж нелепое решение, как кажется. Почти, но не совсем!
Я действительно не помню, почему я не мог напрямую получить доступ к OperationContext.Current. Я смутно припоминаю, что он всегда был пуст и этот неприятный процесс был единственным способом получить экземпляр, который действительно содержал действительные данные.
Я помню, почему я не мог напрямую получить доступ к OperationContext.Current. Я смутно припоминаю, что он всегда был пуст, и этот неприятный процесс был единственным способом получить экземпляр, который действительно содержал действительные данные. Я помню, почему я не мог напрямую получить доступ к OperationContext.Current. Я смутно припоминаю, что он всегда был пуст и этот неприятный процесс был единственным способом получить экземпляр, который действительно содержал действительные данные.На мой взгляд, лучший способ не связан с WebOperationContext
[OperationContract]
[WebInvoke(Method = "POST", UriTemplate = "EntryPoint", BodyStyle = WebMessageBodyStyle.Bare)]
MyData GetData(System.IO.Stream pStream);
Похоже, что поскольку WCF не зависит от транспортного протокола, метод службы по умолчанию не предоставляет доступ к информации, относящейся к HTTP. Однако я только что наткнулся на хорошую статью, описывающую «Режим совместимости с ASP.Net», которая, по сути, позволяет вам указать, что ваша служба действительно предназначена для предоставления через HTTP.
http://blogs.msdn.com/b/wenlong/archive/2006/01/23/516041.aspx
Добавление конфигурации aspNetCompatibilityEnabled
в Web.config
в сочетании с атрибутом AspNetCompatibilityRequirements
для желаемых операций службы должны помочь. Я собираюсь попробовать это сам.
Хав-Бин