locked
WCF MessageContract help. RRS feed

  • Question

  • User-1753096817 posted

    I need to recreate the following soap message from a returning WCF messagecontract class.

    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
                      xmlns:urn="urn:nu:services:schema:message:common:nuiesbmetadata:v01"
                      xmlns:urn1="urn:nu:services:schema:message:common:nuiesbcontext:v01"
                      xmlns="urn:uk:gi:dis:supplierengagement:v02">
        <soapenv:Header>
            <urn:ESBMetaData>
                <urn:OriginalServiceCallerID>SomeUser</urn:OriginalServiceCallerID>
            </urn:ESBMetaData>
            <urn1:ESBContext soapenv:mustUnderstand="1">
                <urn1:BusinessContextType>FunctionName</urn1:BusinessContextType>
                <urn1:BusinessContextInstanceId>uuid:7dc57353-9069-442d-8b69-163f676dd3e3</urn1:BusinessContextInstanceId>
                <urn1:ServiceRequestId>uuid:7dc57353-9069-442d-8b69-163f676dd3e3</urn1:ServiceRequestId>
            </urn1:ESBContext>
        </soapenv:Header>
        <soapenv:Body>
            <appointSupplierAck/>
        </soapenv:Body>
    </soapenv:Envelope>


    I have created a messagecontract class as follows:

    <MessageContract(WrapperNamespace:="http://schemas.xmlsoap.org/soap/envelope/")> _
    Public Class avivaMessageContractResponse
    
        Private _mainBody As String
    
        <MessageHeader(Name:="ESBMetaData", Namespace:="urn:nu:services:schema:message:common:nuiesbmetadata:v01")> _
        Public something As esbMetaData
    
        <MessageBodyMember()> _
        Public Property ApppointSupplierAck As String
            Get
                Return _mainBody
            End Get
            Set(value As String)
                _mainBody = value
            End Set
        End Property
    
    
    End Class

    and another class esbMetaData

    <MessageContract()> _
    Public Class esbMetaData
    
        Private _OriginalServiceCallerID As String = "Default Message"
    
        <MessageHeader(Name:="OriginalServiceCallerID", Namespace:="urn:nu:services:schema:message:common:nuiesbmetadata:v01")> _
        Public Property OriginalServiceCallerID As String
            Get
                Return _OriginalServiceCallerID
            End Get
            Set(value As String)
                _OriginalServiceCallerID = value
            End Set
        End Property
    
    
    End Class

    From these classes I was hoping to get

    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
        <soapenv:Header>
            <urn:ESBMetaData>
                <urn:OriginalServiceCallerID>SomeUser</urn:OriginalServiceCallerID>
            </urn:ESBMetaData>
      ...
      ...
      ...

    But all I get is:

    <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
       <s:Header>
          <h:ESBMetaData i:nil="true" xmlns:h="urn:nu:services:schema:message:common:nuiesbmetadata:v01" 
          xmlns:i="http://www.w3.org/2001/XMLSchema-instance"/>
       </s:Header>
       <s:Body>
          <ApppointSupplierAck xmlns="http://tempuri.org/"/>
       </s:Body>
    </s:Envelope>

    As you can see the OriginalServiceCallerID field is completly missing.

    Also, some help in adding the Namespaces and there prefixes, as you can see about I can get one namespace added, but for the envelope I need to add four namespaces.

    Any help greatly appreciated.

    Paul.









    Monday, December 2, 2013 11:23 AM

Answers

  • User-1753096817 posted

    Come across the following definition:

    http://msdn.microsoft.com/en-us/library/system.servicemodel.dispatcher.idispatchmessageinspector.beforesendreply(v=vs.110).aspx

    This shows that the correlationState object is the return value from the AfterReceiveRequest function.

    So I have created an object to hold the details that I need to pass. Set this object as the return type in the AfterReceiveRequest function, and it works. The members in the object are stored and passed across.

    Is there a way to modify this object?

    Traced the code using the CodeStack and the AfterReceiveRequst method is called from "External Code" and the return is to the class where the MessageContract is defined.

    looked around in the locals pane, but cannot see the returned object anywhere.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, December 3, 2013 10:24 AM

All replies

  • User260886948 posted

    Hi,

    First please use MessageContract as below:

    [MessageContract]
    public class YourMessageType
    {
      // This is in the SOAP Header   
    [MessageHeader] public string A {get;set;} [MessageHeader] public string B {get;set;} // This is in the SOAP body
    [MessageBodyMember] public string C {get;set;} ... }

    Then please try to check this thread:
    #Message contract translation to SOAP message:
    http://stackoverflow.com/questions/5174353/message-contract-translation-to-soap-message .

    Best Regards,
    Amy Peng

    Tuesday, December 3, 2013 1:29 AM
  • User-1753096817 posted

    Great, thanks for the reply.

    My message contract is like that already (only in VB, but not rocket science to convert)

    Anyway, the link provided at the bottom provided me with the means to possibly move forward.

    One of the answers provided uses the following:

    System.ServiceModel.Dispatcher.IDispatchMessageFormatter 

    Searched around and found the follwoing article

    http://keyvan.io/use-idispatchmessageformatter-and-iclientmessageformatter-to-customize-messages-in-wcf

    From this my code is almost working.

    Currently I am using a message inspector to valid any headers with the mustunderstand attribute.

    This was working, but now I find that after implementing the IDispatchMessageFormatter code, although the inspector code is run, I am again getting the header not understood message after the processing of the DeserializeRequest method.

    Should I now stop using the interceptor in favour of the DeserializeRequest method?

    Tuesday, December 3, 2013 5:42 AM
  • User-1753096817 posted

    Ok, I have now found a way to update the reply message to create exactly the reply message that I need.

    This article explains it all:

    http://msdn.microsoft.com/en-us/library/system.servicemodel.dispatcher.idispatchmessageinspector.beforesendreply(v=vs.110).aspx

    However, I need to have the ability to change the message created depending upon a couple of factors.

    My soap header has user login details, so I need a way to pass parameters into the BeforeSendReply function.

    Anyone have any ideas?

    Tuesday, December 3, 2013 10:01 AM
  • User-1753096817 posted

    Come across the following definition:

    http://msdn.microsoft.com/en-us/library/system.servicemodel.dispatcher.idispatchmessageinspector.beforesendreply(v=vs.110).aspx

    This shows that the correlationState object is the return value from the AfterReceiveRequest function.

    So I have created an object to hold the details that I need to pass. Set this object as the return type in the AfterReceiveRequest function, and it works. The members in the object are stored and passed across.

    Is there a way to modify this object?

    Traced the code using the CodeStack and the AfterReceiveRequst method is called from "External Code" and the return is to the class where the MessageContract is defined.

    looked around in the locals pane, but cannot see the returned object anywhere.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, December 3, 2013 10:24 AM