1: public class ServiceChannelProxy<TChannel>: RealProxy
2: {
3: //其他成员
4: public override IMessage Invoke(IMessage msg)
5: {
6: IMethodCallMessage methodCall = (IMethodCallMessage)msg;
7:
8: //得到操作名称
9: object[] attributes = methodCall.MethodBase.GetCustomAttributes(typeof(OperationContractAttribute), true);
10: OperationContractAttribute attribute = (OperationContractAttribute)attributes[0];
11: string operationName = string.IsNullOrEmpty(attribute.Name) ? methodCall.MethodName : attribute.Name;
12:
13: //序列化请求消息
14: Message requestMessage = this.MessageFormatters[operationName].SerializeRequest(this.MessageVersion, methodCall.InArgs);
15:
16: //添加必要的WS-Address报头
17: EndpointAddress address = new EndpointAddress(this.Address);
18: requestMessage.Headers.MessageId = new UniqueId(Guid.NewGuid());
19: requestMessage.Headers.ReplyTo = new EndpointAddress("http://www.w3.org/2005/08/addressing/anonymous");
20: address.ApplyTo(requestMessage);
21:
22: //对请求消息进行编码,并将编码生成的字节发送通过HttpWebRequest向服务端发送
23: HttpWebRequest webRequest = (HttpWebRequest)HttpWebRequest.Create(this.Address);
24: webRequest.Method = "Post";
25: webRequest.KeepAlive = true;
26: webRequest.ContentType = "application/soap+xml; charset=utf-8";
27: ArraySegment<byte> bytes = this.MessageEncoderFactory.Encoder.WriteMessage(requestMessage, int.MaxValue, BufferManager.CreateBufferManager(long.MaxValue, int.MaxValue));
28: webRequest.ContentLength = bytes.Array.Length;
29: webRequest.GetRequestStream().Write(bytes.Array, 0, bytes.Array.Length);
30: webRequest.GetRequestStream().Close();
31: WebResponse webResponse = webRequest.GetResponse();
32:
33: //对HttpResponse进行解码生成回复消息.
34: Message responseMessage = this.MessageEncoderFactory.Encoder.ReadMessage(webResponse.GetResponseStream(), int.MaxValue);
35:
36: //回复消息进行反列化生成相应的对象,并映射为方法调用的返回值或者ref/out参数
37: object[] allArgs = (object[])Array.CreateInstance(typeof(object),methodCall.ArgCount);
38: Array.Copy(methodCall.Args, allArgs, methodCall.ArgCount);
39: object[] refOutParameters = new object[GetRefOutParameterCount(methodCall.MethodBase)];
40: object returnValue = this.MessageFormatters[operationName].DeserializeReply(responseMessage, refOutParameters);
41: MapRefOutParameter(methodCall.MethodBase, allArgs, refOutParameters);
42:
43: //通过ReturnMessage的形式将返回值和ref/out参数返回
44: return new ReturnMessage(returnValue, allArgs, allArgs.Length, methodCall.LogicalCallContext, methodCall);
45: }
46:
47: private int GetRefOutParameterCount(MethodBase method)
48: {
49: int count = 0;
50: foreach (ParameterInfo parameter in method.GetParameters())
51: {
52: if (parameter.IsOut || parameter.ParameterType.IsByRef)
53: {
54: count++;
55: }
56: }
57: return count;
58: }
59:
60: private void MapRefOutParameter(MethodBase method, object[] allArgs,object[] refOutArgs)
61: {
62: List<int> refOutParamPositionsList = new List<int>();
63: foreach (ParameterInfo parameter in method.GetParameters())
64: {
65: if (parameter.IsOut || parameter.ParameterType.IsByRef)
66: {
67: refOutParamPositionsList.Add(parameter.Position);
68: }
69: }
70: int[] refOutParamPositionArray = refOutParamPositionsList.ToArray();
71: for (int i = 0; i < refOutArgs.Length; i++)
72: {
73: allArgs[refOutParamPositionArray[i]] = refOutArgs[i];
74: }
75: }
76: }