Пользовательское сообщение об ошибке для пользовательского WebServiceHost - PullRequest
1 голос
/ 01 октября 2010

У меня есть собственный сервисный узел WCF (webServicehost2) и фабрика, которая выполняет некоторое внедрение зависимости (реализует пользовательский IInstanceProvider), а также некоторую пользовательскую аутентификацию (препятствует пользовательскому RequestInterceptor).

У меня очень маленькая проблема, когда я перехожу к ресурсу REST, которого нет. например

http://localhost/restservice.svc/
http://localhost/restservice.svc/blah/

Я получаю 404 Error, хорошо, что ожидается.

Что я хотел бы знать, так это то, что я могу зафиксировать возвращающуюся ошибку Http и отформатировать ее немного лучше.

Ответы [ 2 ]

3 голосов
/ 01 октября 2010

Я не уверен, что есть более простой способ, но я сделал несколько быстрых прототипов здесь и обнаружил, что один из способов сделать это - добавить пользовательскую реализацию IDispatchMessageInspector, которая просматривает ответное сообщение службы и заменяет содержимое. со своей собственной HTML-страницей.

Это в основном так:

  • Реализация IDispatchMessageInspector.BeforeSendReply ()
  • Посмотрите ответное сообщение, возьмите свойство httpResponse и проверьте, не является ли оно ошибкой на основе свойства StatusCode .
  • Если это ошибка, создайте новое сообщение WCF, в теле которого будет указано содержимое HTML, которое вы хотите обслуживать.
  • Добавьте свойства httpResponse и webBodyFormatMessageProperty к новому сообщению и установите его в качестве ответа.

У меня есть мой образец, который делает это успешно, но это ужасно; Мне нужно немного его почистить, прежде чем публиковать.

1 голос
/ 04 октября 2010

Вот соответствующие фрагменты кода для тех, кто пытается это сделать

Сначала экземпляр IDispatchMessageInspector

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

        public void BeforeSendReply(ref Message reply, object correlationState)
        {
            var prop = (HttpResponseMessageProperty)reply.Properties[HttpResponseMessageProperty.Name];
            if (prop.StatusCode == HttpStatusCode.NotFound)
            {
                ErrorResponse(ref reply);
            }
        }

        private void ErrorResponse(ref Message original)
        {
            const string ERROR_HTML = @"<html><HEAD><TITLE>Request Error</TITLE></HEAD><BODY> <H1>My Error processing request {1}</H1><P>{0}</P></BODY></html>";

            XElement response = XElement.Load(new StringReader(string.Format(ERROR_HTML, "A Resource does not exsist at this location.", HttpStatusCode.NotFound)));
            Message reply = Message.CreateMessage(original.Version, null, response);
            reply.Headers.CopyHeadersFrom(original);
            reply.Properties.CopyProperties(original.Properties);
            original = reply;
        }
    }

Затем, чтобы вставить это в IServiceBehaviour Я добавил

ed.DispatchRuntime.MessageInspectors.Add(new CustomResponseFormatterMessageInspector());

В этом может быть другой код, который имеет отношение к моей реализации, но это все, что я добавил.

 public class DependencyInjectionServiceBehavior : IServiceBehavior
    {
        public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
        {
            foreach (ChannelDispatcherBase cdb in serviceHostBase.ChannelDispatchers)
            {
                var cd = cdb as ChannelDispatcher;
                if (cd != null)
                {
                    foreach (EndpointDispatcher ed in cd.Endpoints)
                    {
                        ed.DispatchRuntime.InstanceProvider =
                            new DependencyInjectionInstanceProvider(serviceDescription.ServiceType);
                        ed.DispatchRuntime.MessageInspectors.Add(new CustomResponseFormatterMessageInspector());
                    }
                }
            }
        }

        public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
        {
        }

        public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
        {
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...