WCF ChannelFactory with Custom Endpoint Behavior (Json-Rpc)

梦想的初衷 提交于 2019-12-10 11:49:49

问题


I've been working really hard on a WCF Json-Rpc Service Model. I'm fairly new to WCF and WCF extensibility but finally I'm now able to process requests from a web browser :) To summarize it, I've now implemented an Endpoint Behavior, an Operation Selector, and a Message Formatter.

You can find the latest source code on this post on MSDN forum.

I'm now trying to create a WCF Client for it but I'm stuck with the following error:

Manual addressing is enabled on this factory, so all messages sent must be pre-addressed.

This is how I'm creating my client:

    private int communicationTimeout = 10;
    private int communicationPort = 80;
    private string jsonRpcRoot = "/json.rpc";

    public void InitializeClient()
    { 
        Uri baseAddress = new UriBuilder(Uri.UriSchemeHttp, Environment.MachineName, communicationPort, jsonRpcRoot).Uri;
        EndpointAddress address = new EndpointAddress(baseAddress.AbsoluteUri);

        ChannelFactory<IJsonService> channelFactory = new ChannelFactory<IJsonService>(new WebHttpBinding(), address);
        channelFactory.Endpoint.Behaviors.Add(new JsonRpcEndpointBehavior());

        IJsonService typedProxy = channelFactory.CreateChannel();

        int a = typedProxy.StartTransport(10);
    }

And this is my (test) service contract. I kept it as simple as possible

[ServiceContract(Namespace = "")]
public interface IJsonService
{
    [OperationContract]
    IList<Mission> GetMissions();

    [OperationContract]
    int StartTransport(int missionId);

    [OperationContract]
    int TransportCompleted(int missionId);
}

回答1:


The answer to my question was lying in the message formatter.

The error indicates that the message built and returned to the WCF stack, doesn't contain an address.

In order to satisfy this rule, the IClientMessageFormatter should include some value in

Message.Headers.To

I've changed the IClientMessageFormatter.SerializeRequest implementation as following:

    public Message SerializeRequest(MessageVersion messageVersion, object[] parameters)
    {
        string jsonText = SerializeJsonRequestParameters(parameters);

        // Compose message
        Message message = Message.CreateMessage(messageVersion, _clientOperation.Action, new JsonRpcBodyWriter(Encoding.UTF8.GetBytes(jsonText)));
        message.Properties.Add(WebBodyFormatMessageProperty.Name, new WebBodyFormatMessageProperty(WebContentFormat.Raw));
        _address.ApplyTo(message);

        HttpRequestMessageProperty reqProp = new HttpRequestMessageProperty();
        reqProp.Headers[HttpRequestHeader.ContentType] = "application/json";
        message.Properties.Add(HttpRequestMessageProperty.Name, reqProp);

        UriBuilder builder = new UriBuilder(message.Headers.To);
        builder.Query = string.Format("jsonrpc={0}", HttpUtility.UrlEncode(jsonText));
        message.Headers.To = builder.Uri;
        message.Properties.Via = builder.Uri;

        return message;
    }


来源:https://stackoverflow.com/questions/18408272/wcf-channelfactory-with-custom-endpoint-behavior-json-rpc

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!