WCF - sending data to server outside of contract

I have a WCF service with a client application. I have complete control over the client and server implementation. I have hundreds of methods in a WCF contract that need some of the information provided by the client. Rather than changing hundreds of methods, is there a way to send specific data from the client with each service call, perhaps somewhere in the channel?

Perhaps when the client configures the proxy before making the call, it can store this data somewhere in the proxy's internal property ... the data will then be sent to the server and from a service method that I could use to check the OperationContext or whatever or some other piece of memory to return this data and use it?

Any ideas?

+2


source to share


3 answers


It sounds like you want something like headers like using SOAP web services. I'm not a WCF expert, but this one looks like the WCF equivalent .



+1


source


It's actually not that hard. The best I can do is write an IClientMessageInspector that adds a SOAP header to the Message.Headers in the BeforeSendRequest method.



See http://weblogs.asp.net/paolopia/archive/2007/08/23/writing-a-wcf-message-inspector.aspx

+1


source


You cannot do this trivially. It will take some work.

It is true that SOAP headers are an ideal way to transfer data out of band to and / or from a service. But you have already defined your contract and adding headers will change the contract.

I believe you will have to start using messaging contracts.

Original:

[DataContract]
public class ComplexObject
{
    [DataMember(Name = "Id")] 
    public int Id;

    [DataMember] 
    public string Name;
}

[ServiceContract()]
public interface IMyContract
{
    void MyOperation(ComplexObject co);
}

public class MyService : IMyContract
{
    #region Implementation of IMyContract

    public void MyOperation(ComplexObject co)
    {
        // use co.*
    }

    #endregion
}

      

Using contracts with messages:

[DataContract]
public class ComplexObject
{
    [DataMember(Name = "Id")] 
    public int Id;

    [DataMember] 
    public string Name;
}

[DataContract]
public class MyHeader
{
    [DataMember]
    public string UserName;

    [DataMember]
    public string Password;
}

[DataContract]
public class OutputHeader
{
    [DataMember]
    public string Token;
}

[MessageContract]
public class MyOperationRequest
{
    [MessageHeader]
    public MyHeader Authentication;

    [MessageBodyMember]
    public ComplexObject TheObject;
}

[MessageContract]
public class MyOperationResponse
{
    [MessageHeader] 
    public OutputHeader OutputHeader;
}

[ServiceContract()]
public interface IMyContract
{
    MyOperationResponse MyOperation(MyOperationRequest request);
}

public class MyService : IMyContract
{
    public MyOperationResponse MyOperation(MyOperationRequest request)
    {
        // use request.TheObject.*
        // Can also read request.Authentication.*

        return new MyOperationResponse 
               { OutputHeader = new OutputHeader { Token = "someToken" } };
    }
}

      

0


source







All Articles