Silverlight 3 и WCF: исключения

Как писал раньше, используя WCF и Silverlight 3, можно передавать ошибки сервера на клиент. Сейчас расскажу как это можно сделать.

Что же было до появления этой возможности? Если на сервере возникало исключение, оно заворачивалось в SOAP и отправлялось на клиент. Вот только в Silverlight-приложение в том виде как есть оно не попадало. Почему? Да потому, что браузер не пропускал. И вот почему. Браузер имеет стандартный набор ошибок и когда с сервера приходит код ответа не 200, браузер отображать сообщение согласно коду ответа. Когда же на стороне сервера возникает исключение, то по умолчанию код ответа присваивается 500 и в Silverlight-приложении мы видим сообщение "Not found". Хотя, если обращения к серверу мониторить Fiddler'ом, то можно получить общую информацию о серверной ошибке.

Сейчас же есть возможность передать в само Silverlight-приложение полную информацию об ошибке сервера. И так, приступим.

По накатаной схеме создаем Silverlight 3 приложение с Web-приложением для тестирования. В Web-приложение добавляем новый елемент Silverlight-enabled WCF Service . И в решение добавляем еще один проект Class Library. В Class Library создаем класс:

public class SilverlightFaultBehavior : BehaviorExtensionElement, IEndpointBehavior
    {
        
        public override Type BehaviorType
        {
            get { return typeof(SilverlightFaultBehavior); }
        }

        protected override object CreateBehavior()
        {
            return new SilverlightFaultBehavior();
        }

        #region IEndpointBehavior Members

        public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
        {

        }

        public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
        {

        }

        public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
        {
            SilverlightFaultMessageInspector inspector = new SilverlightFaultMessageInspector();
            endpointDispatcher.DispatchRuntime.MessageInspectors.Add(inspector);
        }

        public void Validate(ServiceEndpoint endpoint)
        {

        }

        #endregion

        public class SilverlightFaultMessageInspector : IDispatchMessageInspector
        {
            #region IDispatchMessageInspector Members

            public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
            {
                return null;
            }

            public void BeforeSendReply(ref Message reply, object correlationState)
            {
                if (reply.IsFault)
                {
                    HttpResponseMessageProperty property = new HttpResponseMessageProperty();
                    property.StatusCode = System.Net.HttpStatusCode.OK;
                    reply.Properties[HttpResponseMessageProperty.Name] = property;
                }
            }

            #endregion
        }
    }

SilverlightFaultMessageInspector – класс, который в случае ошибки обеспечит код ответа 200, тем самым обеспечит попадание всей информации об ошибке прямо в Silverlight-приложение.

BehaviorExtensionElement – абстрактный класс, который представляет конфигурацию елемента. Специфика данного елемента заключается в том, что он определяет дополнительное поведение сервиса или конечной точки. BehaviorType и CreateBehavior() абстрактные члены этого класса, которые возвращают тип поведения и объект типа поведения соответственно.

Реализуя интерфейс IEndpointBehavior нам важен лишь метод ApplyDispatchBehavior(), что бы добавить нашего “инспектора”. Остальные методы оставим пустыми.

Теперь необходимо в файле конфигурации Web-приложения зарегистрировать наше расширение поведения. Потом, в области конфигурации поведения конечной токи(endpointBehaviors) указать наше зарегистрированое расширение и непосредственно в описании конечной точки указать имя конфигурации поведения(в примере SilverlightFaultBehavior). Также нужно включить передачу ошибок на клиент <serviceDebug includeExceptionDetailInFaults="true"/>. Пример:

<system.serviceModel>
        <extensions>
            <behaviorExtensions>
                <add name="SilverlightFaults" 
                    type="SilverlightFaults.SilverlightFaultBehavior,
		 SilverlightFaults, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
            </behaviorExtensions>
        </extensions>
        <behaviors>
            <serviceBehaviors>
                <behavior name="Faults.Web.CalculatorServiceBehavior">
                    <serviceMetadata httpGetEnabled="true"/>
                    <serviceDebug includeExceptionDetailInFaults="true"/>
                </behavior>
            </serviceBehaviors>
            <endpointBehaviors>
                <behavior name="SilverlightFaultBehavior">
                    <SilverlightFaults/>
                </behavior>
            </endpointBehaviors>
        </behaviors>
        <bindings>
            <customBinding>
                <binding name="customBinding0">
                    <binaryMessageEncoding/>
                    <httpTransport/>
                </binding>
            </customBinding>
        </bindings>
        <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
        <services>
            <service behaviorConfiguration="Faults.Web.CalculatorServiceBehavior" name="Faults.Web.CalculatorService">
                <endpoint address="" binding="customBinding" bindingConfiguration="customBinding0" 
                    contract="Faults.Web.CalculatorService"
                    behaviorConfiguration="SilverlightFaultBehavior"/>
                <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
            </service>
        </services>
    </system.serviceModel>

 

После описанной конфигурации, все серверные ошибки можно будет получать в Silverlight-приложении с полным описанием. К тому же можно использовать механизм WCF’a c Fault.

Скачть пример.

Больше о передаче ошибок в Silverlight-приложение:

 Как видите, если выбирать между WCF-сервисами и Web-сервисами, то предпочтительнее использовать связку Silverlight и WCF

Опубліковані 23-05-2009 12:39 від Sergey Lutay
Зареєстрований як , , ,

Коментарі

 

progg.ru said:

Thank you for submitting this cool story - Trackback from progg.ru

May 22, 2009 11:07 PM
 

Территория блога said:

Как писал раньше , используя WCF и Silverlight 3, можно передавать ошибки сервера на клиент. Сейчас расскажу как это можно сделать. Что же было до появления этой возможности? Если на сервере возникало исключение, оно заворачивалось в SOAP и отправлялось...(

May 23, 2009 2:20 AM
Анонімні коментарі деактивовані. Увійдіть або Зареєструйтесь щоб мати доступ до ресурсів Спільноти.

Новини

Календар повідомлень

<May 2009>
SMTWTFS
262728293012
3456789
10111213141516
17181920212223
24252627282930
31123456

Пошук

Go

Категорії повідомлень

Синдикація

SkinName:iroha_Blog2