1 //------------------------------------------------------------------------------
2 // <copyright file="SoapServerMethod.cs" company="Microsoft">
3 //     Copyright (c) Microsoft Corporation.  All rights reserved.
4 // </copyright>
5 //------------------------------------------------------------------------------
6 
7 namespace System.Web.Services.Protocols {
8     using System;
9     using System.Collections.Generic;
10     using System.Reflection;
11     using System.Web.Services;
12     using System.Web.Services.Description;
13     using System.Xml;
14     using System.Xml.Serialization;
15     using System.Security;
16     using System.Security.Permissions;
17     using System.Security.Policy;
18     using System.Web.Services.Diagnostics;
19 
20     [PermissionSet(SecurityAction.LinkDemand, Name = "FullTrust")]
21     public sealed class SoapServerMethod {
22         //
23         // Internal field visibility is maintained for
24         // compatibility with existing code.
25         //
26         internal LogicalMethodInfo methodInfo;
27         internal XmlSerializer returnSerializer;
28         internal XmlSerializer parameterSerializer;
29         internal XmlSerializer inHeaderSerializer;
30         internal XmlSerializer outHeaderSerializer;
31         internal SoapHeaderMapping[] inHeaderMappings;
32         internal SoapHeaderMapping[] outHeaderMappings;
33         internal SoapReflectedExtension[] extensions;
34         internal object[] extensionInitializers;
35         internal string action;
36         internal bool oneWay;
37         internal bool rpc;
38         internal SoapBindingUse use;
39         internal SoapParameterStyle paramStyle;
40         internal WsiProfiles wsiClaims;
41 
SoapServerMethod()42         public SoapServerMethod() {
43         }
44 
SoapServerMethod(Type serverType, LogicalMethodInfo methodInfo)45         public SoapServerMethod(Type serverType, LogicalMethodInfo methodInfo) {
46             this.methodInfo = methodInfo;
47 
48             //
49             // Set up the XmlImporter, the SoapImporter, and acquire
50             // the ServiceAttribute on the serverType for use in
51             // creating a SoapReflectedMethod.
52             //
53             WebServiceAttribute serviceAttribute = WebServiceReflector.GetAttribute(serverType);
54             string serviceNamespace = serviceAttribute.Namespace;
55             bool serviceDefaultIsEncoded = SoapReflector.ServiceDefaultIsEncoded(serverType);
56 
57             SoapReflectionImporter soapImporter = SoapReflector.CreateSoapImporter(serviceNamespace, serviceDefaultIsEncoded);
58             XmlReflectionImporter xmlImporter = SoapReflector.CreateXmlImporter(serviceNamespace, serviceDefaultIsEncoded);
59 
60             //
61             // Add some types relating to the methodInfo into the two importers
62             //
63             SoapReflector.IncludeTypes(methodInfo, soapImporter);
64             WebMethodReflector.IncludeTypes(methodInfo, xmlImporter);
65 
66             //
67             // Create a SoapReflectedMethod by reflecting on the
68             // LogicalMethodInfo passed to us.
69             //
70             SoapReflectedMethod soapMethod = SoapReflector.ReflectMethod(methodInfo, false, xmlImporter, soapImporter, serviceNamespace);
71 
72             //
73             // Most of the fields in this class are ----ed in from the reflected information
74             //
75             ImportReflectedMethod(soapMethod);
76             ImportSerializers(soapMethod, GetServerTypeEvidence(serverType));
77             ImportHeaderSerializers(soapMethod);
78         }
79 
80         public LogicalMethodInfo MethodInfo {
81             get {
82                 return methodInfo;
83             }
84         }
85 
86         public XmlSerializer ReturnSerializer {
87             get {
88                 return returnSerializer;
89             }
90         }
91 
92         public XmlSerializer ParameterSerializer {
93             get {
94                 return parameterSerializer;
95             }
96         }
97 
98         public XmlSerializer InHeaderSerializer {
99             get {
100                 return inHeaderSerializer;
101             }
102         }
103 
104         public XmlSerializer OutHeaderSerializer {
105             get {
106                 return outHeaderSerializer;
107             }
108         }
109 
110         //
111         //
112 
113         public SoapHeaderMapping[] InHeaderMappings {
114             get {
115                 return inHeaderMappings;
116             }
117         }
118 
119         //
120         //
121 
122         public SoapHeaderMapping[] OutHeaderMappings {
123             get {
124                 return outHeaderMappings;
125             }
126         }
127 
128         /*
129          * WSE3 does not require access to Extension data
130          *
131         public SoapReflectedExtension[] Extensions
132         {
133             get
134             {
135                 return extensions;
136             }
137         }
138 
139         public object[] ExtensionInitializers
140         {
141             get
142             {
143                 return extensionInitializers;
144             }
145         }
146         */
147 
148         public string Action {
149             get {
150                 return action;
151             }
152         }
153 
154         public bool OneWay {
155             get {
156                 return oneWay;
157             }
158         }
159 
160         public bool Rpc {
161             get {
162                 return rpc;
163             }
164         }
165 
166         public SoapBindingUse BindingUse {
167             get {
168                 return use;
169             }
170         }
171 
172         public SoapParameterStyle ParameterStyle {
173             get {
174                 return paramStyle;
175             }
176         }
177 
178         public WsiProfiles WsiClaims {
179             get {
180                 return wsiClaims;
181             }
182         }
183 
184         [SecurityPermission(SecurityAction.Assert, ControlEvidence = true)]
GetServerTypeEvidence(Type type)185         private Evidence GetServerTypeEvidence(Type type) {
186             return type.Assembly.Evidence;
187         }
188 
GetXmlMappingsForMethod(SoapReflectedMethod soapMethod)189         private List<XmlMapping> GetXmlMappingsForMethod(SoapReflectedMethod soapMethod) {
190             List<XmlMapping> mappings = new List<XmlMapping>();
191             mappings.Add(soapMethod.requestMappings);
192             if (soapMethod.responseMappings != null) {
193                 mappings.Add(soapMethod.responseMappings);
194             }
195             mappings.Add(soapMethod.inHeaderMappings);
196             if (soapMethod.outHeaderMappings != null) {
197                 mappings.Add(soapMethod.outHeaderMappings);
198             }
199 
200             return mappings;
201         }
202 
ImportReflectedMethod(SoapReflectedMethod soapMethod)203         private void ImportReflectedMethod(SoapReflectedMethod soapMethod) {
204             this.action = soapMethod.action;
205             this.extensions = soapMethod.extensions;
206             this.extensionInitializers = SoapReflectedExtension.GetInitializers(this.methodInfo, soapMethod.extensions);
207             this.oneWay = soapMethod.oneWay;
208             this.rpc = soapMethod.rpc;
209             this.use = soapMethod.use;
210             this.paramStyle = soapMethod.paramStyle;
211             this.wsiClaims = soapMethod.binding == null ? WsiProfiles.None : soapMethod.binding.ConformsTo;
212         }
213 
ImportHeaderSerializers(SoapReflectedMethod soapMethod)214         private void ImportHeaderSerializers(SoapReflectedMethod soapMethod) {
215             List<SoapHeaderMapping> inHeaders = new List<SoapHeaderMapping>();
216             List<SoapHeaderMapping> outHeaders = new List<SoapHeaderMapping>();
217 
218             for (int j = 0; j < soapMethod.headers.Length; j++) {
219                 SoapHeaderMapping mapping = new SoapHeaderMapping();
220                 SoapReflectedHeader soapHeader = soapMethod.headers[j];
221                 mapping.memberInfo = soapHeader.memberInfo;
222                 mapping.repeats = soapHeader.repeats;
223                 mapping.custom = soapHeader.custom;
224                 mapping.direction = soapHeader.direction;
225                 mapping.headerType = soapHeader.headerType;
226                 if (mapping.direction == SoapHeaderDirection.In)
227                     inHeaders.Add(mapping);
228                 else if (mapping.direction == SoapHeaderDirection.Out)
229                     outHeaders.Add(mapping);
230                 else {
231                     inHeaders.Add(mapping);
232                     outHeaders.Add(mapping);
233                 }
234             }
235 
236             this.inHeaderMappings = inHeaders.ToArray();
237             if (this.outHeaderSerializer != null)
238                 this.outHeaderMappings = outHeaders.ToArray();
239         }
240 
ImportSerializers(SoapReflectedMethod soapMethod, Evidence serverEvidence)241         private void ImportSerializers(SoapReflectedMethod soapMethod, Evidence serverEvidence) {
242             //
243             // Keep track of all XmlMapping instances we need for this method.
244             //
245             List<XmlMapping> mappings = GetXmlMappingsForMethod(soapMethod);
246 
247             //
248             // Generate serializers from those XmlMappings
249             //
250 
251             XmlMapping[] xmlMappings = mappings.ToArray();
252             TraceMethod caller = Tracing.On ? new TraceMethod(this, "ImportSerializers") : null;
253             if (Tracing.On) Tracing.Enter(Tracing.TraceId(Res.TraceCreateSerializer), caller, new TraceMethod(typeof(XmlSerializer), "FromMappings", xmlMappings, serverEvidence));
254             XmlSerializer[] serializers = null;
255             if (AppDomain.CurrentDomain.IsHomogenous) {
256                 serializers = XmlSerializer.FromMappings(xmlMappings);
257             }
258             else {
259 #pragma warning disable 618 // If we're in a non-homogenous domain, legacy CAS mode is enabled, so passing through evidence will not fail
260                 serializers = XmlSerializer.FromMappings(xmlMappings, serverEvidence);
261 #pragma warning restore 618
262             }
263             if (Tracing.On) Tracing.Exit(Tracing.TraceId(Res.TraceCreateSerializer), caller);
264 
265             int i = 0;
266             this.parameterSerializer = serializers[i++];
267             if (soapMethod.responseMappings != null) {
268                 this.returnSerializer = serializers[i++];
269             }
270             this.inHeaderSerializer = serializers[i++];
271             if (soapMethod.outHeaderMappings != null) {
272                 this.outHeaderSerializer = serializers[i++];
273             }
274         }
275     }
276 }
277