#c# #wcf #soap
#c# #wcf #soap
Вопрос:
У меня есть служба WCF, которая является производной от WSDL, предоставленного поставщиком. Когда клиент поставщика обращается к моей службе, он получает сообщение об ошибке « The message with Action '' cannot be processed at the receiver, due to a ContractFilter mismatch at the EndpointDispatcher.
«
Я хотел бы просмотреть входящее сообщение SOAP до того, как будет выдана эта ошибка.
Я попытался создать атрибут с помощью IServiceBehavior
:
[AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = false)]
public sealed class AuditServiceBehavior : Attribute, IServiceBehavior
{
public AuditServiceBehavior() { }
public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
{
Trace.TraceInformation("AuditService.AddBindingParameters called.");
}
public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
// Seems like the right place to invoke something?
Trace.TraceInformation("AuditService.ApplyDispatchBehavior called.");
}
}
Добавление этого атрибута в мою реализацию сервиса позволяет мне видеть сообщения трассировки, но они появляются при запуске службы. Я добавил атрибут с IOperationBehavior
, но, похоже, все методы здесь выполняются после разрешения контрактов.
Что мне нужно сделать, чтобы увидеть входящее SOAP?
Комментарии:
1. Взгляните на трассировку WCF и, в частности, на протоколирование сообщений . Когда вы регистрируете сообщения на транспортном уровне, я полагаю, вы должны иметь возможность прочитать ваше сообщение (если вы не используете потоковый транспорт)
Ответ №1:
Вы могли бы настроить ActionMessageFilter , ActionMessageFilter используется для сопоставления действия сообщения soap.
public class MyActionMesageFilter:ActionMessageFilter
{
public MyActionMesageFilter(params string[] actions):base(actions)
{
}
public override bool Match(Message message)
{
string mes = message.ToString();
bool re = base.Match(message);
string action = message.Headers.Action;
return re;
}
}
Добавьте поведение конечной точки.
public class ReplaceActionFilterEndpointBehavior : IEndpointBehavior
{
public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
{
}
public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
}
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
endpointDispatcher.AddressFilter = new MyActionMesageFilter("http://tempuri.org/IEmployeeService/GetEmployee");
}
public void Validate(ServiceEndpoint endpoint)
{
}
}
И хост.
using (ServiceHost host = new ServiceHost(typeof(Service.EmployeeService)))
{
host.Description.Endpoints[0].EndpointBehaviors.Add(new ReplaceActionFilterEndpointBehavior());
host.Opened = delegate
{
Console.WriteLine("hello");
};
host.Open();
Console.Read();
}
Результат.
Для получения дополнительной информации о настройке ActionMessageFilter вы могли бы обратиться к https://learn.microsoft.com/en-us/dotnet/framework/wcf/samples/custom-message-filter