Как добавить собственные заголовки мыла в wcf?

Могу ли я добавить настраиваемый заголовок SOAP во входящие / исходящие сообщения WCF в basicHttpBinding, как мы можем добавить настраиваемый заголовок аутентификации в веб-службы ASMX? Эти настраиваемые заголовки SOAP должны быть доступны с использованием клиентов веб-служб .net 2.0 / 1.1 (доступных с помощью инструмента WSDL.EXE).


person nRk    schedule 29.12.2009    source источник
comment
обновил свой ответ информацией об инспекторах сообщений   -  person marc_s    schedule 30.12.2009
comment
снова обновил свой ответ, добавив информацию о совместимости ASMX / WCF в отношении заголовка SOAP.   -  person marc_s    schedule 30.12.2009
comment
спасибо marc_s, выглядит хорошо, я попробую.   -  person nRk    schedule 30.12.2009


Ответы (2)


Ознакомьтесь с дополнительными возможностями WCF на Codeplex - это простая библиотека расширений для WCF, которая, помимо прочего, предлагает настраиваемый протокол SOAP. заголовки.

Другой вариант - использовать контракты сообщений WCF в вашей службе WCF - это тоже позволяет легко определять и устанавливать заголовки WCF SOAP.

[MessageContract]
public class BankingTransaction
{
  [MessageHeader]
  public Operation operation;
  [MessageHeader] 
  public DateTime transactionDate;

  [MessageBodyMember] 
  private Account sourceAccount;
  [MessageBodyMember] 
  private Account targetAccount;
  [MessageBodyMember] 
  public int amount;
}

Здесь «операция» и «transactionDate» определены как заголовки SOAP.

Если ни один из этих методов не помогает, вам следует ознакомиться с концепцией инспекторов сообщений WCF, которые вы можете писать как расширения. Они позволяют, например, вставлять определенные заголовки в сообщение при каждом исходящем вызове на клиенте и извлекать их из сообщения на сервере для вашего использования.

См. Это сообщение в блоге Обработка настраиваемых заголовков SOAP через поведение WCF для отправной точки о том, как написать инспектор сообщений и как включить его в настройку вашего проекта.

На стороне клиента IClientMessageInspector определены два метода BeforeSendRequest и AfterReceiveReply, а на стороне сервера IDispatchMessageInspector есть противоположные методы, то есть AfterReceiveRequest и BeforeSendReply.

При этом вы можете добавлять заголовки к каждому сообщению, передаваемому по сети (или выборочно только к нескольким).

Вот фрагмент от разработчика IClientMessageInspector, который мы используем для автоматической передачи информации о локали (информации о языке и культуре) от клиентов к серверу - он должен дать вам представление о том, с чего начать:

public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
    International intlHeader = new International();
    intlHeader.Locale = CultureInfo.CurrentUICulture.TwoLetterISOLanguageName;

    MessageHeader header = MessageHeader.CreateHeader(WSI18N.ElementNames.International, WSI18N.NamespaceURI, intlHeader);
    request.Headers.Add(header);

    return null;
}

На стороне сервера вы затем проверяете наличие этих заголовков и, если они есть, извлекаете их из конверта SOAP и используете их.

ОБНОВЛЕНИЕ: хорошо, вы являетесь клиентами .NET 2.0 и не используете WCF - хорошие новости в том, что это все равно должно работать нормально - см. это сообщение в блоге Пользовательские заголовки SOAP: WCF и ASMX для подробностей. Вы по-прежнему можете использовать инспектор сообщений на стороне сервера для прослушивания и извлечения настраиваемых заголовков, отправляемых вашими клиентами .NET 2.0.

person marc_s    schedule 29.12.2009
comment
Спасибо marc_s, я попытался использовать WCF Extras, я добавил атрибут XmlSerializerFormat в Service Contract WCF Extras throw error при доступе к Services. Есть ли другое решение, например WCF Extras? Могу ли я добавить MessageContract в качестве атрибута к каждому методу, когда я добавил SoapHeader в службы ASMX? Мое требование состоит в том, что мне нужно отправлять некоторые (такие же, например, имя пользователя и пароль) данные для каждого вызова службы WCF. Есть ли способ реализовать это? - person nRk; 30.12.2009
comment
yah marc_s, выглядит здорово. но в упомянутой статье клиент должен быть в .net 3.0 или выше .. но в моем случае клиенты находятся в .net 2.0 и 1.1. Возможно ли еще реализовать это? - person nRk; 30.12.2009

Для меня это решение было проще:

            var client = "Your Service Client"; 
            using (var scope = new OperationContextScope(client.InnerChannel))
            {
                System.Xml.XmlDocument document = new XmlDocument();
                XmlElement element = document.CreateElement("wsse", "UsernameToken", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");

                XmlElement newChild = null;
                newChild = document.CreateElement("wsse", "Username", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
                newChild.InnerText = "finance";
                element.AppendChild(newChild);

                newChild = document.CreateElement("wsse", "CorporationCode", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
                newChild.InnerText = "387";
                element.AppendChild(newChild);

                MessageHeader messageHeader = MessageHeader.CreateHeader("UsernameToken", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", element, false);

                OperationContext.Current.OutgoingMessageHeaders.Add(messageHeader);

                var result = client.GetCorporations(new CorporationType { pageNo = 1 });
            }
person B.Tekkan    schedule 08.11.2018