问题
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