**** Merged from MCS ****
[mono-project.git] / mcs / class / System.Web.Services / System.Web.Services.Description / SoapProtocolImporter.cs
blob1691ec674e574886e020b16bd521808c76ab8cee
1 //
2 // System.Web.Services.Description.SoapProtocolImporter.cs
3 //
4 // Author:
5 // Tim Coleman (tim@timcoleman.com)
6 // Lluis Sanchez Gual (lluis@ximian.com)
7 //
8 // Copyright (C) Tim Coleman, 2002
9 //
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:
19 //
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
22 //
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.
32 using System.CodeDom;
33 using System.Web.Services;
34 using System.Web.Services.Protocols;
35 using System.Web.Services.Configuration;
36 using System.Xml;
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 {
45 #region Fields
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;
58 #endregion // Fields
60 #region Constructors
62 public SoapProtocolImporter ()
64 extensionImporters = ExtensionManager.BuildExtensionImporters ();
67 void SetBinding (SoapBinding soapBinding)
69 this.soapBinding = soapBinding;
72 #endregion // Constructors
74 #region Properties
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
102 #region Methods
104 protected override CodeTypeDeclaration BeginClass ()
106 soapBinding = (SoapBinding) Binding.Extensions.Find (typeof(SoapBinding));
108 CodeTypeDeclaration codeClass = new CodeTypeDeclaration (ClassName);
110 string location = null;
112 if (Port != 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);
124 else {
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 ();
146 return codeClass;
149 protected override void BeginNamespace ()
151 #if NET_2_0
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);
156 #else
157 xmlImporter = new XmlSchemaImporter (LiteralSchemas, ClassNames);
158 soapImporter = new SoapSchemaImporter (EncodedSchemas, ClassNames);
159 xmlExporter = new XmlCodeExporter (CodeNamespace, null);
160 soapExporter = new SoapCodeExporter (CodeNamespace, null);
161 #endif
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;
189 [MonoTODO]
190 protected override bool IsOperationFlowSupported (OperationFlow flow)
192 throw new NotImplementedException ();
195 [MonoTODO]
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);
236 else
237 soapExporter.ExportMembersMapping (inputMembers);
239 if (osbb != null) {
240 if (osbb.Use == SoapBindingUse.Literal)
241 xmlExporter.ExportMembersMapping (outputMembers);
242 else
243 soapExporter.ExportMembersMapping (outputMembers);
246 foreach (SoapExtensionImporter eximporter in extensionImporters)
248 eximporter.ImportContext = this;
249 eximporter.ImportMethod (met.CustomAttributes);
252 return met;
254 catch (InvalidOperationException ex)
256 UnsupportedOperationBindingWarning (ex.Message);
257 return null;
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);
278 else
279 return xmlImporter.ImportMembersMapping (part.Element);
281 else
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;
291 mems[n] = mem;
294 // Rpc messages always have a wrapping element
295 if (style == SoapBindingStyle.Rpc)
296 return soapImporter.ImportMembersMapping (elemName, sbb.Namespace, mems, true);
297 else
298 return soapImporter.ImportMembersMapping ("", "", mems, false);
300 else
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);
307 else
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);
373 outParams [n] = cpd;
375 bool found = false;
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));
381 found = true;
382 break;
386 if (found) continue;
388 if (!hasReturn)
390 hasReturn = true;
391 method.ReturnType = cpd.Type;
392 methodEnd.ReturnType = cpd.Type;
393 GenerateReturnAttributes (outputMembers, outputMembers[n], bodyBinding.Use, method);
394 outParams [n] = null;
395 continue;
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);
413 else
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));
428 else
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)
438 // Invoke call
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);
452 else
453 method.Statements.Add (inv);
455 // Begin Invoke Call
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));
462 // End Invoke call
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);
472 else
473 methodEnd.Statements.Add (inv);
475 else {
476 method.Attributes = MemberAttributes.Public | MemberAttributes.Abstract;
479 // Attributes
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));
497 else
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"));
512 else
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);
529 return method;
532 CodeParameterDeclarationExpression GenerateParameter (XmlMemberMapping member, FieldDirection dir)
534 CodeParameterDeclarationExpression par = new CodeParameterDeclarationExpression (member.TypeFullName, member.MemberName);
535 par.Direction = dir;
536 return par;
539 void GenerateMemberAttributes (XmlMembersMapping members, XmlMemberMapping member, SoapBindingUse use, CodeParameterDeclarationExpression param)
541 if (use == SoapBindingUse.Literal)
542 xmlExporter.AddMappingMetadata (param.CustomAttributes, member, members.Namespace);
543 else
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"));
551 else
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);
563 else
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))
586 return true;
588 return false;
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);
598 XmlTypeMapping map;
599 if (hb.Use == SoapBindingUse.Literal)
601 map = xmlImporter.ImportDerivedTypeMapping (part.Element, typeof (SoapHeader));
602 xmlExporter.ExportTypeMapping (map);
604 else
606 map = soapImporter.ImportDerivedTypeMapping (part.Type, typeof (SoapHeader), true);
607 soapExporter.ExportTypeMapping (map);
610 bool required = false;
612 string varName = headerVariables [map] as string;
613 if (varName == null)
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);
629 #endregion