XmlReflectionMember [] BuildHeadersReflectionMembers(HeaderInfo[] headers) { XmlReflectionMember [] mems = new XmlReflectionMember [headers.Length]; for (int n = 0; n < headers.Length; n++) { HeaderInfo header = headers [n]; XmlReflectionMember m = new XmlReflectionMember(); m.IsReturnValue = false; m.MemberName = header.HeaderType.Name; m.MemberType = header.HeaderType; // MS.NET reflects header classes in a weird way. The root element // name is the CLR class name unless it is specified in an XmlRootAttribute. // The usual is to use the xml type name by default, but not in this case. XmlAttributes ats = new XmlAttributes(header.HeaderType); if (ats.XmlRoot != null) { XmlElementAttribute xe = new XmlElementAttribute(); xe.ElementName = ats.XmlRoot.ElementName; xe.Namespace = ats.XmlRoot.Namespace; m.XmlAttributes = new XmlAttributes(); m.XmlAttributes.XmlElements.Add(xe); } mems [n] = m; } return(mems); }
internal void UpdateHeaderValues(object target, HeaderInfo[] headersInfo) { foreach (SoapHeader header in Headers) { HeaderInfo hinfo = FindHeader(headersInfo, header.GetType()); if (hinfo != null) { hinfo.SetHeaderValue(target, header); header.DidUnderstand = !hinfo.Custom; } } }
HeaderInfo FindHeader(HeaderInfo[] headersInfo, Type headerType) { HeaderInfo unknownHeaderInfo = null; foreach (HeaderInfo headerInfo in headersInfo) { if (headerInfo.HeaderType == headerType) { return(headerInfo); } else if (headerInfo.Custom) { unknownHeaderInfo = headerInfo; } } return(unknownHeaderInfo); }
XmlReflectionMember [] BuildHeadersReflectionMembers (HeaderInfo[] headers) { XmlReflectionMember [] mems = new XmlReflectionMember [headers.Length]; for (int n=0; n<headers.Length; n++) { HeaderInfo header = headers [n]; XmlReflectionMember m = new XmlReflectionMember (); m.IsReturnValue = false; m.MemberName = header.HeaderType.Name; m.MemberType = header.HeaderType; // MS.NET reflects header classes in a weird way. The root element // name is the CLR class name unless it is specified in an XmlRootAttribute. // The usual is to use the xml type name by default, but not in this case. XmlAttributes ats = new XmlAttributes (header.HeaderType); if (ats.XmlRoot != null) { XmlElementAttribute xe = new XmlElementAttribute (); xe.ElementName = ats.XmlRoot.ElementName; xe.Namespace = ats.XmlRoot.Namespace; m.XmlAttributes = new XmlAttributes (); m.XmlAttributes.XmlElements.Add (xe); } mems [n] = m; } return mems; }
// // Constructor // public SoapMethodStubInfo (TypeStubInfo typeStub, LogicalMethodInfo source, object kind, XmlReflectionImporter xmlImporter, SoapReflectionImporter soapImporter) : base (typeStub, source) { SoapTypeStubInfo parent = (SoapTypeStubInfo) typeStub; XmlElementAttribute optional_ns = null; if (kind == null) { Use = parent.LogicalType.BindingUse; RequestName = ""; RequestNamespace = ""; ResponseName = ""; ResponseNamespace = ""; ParameterStyle = parent.ParameterStyle; SoapBindingStyle = parent.SoapBindingStyle; OneWay = false; // disabled (see bug #332150) //#if NET_2_0 // if (parent.Type != source.DeclaringType) // Binding = source.DeclaringType.Name + parent.ProtocolName; //#endif } else if (kind is SoapDocumentMethodAttribute){ SoapDocumentMethodAttribute dma = (SoapDocumentMethodAttribute) kind; Use = dma.Use; if (Use == SoapBindingUse.Default) { if (parent.SoapBindingStyle == SoapBindingStyle.Document) Use = parent.LogicalType.BindingUse; else Use = SoapBindingUse.Literal; } Action = dma.Action; Binding = dma.Binding; RequestName = dma.RequestElementName; RequestNamespace = dma.RequestNamespace; ResponseName = dma.ResponseElementName; ResponseNamespace = dma.ResponseNamespace; ParameterStyle = dma.ParameterStyle; if (ParameterStyle == SoapParameterStyle.Default) ParameterStyle = parent.ParameterStyle; OneWay = dma.OneWay; SoapBindingStyle = SoapBindingStyle.Document; } else { SoapRpcMethodAttribute rma = (SoapRpcMethodAttribute) kind; Use = SoapBindingUse.Encoded; // RPC always use encoded Action = rma.Action; if (Action != null && Action.Length == 0) Action = null; Binding = rma.Binding; // When using RPC, MS.NET seems to ignore RequestElementName and // MessageName, and it always uses the method name RequestName = source.Name; ResponseName = source.Name + "Response"; // RequestName = rma.RequestElementName; // ResponseName = rma.ResponseElementName; RequestNamespace = rma.RequestNamespace; ResponseNamespace = rma.ResponseNamespace; ParameterStyle = SoapParameterStyle.Wrapped; OneWay = rma.OneWay; SoapBindingStyle = SoapBindingStyle.Rpc; // For RPC calls, make all arguments be part of the empty namespace optional_ns = new XmlElementAttribute (); optional_ns.Namespace = ""; } if (OneWay){ if (source.ReturnType != typeof (void)) throw new Exception ("OneWay methods should not have a return value."); if (source.OutParameters.Length != 0) throw new Exception ("OneWay methods should not have out/ref parameters."); } BindingInfo binfo = parent.GetBinding (Binding); if (binfo == null) throw new InvalidOperationException ("Type '" + parent.Type + "' is missing WebServiceBinding attribute that defines a binding named '" + Binding + "'."); string serviceNamespace = binfo.Namespace; if (RequestNamespace == "") RequestNamespace = parent.LogicalType.GetWebServiceNamespace (serviceNamespace, Use); if (ResponseNamespace == "") ResponseNamespace = parent.LogicalType.GetWebServiceNamespace (serviceNamespace, Use); if (RequestName == "") RequestName = Name; if (ResponseName == "") ResponseName = Name + "Response"; if (Action == null) Action = serviceNamespace.EndsWith("/") ? (serviceNamespace + Name) : (serviceNamespace + "/" + Name); bool hasWrappingElem = (ParameterStyle == SoapParameterStyle.Wrapped); bool writeAccessors = (SoapBindingStyle == SoapBindingStyle.Rpc); XmlReflectionMember [] in_members = BuildRequestReflectionMembers (optional_ns); XmlReflectionMember [] out_members = BuildResponseReflectionMembers (optional_ns); if (Use == SoapBindingUse.Literal) { xmlImporter.IncludeTypes (source.CustomAttributeProvider); InputMembersMapping = xmlImporter.ImportMembersMapping (RequestName, RequestNamespace, in_members, hasWrappingElem); OutputMembersMapping = xmlImporter.ImportMembersMapping (ResponseName, ResponseNamespace, out_members, hasWrappingElem); } else { soapImporter.IncludeTypes (source.CustomAttributeProvider); InputMembersMapping = soapImporter.ImportMembersMapping (RequestName, RequestNamespace, in_members, hasWrappingElem, writeAccessors); OutputMembersMapping = soapImporter.ImportMembersMapping (ResponseName, ResponseNamespace, out_members, hasWrappingElem, writeAccessors); } InputMembersMapping.SetKey(RequestName); OutputMembersMapping.SetKey(ResponseName); requestSerializerId = parent.RegisterSerializer (InputMembersMapping); responseSerializerId = parent.RegisterSerializer (OutputMembersMapping); object[] o = source.GetCustomAttributes (typeof (SoapHeaderAttribute)); ArrayList allHeaderList = new ArrayList (o.Length); ArrayList inHeaderList = new ArrayList (o.Length); ArrayList outHeaderList = new ArrayList (o.Length); ArrayList faultHeaderList = new ArrayList (); SoapHeaderDirection unknownHeaderDirections = (SoapHeaderDirection)0; for (int i = 0; i < o.Length; i++) { SoapHeaderAttribute att = (SoapHeaderAttribute) o[i]; MemberInfo[] mems = source.DeclaringType.GetMember (att.MemberName); if (mems.Length == 0) throw new InvalidOperationException ("Member " + att.MemberName + " not found in class " + source.DeclaringType.FullName + "."); HeaderInfo header = new HeaderInfo (mems[0], att); allHeaderList.Add (header); if (!header.Custom) { if ((header.Direction & SoapHeaderDirection.In) != 0) inHeaderList.Add (header); if ((header.Direction & SoapHeaderDirection.Out) != 0) outHeaderList.Add (header); if ((header.Direction & SoapHeaderDirection.Fault) != 0) faultHeaderList.Add (header); } else unknownHeaderDirections |= header.Direction; } Headers = (HeaderInfo[]) allHeaderList.ToArray (typeof(HeaderInfo)); if (inHeaderList.Count > 0 || (unknownHeaderDirections & SoapHeaderDirection.In) != 0) { InHeaders = (HeaderInfo[]) inHeaderList.ToArray (typeof(HeaderInfo)); XmlReflectionMember[] members = BuildHeadersReflectionMembers (InHeaders); if (Use == SoapBindingUse.Literal) InputHeaderMembersMapping = xmlImporter.ImportMembersMapping ("", RequestNamespace, members, false); else InputHeaderMembersMapping = soapImporter.ImportMembersMapping ("", RequestNamespace, members, false, false); InputHeaderMembersMapping.SetKey(RequestName + ":InHeaders"); requestHeadersSerializerId = parent.RegisterSerializer (InputHeaderMembersMapping); } if (outHeaderList.Count > 0 || (unknownHeaderDirections & SoapHeaderDirection.Out) != 0) { OutHeaders = (HeaderInfo[]) outHeaderList.ToArray (typeof(HeaderInfo)); XmlReflectionMember[] members = BuildHeadersReflectionMembers (OutHeaders); if (Use == SoapBindingUse.Literal) OutputHeaderMembersMapping = xmlImporter.ImportMembersMapping ("", RequestNamespace, members, false); else OutputHeaderMembersMapping = soapImporter.ImportMembersMapping ("", RequestNamespace, members, false, false); OutputHeaderMembersMapping.SetKey(ResponseName + ":OutHeaders"); responseHeadersSerializerId = parent.RegisterSerializer (OutputHeaderMembersMapping); } if (faultHeaderList.Count > 0 || (unknownHeaderDirections & SoapHeaderDirection.Fault) != 0) { FaultHeaders = (HeaderInfo[]) faultHeaderList.ToArray (typeof(HeaderInfo)); XmlReflectionMember[] members = BuildHeadersReflectionMembers (FaultHeaders); if (Use == SoapBindingUse.Literal) FaultHeaderMembersMapping = xmlImporter.ImportMembersMapping ("", RequestNamespace, members, false); else FaultHeaderMembersMapping = soapImporter.ImportMembersMapping ("", RequestNamespace, members, false, false); faultHeadersSerializerId = parent.RegisterSerializer (FaultHeaderMembersMapping); } SoapExtensions = SoapExtension.GetMethodExtensions (source); }
HeaderInfo FindHeader (HeaderInfo[] headersInfo, Type headerType) { HeaderInfo unknownHeaderInfo = null; foreach (HeaderInfo headerInfo in headersInfo) { if (headerInfo.HeaderType == headerType) return headerInfo; else if (headerInfo.Custom) unknownHeaderInfo = headerInfo; } return unknownHeaderInfo; }
internal void UpdateHeaderValues (object target, HeaderInfo[] headersInfo) { foreach (SoapHeader header in Headers) { HeaderInfo hinfo = FindHeader (headersInfo, header.GetType ()); if (hinfo != null) { hinfo.SetHeaderValue (target, header); header.DidUnderstand = !hinfo.Custom; } } }
internal void CollectHeaders (object target, HeaderInfo[] headers, SoapHeaderDirection direction) { Headers.Clear (); foreach (HeaderInfo hi in headers) { if ((hi.Direction & direction) != 0 && !hi.Custom) { SoapHeader headerVal = hi.GetHeaderValue (target) as SoapHeader; if (headerVal != null) Headers.Add (headerVal); } } }
// // Constructor // public SoapMethodStubInfo(TypeStubInfo typeStub, LogicalMethodInfo source, object kind, XmlReflectionImporter xmlImporter, SoapReflectionImporter soapImporter) : base(typeStub, source) { SoapTypeStubInfo parent = (SoapTypeStubInfo)typeStub; XmlElementAttribute optional_ns = null; if (kind == null) { Use = parent.LogicalType.BindingUse; RequestName = ""; RequestNamespace = ""; ResponseName = ""; ResponseNamespace = ""; ParameterStyle = parent.ParameterStyle; SoapBindingStyle = parent.SoapBindingStyle; OneWay = false; // disabled (see bug #332150) //#if NET_2_0 // if (parent.Type != source.DeclaringType) // Binding = source.DeclaringType.Name + parent.ProtocolName; //#endif } else if (kind is SoapDocumentMethodAttribute) { SoapDocumentMethodAttribute dma = (SoapDocumentMethodAttribute)kind; Use = dma.Use; if (Use == SoapBindingUse.Default) { if (parent.SoapBindingStyle == SoapBindingStyle.Document) { Use = parent.LogicalType.BindingUse; } else { Use = SoapBindingUse.Literal; } } Action = dma.Action; Binding = dma.Binding; RequestName = dma.RequestElementName; RequestNamespace = dma.RequestNamespace; ResponseName = dma.ResponseElementName; ResponseNamespace = dma.ResponseNamespace; ParameterStyle = dma.ParameterStyle; if (ParameterStyle == SoapParameterStyle.Default) { ParameterStyle = parent.ParameterStyle; } OneWay = dma.OneWay; SoapBindingStyle = SoapBindingStyle.Document; } else { SoapRpcMethodAttribute rma = (SoapRpcMethodAttribute)kind; Use = SoapBindingUse.Encoded; // RPC always use encoded Action = rma.Action; if (Action != null && Action.Length == 0) { Action = null; } Binding = rma.Binding; // When using RPC, MS.NET seems to ignore RequestElementName and // MessageName, and it always uses the method name RequestName = source.Name; ResponseName = source.Name + "Response"; // RequestName = rma.RequestElementName; // ResponseName = rma.ResponseElementName; RequestNamespace = rma.RequestNamespace; ResponseNamespace = rma.ResponseNamespace; ParameterStyle = SoapParameterStyle.Wrapped; OneWay = rma.OneWay; SoapBindingStyle = SoapBindingStyle.Rpc; // For RPC calls, make all arguments be part of the empty namespace optional_ns = new XmlElementAttribute(); optional_ns.Namespace = ""; } if (OneWay) { if (source.ReturnType != typeof(void)) { throw new Exception("OneWay methods should not have a return value."); } if (source.OutParameters.Length != 0) { throw new Exception("OneWay methods should not have out/ref parameters."); } } BindingInfo binfo = parent.GetBinding(Binding); if (binfo == null) { throw new InvalidOperationException("Type '" + parent.Type + "' is missing WebServiceBinding attribute that defines a binding named '" + Binding + "'."); } string serviceNamespace = binfo.Namespace; if (RequestNamespace == "") { RequestNamespace = parent.LogicalType.GetWebServiceNamespace(serviceNamespace, Use); } if (ResponseNamespace == "") { ResponseNamespace = parent.LogicalType.GetWebServiceNamespace(serviceNamespace, Use); } if (RequestName == "") { RequestName = Name; } if (ResponseName == "") { ResponseName = Name + "Response"; } if (Action == null) { Action = serviceNamespace.EndsWith("/") ? (serviceNamespace + Name) : (serviceNamespace + "/" + Name); } bool hasWrappingElem = (ParameterStyle == SoapParameterStyle.Wrapped); bool writeAccessors = (SoapBindingStyle == SoapBindingStyle.Rpc); XmlReflectionMember [] in_members = BuildRequestReflectionMembers(optional_ns); XmlReflectionMember [] out_members = BuildResponseReflectionMembers(optional_ns); if (Use == SoapBindingUse.Literal) { xmlImporter.IncludeTypes(source.CustomAttributeProvider); InputMembersMapping = xmlImporter.ImportMembersMapping(RequestName, RequestNamespace, in_members, hasWrappingElem); OutputMembersMapping = xmlImporter.ImportMembersMapping(ResponseName, ResponseNamespace, out_members, hasWrappingElem); } else { soapImporter.IncludeTypes(source.CustomAttributeProvider); InputMembersMapping = soapImporter.ImportMembersMapping(RequestName, RequestNamespace, in_members, hasWrappingElem, writeAccessors); OutputMembersMapping = soapImporter.ImportMembersMapping(ResponseName, ResponseNamespace, out_members, hasWrappingElem, writeAccessors); } requestSerializerId = parent.RegisterSerializer(InputMembersMapping); responseSerializerId = parent.RegisterSerializer(OutputMembersMapping); object[] o = source.GetCustomAttributes(typeof(SoapHeaderAttribute)); ArrayList allHeaderList = new ArrayList(o.Length); ArrayList inHeaderList = new ArrayList(o.Length); ArrayList outHeaderList = new ArrayList(o.Length); ArrayList faultHeaderList = new ArrayList(); SoapHeaderDirection unknownHeaderDirections = (SoapHeaderDirection)0; for (int i = 0; i < o.Length; i++) { SoapHeaderAttribute att = (SoapHeaderAttribute)o[i]; MemberInfo[] mems = source.DeclaringType.GetMember(att.MemberName); if (mems.Length == 0) { throw new InvalidOperationException("Member " + att.MemberName + " not found in class " + source.DeclaringType.FullName + "."); } HeaderInfo header = new HeaderInfo(mems[0], att); allHeaderList.Add(header); if (!header.Custom) { if ((header.Direction & SoapHeaderDirection.In) != 0) { inHeaderList.Add(header); } if ((header.Direction & SoapHeaderDirection.Out) != 0) { outHeaderList.Add(header); } if ((header.Direction & SoapHeaderDirection.Fault) != 0) { faultHeaderList.Add(header); } } else { unknownHeaderDirections |= header.Direction; } } Headers = (HeaderInfo[])allHeaderList.ToArray(typeof(HeaderInfo)); if (inHeaderList.Count > 0 || (unknownHeaderDirections & SoapHeaderDirection.In) != 0) { InHeaders = (HeaderInfo[])inHeaderList.ToArray(typeof(HeaderInfo)); XmlReflectionMember[] members = BuildHeadersReflectionMembers(InHeaders); if (Use == SoapBindingUse.Literal) { InputHeaderMembersMapping = xmlImporter.ImportMembersMapping("", RequestNamespace, members, false); } else { InputHeaderMembersMapping = soapImporter.ImportMembersMapping("", RequestNamespace, members, false, false); } requestHeadersSerializerId = parent.RegisterSerializer(InputHeaderMembersMapping); } if (outHeaderList.Count > 0 || (unknownHeaderDirections & SoapHeaderDirection.Out) != 0) { OutHeaders = (HeaderInfo[])outHeaderList.ToArray(typeof(HeaderInfo)); XmlReflectionMember[] members = BuildHeadersReflectionMembers(OutHeaders); if (Use == SoapBindingUse.Literal) { OutputHeaderMembersMapping = xmlImporter.ImportMembersMapping("", RequestNamespace, members, false); } else { OutputHeaderMembersMapping = soapImporter.ImportMembersMapping("", RequestNamespace, members, false, false); } responseHeadersSerializerId = parent.RegisterSerializer(OutputHeaderMembersMapping); } if (faultHeaderList.Count > 0 || (unknownHeaderDirections & SoapHeaderDirection.Fault) != 0) { FaultHeaders = (HeaderInfo[])faultHeaderList.ToArray(typeof(HeaderInfo)); XmlReflectionMember[] members = BuildHeadersReflectionMembers(FaultHeaders); if (Use == SoapBindingUse.Literal) { FaultHeaderMembersMapping = xmlImporter.ImportMembersMapping("", RequestNamespace, members, false); } else { FaultHeaderMembersMapping = soapImporter.ImportMembersMapping("", RequestNamespace, members, false, false); } faultHeadersSerializerId = parent.RegisterSerializer(FaultHeaderMembersMapping); } SoapExtensions = SoapExtension.GetMethodExtensions(source); }