2 // System.Web.Services.Description.SoapProtocolImporter.cs
5 // Tim Coleman (tim@timcoleman.com)
6 // Lluis Sanchez Gual (lluis@ximian.com)
8 // Copyright (C) Tim Coleman, 2002
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 using System
.Web
.Services
;
34 using System
.Web
.Services
.Protocols
;
35 using System
.Web
.Services
.Configuration
;
37 using System
.Xml
.Schema
;
38 using System
.Xml
.Serialization
;
39 using System
.Configuration
;
40 using System
.Collections
;
42 namespace System
.Web
.Services
.Description
{
43 public class SoapProtocolImporter
: ProtocolImporter
{
47 SoapBinding soapBinding
;
48 SoapCodeExporter soapExporter
;
49 SoapSchemaImporter soapImporter
;
50 XmlCodeExporter xmlExporter
;
51 XmlSchemaImporter xmlImporter
;
52 CodeIdentifiers memberIds
;
53 ArrayList extensionImporters
;
54 Hashtable headerVariables
;
55 XmlSchemas xmlSchemas
;
56 XmlSchemas soapSchemas
;
62 public SoapProtocolImporter ()
64 extensionImporters
= ExtensionManager
.BuildExtensionImporters ();
67 void SetBinding (SoapBinding soapBinding
)
69 this.soapBinding
= soapBinding
;
72 #endregion // Constructors
76 public override string ProtocolName
{
77 get { return "Soap"; }
80 public SoapBinding SoapBinding
{
81 get { return soapBinding; }
84 public SoapCodeExporter SoapExporter
{
85 get { return soapExporter; }
88 public SoapSchemaImporter SoapImporter
{
89 get { return soapImporter; }
92 public XmlCodeExporter XmlExporter
{
93 get { return xmlExporter; }
96 public XmlSchemaImporter XmlImporter
{
97 get { return xmlImporter; }
100 #endregion // Properties
104 protected override CodeTypeDeclaration
BeginClass ()
106 soapBinding
= (SoapBinding
) Binding
.Extensions
.Find (typeof(SoapBinding
));
108 CodeTypeDeclaration codeClass
= new CodeTypeDeclaration (ClassName
);
110 string location
= null;
113 SoapAddressBinding sab
= (SoapAddressBinding
) Port
.Extensions
.Find (typeof(SoapAddressBinding
));
114 if (sab
!= null) location
= sab
.Location
;
117 string namspace
= (Port
!= null ? Port
.Binding
.Namespace
: Binding
.ServiceDescription
.TargetNamespace
);
118 string name
= (Port
!= null ? Port
.Name
: Binding
.Name
);
120 if (Style
== ServiceDescriptionImportStyle
.Client
) {
121 CodeTypeReference ctr
= new CodeTypeReference ("System.Web.Services.Protocols.SoapHttpClientProtocol");
122 codeClass
.BaseTypes
.Add (ctr
);
125 CodeTypeReference ctr
= new CodeTypeReference ("System.Web.Services.WebService");
126 codeClass
.BaseTypes
.Add (ctr
);
127 CodeAttributeDeclaration attws
= new CodeAttributeDeclaration ("System.Web.Services.WebServiceAttribute");
128 attws
.Arguments
.Add (GetArg ("Namespace", namspace
));
129 AddCustomAttribute (codeClass
, attws
, true);
132 CodeAttributeDeclaration att
= new CodeAttributeDeclaration ("System.Web.Services.WebServiceBinding");
133 att
.Arguments
.Add (GetArg ("Name", name
));
134 att
.Arguments
.Add (GetArg ("Namespace", namspace
));
135 AddCustomAttribute (codeClass
, att
, true);
137 if (Style
== ServiceDescriptionImportStyle
.Client
) {
138 CodeConstructor cc
= new CodeConstructor ();
139 cc
.Attributes
= MemberAttributes
.Public
;
140 GenerateServiceUrl (location
, cc
.Statements
);
141 codeClass
.Members
.Add (cc
);
144 memberIds
= new CodeIdentifiers ();
145 headerVariables
= new Hashtable ();
149 protected override void BeginNamespace ()
152 xmlImporter
= new XmlSchemaImporter (LiteralSchemas
, base.CodeGenerationOptions
, base.CodeGenerator
, base.ImportContext
);
153 soapImporter
= new SoapSchemaImporter (EncodedSchemas
, base.CodeGenerationOptions
, base.CodeGenerator
, base.ImportContext
);
154 xmlExporter
= new XmlCodeExporter (CodeNamespace
, null, base.CodeGenerator
, base.CodeGenerationOptions
, null);
155 soapExporter
= new SoapCodeExporter (CodeNamespace
, null, base.CodeGenerator
, base.CodeGenerationOptions
, null);
157 xmlImporter
= new XmlSchemaImporter (LiteralSchemas
, ClassNames
);
158 soapImporter
= new SoapSchemaImporter (EncodedSchemas
, ClassNames
);
159 xmlExporter
= new XmlCodeExporter (CodeNamespace
, null);
160 soapExporter
= new SoapCodeExporter (CodeNamespace
, null);
164 protected override void EndClass ()
166 SoapTransportImporter transportImporter
= SoapTransportImporter
.FindTransportImporter (soapBinding
.Transport
);
167 if (transportImporter
== null) throw new InvalidOperationException ("Transport '" + soapBinding
.Transport
+ "' not supported");
168 transportImporter
.ImportContext
= this;
169 transportImporter
.ImportClass ();
171 if (xmlExporter
.IncludeMetadata
.Count
> 0 || soapExporter
.IncludeMetadata
.Count
> 0)
173 if (CodeTypeDeclaration
.CustomAttributes
== null)
174 CodeTypeDeclaration
.CustomAttributes
= new CodeAttributeDeclarationCollection ();
175 CodeTypeDeclaration
.CustomAttributes
.AddRange (xmlExporter
.IncludeMetadata
);
176 CodeTypeDeclaration
.CustomAttributes
.AddRange (soapExporter
.IncludeMetadata
);
180 protected override void EndNamespace ()
184 protected override bool IsBindingSupported ()
186 return Binding
.Extensions
.Find (typeof(SoapBinding
)) != null;
190 protected override bool IsOperationFlowSupported (OperationFlow flow
)
192 throw new NotImplementedException ();
196 protected virtual bool IsSoapEncodingPresent (string uriList
)
198 throw new NotImplementedException ();
201 protected override CodeMemberMethod
GenerateMethod ()
205 SoapOperationBinding soapOper
= OperationBinding
.Extensions
.Find (typeof (SoapOperationBinding
)) as SoapOperationBinding
;
206 if (soapOper
== null) throw new InvalidOperationException ("Soap operation binding not found");
208 SoapBindingStyle style
= soapOper
.Style
!= SoapBindingStyle
.Default
? soapOper
.Style
: soapBinding
.Style
;
210 SoapBodyBinding isbb
= null;
211 XmlMembersMapping inputMembers
= null;
213 isbb
= OperationBinding
.Input
.Extensions
.Find (typeof(SoapBodyBinding
)) as SoapBodyBinding
;
214 if (isbb
== null) throw new InvalidOperationException ("Soap body binding not found");
216 inputMembers
= ImportMembersMapping (InputMessage
, isbb
, style
, false);
217 if (inputMembers
== null) throw new InvalidOperationException ("Input message not declared");
219 // If OperationBinding.Output is null, it is an OneWay operation
221 SoapBodyBinding osbb
= null;
222 XmlMembersMapping outputMembers
= null;
224 if (OperationBinding
.Output
!= null) {
225 osbb
= OperationBinding
.Output
.Extensions
.Find (typeof(SoapBodyBinding
)) as SoapBodyBinding
;
226 if (osbb
== null) throw new InvalidOperationException ("Soap body binding not found");
228 outputMembers
= ImportMembersMapping (OutputMessage
, osbb
, style
, true);
229 if (outputMembers
== null) throw new InvalidOperationException ("Output message not declared");
232 CodeMemberMethod met
= GenerateMethod (memberIds
, soapOper
, isbb
, inputMembers
, outputMembers
);
234 if (isbb
.Use
== SoapBindingUse
.Literal
)
235 xmlExporter
.ExportMembersMapping (inputMembers
);
237 soapExporter
.ExportMembersMapping (inputMembers
);
240 if (osbb
.Use
== SoapBindingUse
.Literal
)
241 xmlExporter
.ExportMembersMapping (outputMembers
);
243 soapExporter
.ExportMembersMapping (outputMembers
);
246 foreach (SoapExtensionImporter eximporter
in extensionImporters
)
248 eximporter
.ImportContext
= this;
249 eximporter
.ImportMethod (met
.CustomAttributes
);
254 catch (InvalidOperationException ex
)
256 UnsupportedOperationBindingWarning (ex
.Message
);
261 XmlMembersMapping
ImportMembersMapping (Message msg
, SoapBodyBinding sbb
, SoapBindingStyle style
, bool output
)
263 string elemName
= Operation
.Name
;
264 if (output
) elemName
+= "Response";
266 if (msg
.Parts
.Count
== 1 && msg
.Parts
[0].Name
== "parameters")
268 // Wrapped parameter style
270 MessagePart part
= msg
.Parts
[0];
271 if (sbb
.Use
== SoapBindingUse
.Encoded
)
273 SoapSchemaMember ssm
= new SoapSchemaMember ();
274 ssm
.MemberName
= part
.Name
;
275 ssm
.MemberType
= part
.Type
;
276 return soapImporter
.ImportMembersMapping (elemName
, part
.Type
.Namespace
, ssm
);
279 return xmlImporter
.ImportMembersMapping (part
.Element
);
283 if (sbb
.Use
== SoapBindingUse
.Encoded
)
285 SoapSchemaMember
[] mems
= new SoapSchemaMember
[msg
.Parts
.Count
];
286 for (int n
=0; n
<mems
.Length
; n
++)
288 SoapSchemaMember mem
= new SoapSchemaMember();
289 mem
.MemberName
= msg
.Parts
[n
].Name
;
290 mem
.MemberType
= msg
.Parts
[n
].Type
;
294 // Rpc messages always have a wrapping element
295 if (style
== SoapBindingStyle
.Rpc
)
296 return soapImporter
.ImportMembersMapping (elemName
, sbb
.Namespace
, mems
, true);
298 return soapImporter
.ImportMembersMapping ("", "", mems
, false);
302 if (style
== SoapBindingStyle
.Rpc
)
303 throw new InvalidOperationException ("The combination of style=rpc with use=literal is not supported");
305 if (msg
.Parts
.Count
== 1 && msg
.Parts
[0].Type
!= XmlQualifiedName
.Empty
)
306 return xmlImporter
.ImportAnyType (msg
.Parts
[0].Type
, null);
309 XmlQualifiedName
[] pnames
= new XmlQualifiedName
[msg
.Parts
.Count
];
310 for (int n
=0; n
<pnames
.Length
; n
++)
311 pnames
[n
] = msg
.Parts
[n
].Element
;
312 return xmlImporter
.ImportMembersMapping (pnames
);
318 CodeMemberMethod
GenerateMethod (CodeIdentifiers memberIds
, SoapOperationBinding soapOper
, SoapBodyBinding bodyBinding
, XmlMembersMapping inputMembers
, XmlMembersMapping outputMembers
)
320 CodeIdentifiers pids
= new CodeIdentifiers ();
321 CodeMemberMethod method
= new CodeMemberMethod ();
322 CodeMemberMethod methodBegin
= new CodeMemberMethod ();
323 CodeMemberMethod methodEnd
= new CodeMemberMethod ();
324 method
.Attributes
= MemberAttributes
.Public
| MemberAttributes
.Final
;
325 methodBegin
.Attributes
= MemberAttributes
.Public
| MemberAttributes
.Final
;
326 methodEnd
.Attributes
= MemberAttributes
.Public
| MemberAttributes
.Final
;
328 SoapBindingStyle style
= soapOper
.Style
!= SoapBindingStyle
.Default
? soapOper
.Style
: soapBinding
.Style
;
330 // Find unique names for temporary variables
332 for (int n
=0; n
<inputMembers
.Count
; n
++)
333 pids
.AddUnique (inputMembers
[n
].MemberName
, inputMembers
[n
]);
335 if (outputMembers
!= null)
336 for (int n
=0; n
<outputMembers
.Count
; n
++)
337 pids
.AddUnique (outputMembers
[n
].MemberName
, outputMembers
[n
]);
339 string varAsyncResult
= pids
.AddUnique ("asyncResult","asyncResult");
340 string varResults
= pids
.AddUnique ("results","results");
341 string varCallback
= pids
.AddUnique ("callback","callback");
342 string varAsyncState
= pids
.AddUnique ("asyncState","asyncState");
344 string messageName
= memberIds
.AddUnique(CodeIdentifier
.MakeValid(Operation
.Name
),method
);
346 method
.Name
= CodeIdentifier
.MakeValid(Operation
.Name
);
347 if (method
.Name
== ClassName
) method
.Name
+= "1";
348 methodBegin
.Name
= memberIds
.AddUnique(CodeIdentifier
.MakeValid("Begin" + method
.Name
),method
);
349 methodEnd
.Name
= memberIds
.AddUnique(CodeIdentifier
.MakeValid("End" + method
.Name
),method
);
351 method
.ReturnType
= new CodeTypeReference (typeof(void));
352 methodEnd
.ReturnType
= new CodeTypeReference (typeof(void));
353 methodEnd
.Parameters
.Add (new CodeParameterDeclarationExpression (typeof (IAsyncResult
),varAsyncResult
));
355 CodeExpression
[] paramArray
= new CodeExpression
[inputMembers
.Count
];
356 CodeParameterDeclarationExpression
[] outParams
= new CodeParameterDeclarationExpression
[outputMembers
!= null ? outputMembers
.Count
: 0];
358 for (int n
=0; n
<inputMembers
.Count
; n
++)
360 CodeParameterDeclarationExpression param
= GenerateParameter (inputMembers
[n
], FieldDirection
.In
);
361 method
.Parameters
.Add (param
);
362 GenerateMemberAttributes (inputMembers
, inputMembers
[n
], bodyBinding
.Use
, param
);
363 methodBegin
.Parameters
.Add (GenerateParameter (inputMembers
[n
], FieldDirection
.In
));
364 paramArray
[n
] = new CodeVariableReferenceExpression (param
.Name
);
367 if (outputMembers
!= null)
369 bool hasReturn
= false;
370 for (int n
=0; n
<outputMembers
.Count
; n
++)
372 CodeParameterDeclarationExpression cpd
= GenerateParameter (outputMembers
[n
], FieldDirection
.Out
);
376 foreach (CodeParameterDeclarationExpression ip
in method
.Parameters
)
378 if (ip
.Name
== cpd
.Name
&& ip
.Type
.BaseType
== cpd
.Type
.BaseType
) {
379 ip
.Direction
= FieldDirection
.Ref
;
380 methodEnd
.Parameters
.Add (GenerateParameter (outputMembers
[n
], FieldDirection
.Out
));
391 method
.ReturnType
= cpd
.Type
;
392 methodEnd
.ReturnType
= cpd
.Type
;
393 GenerateReturnAttributes (outputMembers
, outputMembers
[n
], bodyBinding
.Use
, method
);
394 outParams
[n
] = null;
398 method
.Parameters
.Add (cpd
);
399 GenerateMemberAttributes (outputMembers
, outputMembers
[n
], bodyBinding
.Use
, cpd
);
400 methodEnd
.Parameters
.Add (GenerateParameter (outputMembers
[n
], FieldDirection
.Out
));
404 methodBegin
.Parameters
.Add (new CodeParameterDeclarationExpression (typeof (AsyncCallback
),varCallback
));
405 methodBegin
.Parameters
.Add (new CodeParameterDeclarationExpression (typeof (object),varAsyncState
));
406 methodBegin
.ReturnType
= new CodeTypeReference (typeof(IAsyncResult
));
408 // Array of input parameters
410 CodeArrayCreateExpression methodParams
;
411 if (paramArray
.Length
> 0)
412 methodParams
= new CodeArrayCreateExpression (typeof(object), paramArray
);
414 methodParams
= new CodeArrayCreateExpression (typeof(object), 0);
416 // Assignment of output parameters
418 CodeStatementCollection outAssign
= new CodeStatementCollection ();
419 CodeVariableReferenceExpression arrVar
= new CodeVariableReferenceExpression (varResults
);
420 for (int n
=0; n
<outParams
.Length
; n
++)
422 CodeExpression index
= new CodePrimitiveExpression (n
);
423 if (outParams
[n
] == null)
425 CodeExpression res
= new CodeCastExpression (method
.ReturnType
, new CodeArrayIndexerExpression (arrVar
, index
));
426 outAssign
.Add (new CodeMethodReturnStatement (res
));
430 CodeExpression res
= new CodeCastExpression (outParams
[n
].Type
, new CodeArrayIndexerExpression (arrVar
, index
));
431 CodeExpression
var = new CodeVariableReferenceExpression (outParams
[n
].Name
);
432 outAssign
.Insert (0, new CodeAssignStatement (var, res
));
436 if (Style
== ServiceDescriptionImportStyle
.Client
)
440 CodeThisReferenceExpression ethis
= new CodeThisReferenceExpression();
441 CodePrimitiveExpression varMsgName
= new CodePrimitiveExpression (messageName
);
442 CodeMethodInvokeExpression inv
;
443 CodeVariableDeclarationStatement dec
;
445 inv
= new CodeMethodInvokeExpression (ethis
, "Invoke", varMsgName
, methodParams
);
446 if (outputMembers
!= null && outputMembers
.Count
> 0)
448 dec
= new CodeVariableDeclarationStatement (typeof(object[]), varResults
, inv
);
449 method
.Statements
.Add (dec
);
450 method
.Statements
.AddRange (outAssign
);
453 method
.Statements
.Add (inv
);
457 CodeExpression expCallb
= new CodeVariableReferenceExpression (varCallback
);
458 CodeExpression expAsyncs
= new CodeVariableReferenceExpression (varAsyncState
);
459 inv
= new CodeMethodInvokeExpression (ethis
, "BeginInvoke", varMsgName
, methodParams
, expCallb
, expAsyncs
);
460 methodBegin
.Statements
.Add (new CodeMethodReturnStatement (inv
));
464 CodeExpression varAsyncr
= new CodeVariableReferenceExpression (varAsyncResult
);
465 inv
= new CodeMethodInvokeExpression (ethis
, "EndInvoke", varAsyncr
);
466 if (outputMembers
!= null && outputMembers
.Count
> 0)
468 dec
= new CodeVariableDeclarationStatement (typeof(object[]), varResults
, inv
);
469 methodEnd
.Statements
.Add (dec
);
470 methodEnd
.Statements
.AddRange (outAssign
);
473 methodEnd
.Statements
.Add (inv
);
476 method
.Attributes
= MemberAttributes
.Public
| MemberAttributes
.Abstract
;
481 ImportHeaders (method
);
483 CodeAttributeDeclaration att
= new CodeAttributeDeclaration ("System.Web.Services.WebMethodAttribute");
484 if (messageName
!= method
.Name
) att
.Arguments
.Add (GetArg ("MessageName",messageName
));
485 AddCustomAttribute (method
, att
, (Style
== ServiceDescriptionImportStyle
.Server
));
487 if (style
== SoapBindingStyle
.Rpc
)
489 att
= new CodeAttributeDeclaration ("System.Web.Services.Protocols.SoapRpcMethodAttribute");
490 att
.Arguments
.Add (GetArg (soapOper
.SoapAction
));
491 if (inputMembers
.ElementName
!= method
.Name
) att
.Arguments
.Add (GetArg ("RequestElementName", inputMembers
.ElementName
));
492 if (outputMembers
!= null && outputMembers
.ElementName
!= (method
.Name
+ "Response")) att
.Arguments
.Add (GetArg ("ResponseElementName", outputMembers
.ElementName
));
493 att
.Arguments
.Add (GetArg ("RequestNamespace", inputMembers
.Namespace
));
494 if (outputMembers
!= null) att
.Arguments
.Add (GetArg ("ResponseNamespace", outputMembers
.Namespace
));
495 if (outputMembers
== null) att
.Arguments
.Add (GetArg ("OneWay", true));
499 if (outputMembers
!= null && (inputMembers
.ElementName
== "" && outputMembers
.ElementName
!= "" ||
500 inputMembers
.ElementName
!= "" && outputMembers
.ElementName
== ""))
501 throw new InvalidOperationException ("Parameter style is not the same for the input message and output message");
503 att
= new CodeAttributeDeclaration ("System.Web.Services.Protocols.SoapDocumentMethodAttribute");
504 att
.Arguments
.Add (GetArg (soapOper
.SoapAction
));
505 if (inputMembers
.ElementName
!= "") {
506 if (inputMembers
.ElementName
!= method
.Name
) att
.Arguments
.Add (GetArg ("RequestElementName", inputMembers
.ElementName
));
507 if (outputMembers
!= null && outputMembers
.ElementName
!= (method
.Name
+ "Response")) att
.Arguments
.Add (GetArg ("ResponseElementName", outputMembers
.ElementName
));
508 att
.Arguments
.Add (GetArg ("RequestNamespace", inputMembers
.Namespace
));
509 if (outputMembers
!= null) att
.Arguments
.Add (GetArg ("ResponseNamespace", outputMembers
.Namespace
));
510 att
.Arguments
.Add (GetEnumArg ("ParameterStyle", "System.Web.Services.Protocols.SoapParameterStyle", "Wrapped"));
513 att
.Arguments
.Add (GetEnumArg ("ParameterStyle", "System.Web.Services.Protocols.SoapParameterStyle", "Bare"));
515 if (outputMembers
== null) att
.Arguments
.Add (GetArg ("OneWay", true));
517 att
.Arguments
.Add (GetEnumArg ("Use", "System.Web.Services.Description.SoapBindingUse", bodyBinding
.Use
.ToString()));
520 AddCustomAttribute (method
, att
, true);
522 CodeTypeDeclaration
.Members
.Add (method
);
524 if (Style
== ServiceDescriptionImportStyle
.Client
) {
525 CodeTypeDeclaration
.Members
.Add (methodBegin
);
526 CodeTypeDeclaration
.Members
.Add (methodEnd
);
532 CodeParameterDeclarationExpression
GenerateParameter (XmlMemberMapping member
, FieldDirection dir
)
534 CodeParameterDeclarationExpression par
= new CodeParameterDeclarationExpression (member
.TypeFullName
, member
.MemberName
);
539 void GenerateMemberAttributes (XmlMembersMapping members
, XmlMemberMapping member
, SoapBindingUse use
, CodeParameterDeclarationExpression param
)
541 if (use
== SoapBindingUse
.Literal
)
542 xmlExporter
.AddMappingMetadata (param
.CustomAttributes
, member
, members
.Namespace
);
544 soapExporter
.AddMappingMetadata (param
.CustomAttributes
, member
);
547 void GenerateReturnAttributes (XmlMembersMapping members
, XmlMemberMapping member
, SoapBindingUse use
, CodeMemberMethod method
)
549 if (use
== SoapBindingUse
.Literal
)
550 xmlExporter
.AddMappingMetadata (method
.ReturnTypeCustomAttributes
, member
, members
.Namespace
, (member
.ElementName
!= method
.Name
+ "Result"));
552 soapExporter
.AddMappingMetadata (method
.ReturnTypeCustomAttributes
, member
, (member
.ElementName
!= method
.Name
+ "Result"));
555 void ImportHeaders (CodeMemberMethod method
)
557 foreach (object ob
in OperationBinding
.Input
.Extensions
)
559 SoapHeaderBinding hb
= ob
as SoapHeaderBinding
;
560 if (hb
== null) continue;
561 if (HasHeader (OperationBinding
.Output
, hb
))
562 ImportHeader (method
, hb
, SoapHeaderDirection
.In
| SoapHeaderDirection
.Out
);
564 ImportHeader (method
, hb
, SoapHeaderDirection
.In
);
567 if (OperationBinding
.Output
== null) return;
569 foreach (object ob
in OperationBinding
.Output
.Extensions
)
571 SoapHeaderBinding hb
= ob
as SoapHeaderBinding
;
572 if (hb
== null) continue;
573 if (!HasHeader (OperationBinding
.Input
, hb
))
574 ImportHeader (method
, hb
, SoapHeaderDirection
.Out
);
578 bool HasHeader (MessageBinding msg
, SoapHeaderBinding hb
)
580 if (msg
== null) return false;
582 foreach (object ob
in msg
.Extensions
)
584 SoapHeaderBinding mhb
= ob
as SoapHeaderBinding
;
585 if ((mhb
!= null) && (mhb
.Message
== hb
.Message
) && (mhb
.Part
== hb
.Part
))
591 void ImportHeader (CodeMemberMethod method
, SoapHeaderBinding hb
, SoapHeaderDirection direction
)
593 Message msg
= ServiceDescriptions
.GetMessage (hb
.Message
);
594 if (msg
== null) throw new InvalidOperationException ("Message " + hb
.Message
+ " not found");
595 MessagePart part
= msg
.Parts
[hb
.Part
];
596 if (part
== null) throw new InvalidOperationException ("Message part " + hb
.Part
+ " not found in message " + hb
.Message
);
599 if (hb
.Use
== SoapBindingUse
.Literal
)
601 map
= xmlImporter
.ImportDerivedTypeMapping (part
.Element
, typeof (SoapHeader
));
602 xmlExporter
.ExportTypeMapping (map
);
606 map
= soapImporter
.ImportDerivedTypeMapping (part
.Type
, typeof (SoapHeader
), true);
607 soapExporter
.ExportTypeMapping (map
);
610 bool required
= false;
612 string varName
= headerVariables
[map
] as string;
615 varName
= memberIds
.AddUnique(CodeIdentifier
.MakeValid (map
.TypeName
+ "Value"),hb
);
616 headerVariables
.Add (map
, varName
);
617 CodeMemberField codeField
= new CodeMemberField (map
.TypeFullName
, varName
);
618 codeField
.Attributes
= MemberAttributes
.Public
;
619 CodeTypeDeclaration
.Members
.Add (codeField
);
622 CodeAttributeDeclaration att
= new CodeAttributeDeclaration ("System.Web.Services.Protocols.SoapHeaderAttribute");
623 att
.Arguments
.Add (GetArg (varName
));
624 att
.Arguments
.Add (GetArg ("Required", required
));
625 if (direction
!= SoapHeaderDirection
.In
) att
.Arguments
.Add (GetEnumArg ("Direction", "System.Web.Services.Protocols.SoapHeaderDirection", direction
.ToString ()));
626 AddCustomAttribute (method
, att
, true);