Тело запроса доступа в УСПОКОИТЕЛЬНОМ сервисе WCF

Я предпочитаю использовать исключения для обработки ошибок и возвращаемых значений (или параметры) как нормальный результат функции. Это дает легкую и последовательную схему обработки ошибок, и, если сделано правильно она делает для намного более чисто выглядящего кода.

17
задан urini 17 August 2009 в 12:53
поделиться

3 ответа

Приношу свои извинения за предыдущий ответ, я глупо предположил, что я только что применил 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. Я смутно припоминаю, что он всегда был пуст и этот неприятный процесс был единственным способом получить экземпляр, который действительно содержал действительные данные.

0
ответ дан 30 November 2019 в 12:51
поделиться

На мой взгляд, лучший способ не связан с WebOperationContext

[OperationContract]
[WebInvoke(Method = "POST", UriTemplate = "EntryPoint", BodyStyle = WebMessageBodyStyle.Bare)]
MyData GetData(System.IO.Stream pStream);
11
ответ дан 30 November 2019 в 12:51
поделиться

Похоже, что поскольку WCF не зависит от транспортного протокола, метод службы по умолчанию не предоставляет доступ к информации, относящейся к HTTP. Однако я только что наткнулся на хорошую статью, описывающую «Режим совместимости с ASP.Net», которая, по сути, позволяет вам указать, что ваша служба действительно предназначена для предоставления через HTTP.

http://blogs.msdn.com/b/wenlong/archive/2006/01/23/516041.aspx

Добавление конфигурации aspNetCompatibilityEnabled в Web.config в сочетании с атрибутом AspNetCompatibilityRequirements для желаемых операций службы должны помочь. Я собираюсь попробовать это сам.

Хав-Бин

1
ответ дан 30 November 2019 в 12:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: