private void WriteReturnMappings(CodeMemberMethod codeMethod, CodeExpression invoke, SoapParameters parameters, string resultsName) { if ((parameters.Return == null) && (parameters.OutParameters.Count == 0)) { codeMethod.Statements.Add(new CodeExpressionStatement(invoke)); } else { codeMethod.Statements.Add(new CodeVariableDeclarationStatement(typeof(object[]), resultsName, invoke)); int num = (parameters.Return == null) ? 0 : 1; for (int i = 0; i < parameters.OutParameters.Count; i++) { SoapParameter parameter = (SoapParameter) parameters.OutParameters[i]; CodeExpression left = new CodeArgumentReferenceExpression(parameter.name); CodeExpression expression = new CodeArrayIndexerExpression(); ((CodeArrayIndexerExpression) expression).TargetObject = new CodeVariableReferenceExpression(resultsName); ((CodeArrayIndexerExpression) expression).Indices.Add(new CodePrimitiveExpression(num++)); expression = new CodeCastExpression(WebCodeGenerator.FullTypeName(parameter.mapping, base.ServiceImporter.CodeGenerator), expression); codeMethod.Statements.Add(new CodeAssignStatement(left, expression)); if (parameter.mapping.CheckSpecified) { left = new CodeArgumentReferenceExpression(parameter.name + "Specified"); expression = new CodeArrayIndexerExpression(); ((CodeArrayIndexerExpression) expression).TargetObject = new CodeVariableReferenceExpression(resultsName); ((CodeArrayIndexerExpression) expression).Indices.Add(new CodePrimitiveExpression(num++)); expression = new CodeCastExpression(typeof(bool).FullName, expression); codeMethod.Statements.Add(new CodeAssignStatement(left, expression)); } } if (parameters.Return != null) { CodeExpression expression3 = new CodeArrayIndexerExpression(); ((CodeArrayIndexerExpression) expression3).TargetObject = new CodeVariableReferenceExpression(resultsName); ((CodeArrayIndexerExpression) expression3).Indices.Add(new CodePrimitiveExpression(0)); expression3 = new CodeCastExpression(WebCodeGenerator.FullTypeName(parameters.Return, base.ServiceImporter.CodeGenerator), expression3); codeMethod.Statements.Add(new CodeMethodReturnStatement(expression3)); } } }
void WriteReturnMappings(CodeMemberMethod codeMethod, CodeExpression invoke, SoapParameters parameters, string resultsName) { if (parameters.Return == null && parameters.OutParameters.Count == 0) { codeMethod.Statements.Add(new CodeExpressionStatement(invoke)); } else { codeMethod.Statements.Add(new CodeVariableDeclarationStatement(typeof(object[]), resultsName, invoke)); int count = parameters.Return == null ? 0 : 1; for (int i = 0; i < parameters.OutParameters.Count; i++) { SoapParameter parameter = (SoapParameter)parameters.OutParameters[i]; CodeExpression target = new CodeArgumentReferenceExpression(parameter.name); CodeExpression value = new CodeArrayIndexerExpression(); ((CodeArrayIndexerExpression)value).TargetObject = new CodeVariableReferenceExpression(resultsName); ((CodeArrayIndexerExpression)value).Indices.Add(new CodePrimitiveExpression(count++)); value = new CodeCastExpression(WebCodeGenerator.FullTypeName(parameter.mapping, ServiceImporter.CodeGenerator), value); codeMethod.Statements.Add(new CodeAssignStatement(target, value)); if (parameter.mapping.CheckSpecified) { target = new CodeArgumentReferenceExpression(parameter.name + "Specified"); value = new CodeArrayIndexerExpression(); ((CodeArrayIndexerExpression) value).TargetObject = new CodeVariableReferenceExpression(resultsName); ((CodeArrayIndexerExpression)value).Indices.Add(new CodePrimitiveExpression(count++)); value = new CodeCastExpression(typeof(bool).FullName, value); codeMethod.Statements.Add(new CodeAssignStatement(target, value)); } } if (parameters.Return != null) { CodeExpression value = new CodeArrayIndexerExpression(); ((CodeArrayIndexerExpression)value).TargetObject = new CodeVariableReferenceExpression(resultsName); ((CodeArrayIndexerExpression)value).Indices.Add(new CodePrimitiveExpression(0)); value = new CodeCastExpression(WebCodeGenerator.FullTypeName(parameters.Return, ServiceImporter.CodeGenerator), value); codeMethod.Statements.Add(new CodeMethodReturnStatement(value)); } } }
protected override CodeMemberMethod GenerateMethod() { Message outputMessage; SoapBodyBinding binding2; MessageBinding output; bool flag; SoapOperationBinding binding5 = (SoapOperationBinding) base.OperationBinding.Extensions.Find(typeof(SoapOperationBinding)); if (binding5 == null) { throw base.OperationBindingSyntaxException(System.Web.Services.Res.GetString("MissingSoapOperationBinding0")); } SoapBindingStyle soapBindingStyle = binding5.Style; if (soapBindingStyle == SoapBindingStyle.Default) { soapBindingStyle = this.SoapBinding.Style; } if (soapBindingStyle == SoapBindingStyle.Default) { soapBindingStyle = SoapBindingStyle.Document; } string[] parameterOrder = base.Operation.ParameterOrder; Message inputMessage = base.InputMessage; MessageBinding input = base.OperationBinding.Input; SoapBodyBinding soapBodyBinding = (SoapBodyBinding) base.OperationBinding.Input.Extensions.Find(typeof(SoapBodyBinding)); if (soapBodyBinding == null) { base.UnsupportedOperationBindingWarning(System.Web.Services.Res.GetString("MissingSoapBodyInputBinding0")); return null; } if (base.Operation.Messages.Output != null) { outputMessage = base.OutputMessage; output = base.OperationBinding.Output; binding2 = (SoapBodyBinding) base.OperationBinding.Output.Extensions.Find(typeof(SoapBodyBinding)); if (binding2 == null) { base.UnsupportedOperationBindingWarning(System.Web.Services.Res.GetString("MissingSoapBodyOutputBinding0")); return null; } } else { outputMessage = null; output = null; binding2 = null; } CodeAttributeDeclarationCollection metadata = new CodeAttributeDeclarationCollection(); this.PrepareHeaders(input); if (output != null) { this.PrepareHeaders(output); } string name = null; string str = (!string.IsNullOrEmpty(input.Name) && (soapBindingStyle != SoapBindingStyle.Rpc)) ? input.Name : base.Operation.Name; str = XmlConvert.DecodeName(str); if (output != null) { name = (!string.IsNullOrEmpty(output.Name) && (soapBindingStyle != SoapBindingStyle.Rpc)) ? output.Name : (base.Operation.Name + "Response"); name = XmlConvert.DecodeName(name); } this.GenerateExtensionMetadata(metadata); this.GenerateHeaders(metadata, soapBodyBinding.Use, soapBindingStyle == SoapBindingStyle.Rpc, input, output); MessagePart[] messageParts = this.GetMessageParts(inputMessage, soapBodyBinding); if (!this.CheckMessageStyles(base.MethodName, messageParts, soapBodyBinding, soapBindingStyle, out flag)) { return null; } MessagePart[] parts = null; if (outputMessage != null) { bool flag2; parts = this.GetMessageParts(outputMessage, binding2); if (!this.CheckMessageStyles(base.MethodName, parts, binding2, soapBindingStyle, out flag2)) { return null; } if (flag != flag2) { flag = false; } } bool flag3 = ((soapBindingStyle != SoapBindingStyle.Rpc) && flag) || ((soapBodyBinding.Use == SoapBindingUse.Literal) && (soapBindingStyle == SoapBindingStyle.Rpc)); XmlMembersMapping request = this.ImportMessage(str, messageParts, soapBodyBinding, soapBindingStyle, flag); if (request == null) { return null; } XmlMembersMapping response = null; if (outputMessage != null) { response = this.ImportMessage(name, parts, binding2, soapBindingStyle, flag); if (response == null) { return null; } } string str3 = CodeIdentifier.MakeValid(XmlConvert.DecodeName(base.Operation.Name)); if (base.ClassName == str3) { str3 = "Call" + str3; } string identifier = base.MethodNames.AddUnique(CodeIdentifier.MakeValid(XmlConvert.DecodeName(str3)), base.Operation); bool flag4 = str3 != identifier; CodeIdentifiers identifiers = new CodeIdentifiers(false); identifiers.AddReserved(identifier); SoapParameters parameters = new SoapParameters(request, response, parameterOrder, base.MethodNames); foreach (SoapParameter parameter in parameters.Parameters) { if ((parameter.IsOut || parameter.IsByRef) && !base.ServiceImporter.CodeGenerator.Supports(GeneratorSupport.ReferenceParameters)) { base.UnsupportedOperationWarning(System.Web.Services.Res.GetString("CodeGenSupportReferenceParameters", new object[] { base.ServiceImporter.CodeGenerator.GetType().Name })); return null; } parameter.name = identifiers.AddUnique(parameter.name, null); if (parameter.mapping.CheckSpecified) { parameter.specifiedName = identifiers.AddUnique(parameter.name + "Specified", null); } } if ((base.Style != ServiceDescriptionImportStyle.Client) || flag4) { this.BeginMetadata(); if (flag4) { this.AddMetadataProperty("MessageName", identifier); } this.EndMetadata(metadata, typeof(WebMethodAttribute), null); } this.BeginMetadata(); if ((flag3 && (request.ElementName.Length > 0)) && (request.ElementName != identifier)) { this.AddMetadataProperty("RequestElementName", request.ElementName); } if (request.Namespace != null) { this.AddMetadataProperty("RequestNamespace", request.Namespace); } if (response == null) { this.AddMetadataProperty("OneWay", true); } else { if ((flag3 && (response.ElementName.Length > 0)) && (response.ElementName != (identifier + "Response"))) { this.AddMetadataProperty("ResponseElementName", response.ElementName); } if (response.Namespace != null) { this.AddMetadataProperty("ResponseNamespace", response.Namespace); } } if (soapBindingStyle == SoapBindingStyle.Rpc) { if (soapBodyBinding.Use != SoapBindingUse.Encoded) { this.AddMetadataProperty("Use", (CodeExpression) new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(typeof(SoapBindingUse).FullName), Enum.Format(typeof(SoapBindingUse), soapBodyBinding.Use, "G"))); } this.EndMetadata(metadata, typeof(SoapRpcMethodAttribute), binding5.SoapAction); } else { this.AddMetadataProperty("Use", (CodeExpression) new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(typeof(SoapBindingUse).FullName), Enum.Format(typeof(SoapBindingUse), soapBodyBinding.Use, "G"))); this.AddMetadataProperty("ParameterStyle", (CodeExpression) new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(typeof(SoapParameterStyle).FullName), Enum.Format(typeof(SoapParameterStyle), flag ? SoapParameterStyle.Wrapped : SoapParameterStyle.Bare, "G"))); this.EndMetadata(metadata, typeof(SoapDocumentMethodAttribute), binding5.SoapAction); } base.IsEncodedBinding = base.IsEncodedBinding || (soapBodyBinding.Use == SoapBindingUse.Encoded); CodeAttributeDeclarationCollection[] parameterAttributes = new CodeAttributeDeclarationCollection[parameters.Parameters.Count + parameters.CheckSpecifiedCount]; int index = 0; CodeAttributeDeclaration declaration = new CodeAttributeDeclaration(typeof(XmlIgnoreAttribute).FullName); foreach (SoapParameter parameter2 in parameters.Parameters) { parameterAttributes[index] = new CodeAttributeDeclarationCollection(); if (soapBodyBinding.Use == SoapBindingUse.Encoded) { this.soapExporter.AddMappingMetadata(parameterAttributes[index], parameter2.mapping, parameter2.name != parameter2.mapping.MemberName); } else { string ns = (soapBindingStyle == SoapBindingStyle.Rpc) ? parameter2.mapping.Namespace : (parameter2.IsOut ? response.Namespace : request.Namespace); bool forceUseMemberName = parameter2.name != parameter2.mapping.MemberName; this.xmlExporter.AddMappingMetadata(parameterAttributes[index], parameter2.mapping, ns, forceUseMemberName); if (parameter2.mapping.CheckSpecified) { index++; parameterAttributes[index] = new CodeAttributeDeclarationCollection(); this.xmlExporter.AddMappingMetadata(parameterAttributes[index], parameter2.mapping, ns, parameter2.specifiedName != (parameter2.mapping.MemberName + "Specified")); parameterAttributes[index].Add(declaration); } } if ((parameterAttributes[index].Count > 0) && !base.ServiceImporter.CodeGenerator.Supports(GeneratorSupport.ParameterAttributes)) { base.UnsupportedOperationWarning(System.Web.Services.Res.GetString("CodeGenSupportParameterAttributes", new object[] { base.ServiceImporter.CodeGenerator.GetType().Name })); return null; } index++; } CodeFlags[] codeFlags = SoapParameter.GetCodeFlags(parameters.Parameters, parameters.CheckSpecifiedCount); string[] parameterTypeNames = SoapParameter.GetTypeFullNames(parameters.Parameters, parameters.CheckSpecifiedCount, base.ServiceImporter.CodeGenerator); string returnTypeName = (parameters.Return == null) ? typeof(void).FullName : WebCodeGenerator.FullTypeName(parameters.Return, base.ServiceImporter.CodeGenerator); CodeMemberMethod codeMethod = WebCodeGenerator.AddMethod(base.CodeTypeDeclaration, str3, codeFlags, parameterTypeNames, SoapParameter.GetNames(parameters.Parameters, parameters.CheckSpecifiedCount), parameterAttributes, returnTypeName, metadata, CodeFlags.IsPublic | ((base.Style == ServiceDescriptionImportStyle.Client) ? ((CodeFlags) 0) : CodeFlags.IsAbstract)); codeMethod.Comments.Add(new CodeCommentStatement(System.Web.Services.Res.GetString("CodeRemarks"), true)); if (parameters.Return != null) { if (soapBodyBinding.Use == SoapBindingUse.Encoded) { this.soapExporter.AddMappingMetadata(codeMethod.ReturnTypeCustomAttributes, parameters.Return, parameters.Return.ElementName != (identifier + "Result")); } else { this.xmlExporter.AddMappingMetadata(codeMethod.ReturnTypeCustomAttributes, parameters.Return, response.Namespace, parameters.Return.ElementName != (identifier + "Result")); } if ((codeMethod.ReturnTypeCustomAttributes.Count != 0) && !base.ServiceImporter.CodeGenerator.Supports(GeneratorSupport.ReturnTypeAttributes)) { base.UnsupportedOperationWarning(System.Web.Services.Res.GetString("CodeGenSupportReturnTypeAttributes", new object[] { base.ServiceImporter.CodeGenerator.GetType().Name })); return null; } } string resultsName = identifiers.MakeUnique("results"); if (base.Style == ServiceDescriptionImportStyle.Client) { bool flag6 = (base.ServiceImporter.CodeGenerationOptions & CodeGenerationOptions.GenerateOldAsync) != CodeGenerationOptions.None; bool flag7 = (((base.ServiceImporter.CodeGenerationOptions & CodeGenerationOptions.GenerateNewAsync) != CodeGenerationOptions.None) && base.ServiceImporter.CodeGenerator.Supports(GeneratorSupport.DeclareEvents)) && base.ServiceImporter.CodeGenerator.Supports(GeneratorSupport.DeclareDelegates); CodeExpression[] invokeParams = new CodeExpression[2]; this.CreateInvokeParams(invokeParams, identifier, parameters.InParameters, parameters.InCheckSpecifiedCount); CodeMethodInvokeExpression invoke = new CodeMethodInvokeExpression(new CodeThisReferenceExpression(), "Invoke", invokeParams); this.WriteReturnMappings(codeMethod, invoke, parameters, resultsName); if (flag6) { int num2 = parameters.InParameters.Count + parameters.InCheckSpecifiedCount; string[] typeFullNames = new string[num2 + 2]; SoapParameter.GetTypeFullNames(parameters.InParameters, typeFullNames, 0, parameters.InCheckSpecifiedCount, base.ServiceImporter.CodeGenerator); typeFullNames[num2] = typeof(AsyncCallback).FullName; typeFullNames[num2 + 1] = typeof(object).FullName; string[] strArray4 = new string[num2 + 2]; SoapParameter.GetNames(parameters.InParameters, strArray4, 0, parameters.InCheckSpecifiedCount); strArray4[num2] = "callback"; strArray4[num2 + 1] = "asyncState"; CodeFlags[] parameterFlags = new CodeFlags[num2 + 2]; CodeMemberMethod method2 = WebCodeGenerator.AddMethod(base.CodeTypeDeclaration, "Begin" + identifier, parameterFlags, typeFullNames, strArray4, typeof(IAsyncResult).FullName, null, CodeFlags.IsPublic); method2.Comments.Add(new CodeCommentStatement(System.Web.Services.Res.GetString("CodeRemarks"), true)); invokeParams = new CodeExpression[4]; this.CreateInvokeParams(invokeParams, identifier, parameters.InParameters, parameters.InCheckSpecifiedCount); invokeParams[2] = new CodeArgumentReferenceExpression("callback"); invokeParams[3] = new CodeArgumentReferenceExpression("asyncState"); invoke = new CodeMethodInvokeExpression(new CodeThisReferenceExpression(), "BeginInvoke", invokeParams); method2.Statements.Add(new CodeMethodReturnStatement(invoke)); int num3 = parameters.OutParameters.Count + parameters.OutCheckSpecifiedCount; string[] strArray5 = new string[num3 + 1]; SoapParameter.GetTypeFullNames(parameters.OutParameters, strArray5, 1, parameters.OutCheckSpecifiedCount, base.ServiceImporter.CodeGenerator); strArray5[0] = typeof(IAsyncResult).FullName; string[] strArray6 = new string[num3 + 1]; SoapParameter.GetNames(parameters.OutParameters, strArray6, 1, parameters.OutCheckSpecifiedCount); strArray6[0] = "asyncResult"; CodeFlags[] flagsArray3 = new CodeFlags[num3 + 1]; for (int i = 0; i < num3; i++) { flagsArray3[i + 1] = CodeFlags.IsOut; } CodeMemberMethod method3 = WebCodeGenerator.AddMethod(base.CodeTypeDeclaration, "End" + identifier, flagsArray3, strArray5, strArray6, (parameters.Return == null) ? typeof(void).FullName : WebCodeGenerator.FullTypeName(parameters.Return, base.ServiceImporter.CodeGenerator), null, CodeFlags.IsPublic); method3.Comments.Add(new CodeCommentStatement(System.Web.Services.Res.GetString("CodeRemarks"), true)); CodeExpression expression2 = new CodeArgumentReferenceExpression("asyncResult"); invoke = new CodeMethodInvokeExpression(new CodeThisReferenceExpression(), "EndInvoke", new CodeExpression[] { expression2 }); this.WriteReturnMappings(method3, invoke, parameters, resultsName); } if (!flag7) { return codeMethod; } string str8 = ProtocolImporter.MethodSignature(identifier, returnTypeName, codeFlags, parameterTypeNames); DelegateInfo info = (DelegateInfo) base.ExportContext[str8]; if (info == null) { string handlerType = base.ClassNames.AddUnique(identifier + "CompletedEventHandler", identifier); string handlerArgs = base.ClassNames.AddUnique(identifier + "CompletedEventArgs", identifier); info = new DelegateInfo(handlerType, handlerArgs); } string handlerName = base.MethodNames.AddUnique(identifier + "Completed", identifier); string methodName = base.MethodNames.AddUnique(identifier + "Async", identifier); string callbackMember = base.MethodNames.AddUnique(identifier + "OperationCompleted", identifier); string callbackName = base.MethodNames.AddUnique("On" + identifier + "OperationCompleted", identifier); WebCodeGenerator.AddEvent(base.CodeTypeDeclaration.Members, info.handlerType, handlerName); WebCodeGenerator.AddCallbackDeclaration(base.CodeTypeDeclaration.Members, callbackMember); string[] names = SoapParameter.GetNames(parameters.InParameters, parameters.InCheckSpecifiedCount); string userState = ProtocolImporter.UniqueName("userState", names); CodeMemberMethod method4 = WebCodeGenerator.AddAsyncMethod(base.CodeTypeDeclaration, methodName, SoapParameter.GetTypeFullNames(parameters.InParameters, parameters.InCheckSpecifiedCount, base.ServiceImporter.CodeGenerator), names, callbackMember, callbackName, userState); invokeParams = new CodeExpression[4]; this.CreateInvokeParams(invokeParams, identifier, parameters.InParameters, parameters.InCheckSpecifiedCount); invokeParams[2] = new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), callbackMember); invokeParams[3] = new CodeArgumentReferenceExpression(userState); invoke = new CodeMethodInvokeExpression(new CodeThisReferenceExpression(), "InvokeAsync", invokeParams); method4.Statements.Add(invoke); bool methodHasOutParameters = (parameters.Return != null) || (parameters.OutParameters.Count > 0); WebCodeGenerator.AddCallbackImplementation(base.CodeTypeDeclaration, callbackName, handlerName, info.handlerArgs, methodHasOutParameters); if (base.ExportContext[str8] != null) { return codeMethod; } WebCodeGenerator.AddDelegate(base.ExtraCodeClasses, info.handlerType, methodHasOutParameters ? info.handlerArgs : typeof(AsyncCompletedEventArgs).FullName); if (methodHasOutParameters) { int num5 = parameters.OutParameters.Count + parameters.OutCheckSpecifiedCount; string[] strArray8 = new string[num5 + 1]; SoapParameter.GetTypeFullNames(parameters.OutParameters, strArray8, 1, parameters.OutCheckSpecifiedCount, base.ServiceImporter.CodeGenerator); strArray8[0] = (parameters.Return == null) ? null : WebCodeGenerator.FullTypeName(parameters.Return, base.ServiceImporter.CodeGenerator); string[] strArray9 = new string[num5 + 1]; SoapParameter.GetNames(parameters.OutParameters, strArray9, 1, parameters.OutCheckSpecifiedCount); strArray9[0] = (parameters.Return == null) ? null : "Result"; base.ExtraCodeClasses.Add(WebCodeGenerator.CreateArgsClass(info.handlerArgs, strArray8, strArray9, base.ServiceImporter.CodeGenerator.Supports(GeneratorSupport.PartialTypes))); } base.ExportContext[str8] = info; } return codeMethod; }
/// <include file='doc\SoapProtocolImporter.uex' path='docs/doc[@for="SoapProtocolImporter.GenerateMethod"]/*' /> /// <devdoc> /// <para>[To be supplied.]</para> /// </devdoc> protected override CodeMemberMethod GenerateMethod() { Message requestMessage; Message responseMessage; string[] parameterOrder; SoapBodyBinding soapRequestBinding; SoapBodyBinding soapResponseBinding; MessageBinding requestBinding; MessageBinding responseBinding; SoapOperationBinding soapOperationBinding = (SoapOperationBinding)this.OperationBinding.Extensions.Find(typeof(SoapOperationBinding)); if (soapOperationBinding == null) throw OperationBindingSyntaxException(Res.GetString(Res.MissingSoapOperationBinding0)); SoapBindingStyle soapBindingStyle = soapOperationBinding.Style; if (soapBindingStyle == SoapBindingStyle.Default) soapBindingStyle = SoapBinding.Style; if (soapBindingStyle == SoapBindingStyle.Default) soapBindingStyle = SoapBindingStyle.Document; parameterOrder = this.Operation.ParameterOrder; requestMessage = this.InputMessage; requestBinding = this.OperationBinding.Input; soapRequestBinding = (SoapBodyBinding)this.OperationBinding.Input.Extensions.Find(typeof(SoapBodyBinding)); if (soapRequestBinding == null) { UnsupportedOperationBindingWarning(Res.GetString(Res.MissingSoapBodyInputBinding0)); return null; } if (this.Operation.Messages.Output != null) { responseMessage = this.OutputMessage; responseBinding = this.OperationBinding.Output; soapResponseBinding = (SoapBodyBinding)this.OperationBinding.Output.Extensions.Find(typeof(SoapBodyBinding)); if (soapResponseBinding == null) { UnsupportedOperationBindingWarning(Res.GetString(Res.MissingSoapBodyOutputBinding0)); return null; } } else { responseMessage = null; responseBinding = null; soapResponseBinding = null; } CodeAttributeDeclarationCollection metadata = new CodeAttributeDeclarationCollection(); PrepareHeaders(requestBinding); if (responseBinding != null) PrepareHeaders(responseBinding); string requestMessageName; string responseMessageName = null; requestMessageName = !String.IsNullOrEmpty(requestBinding.Name) && soapBindingStyle != SoapBindingStyle.Rpc ? requestBinding.Name : this.Operation.Name; // per WSDL 1.1 sec 3.5 requestMessageName = XmlConvert.DecodeName(requestMessageName); if (responseBinding != null) { responseMessageName = !String.IsNullOrEmpty(responseBinding.Name) && soapBindingStyle != SoapBindingStyle.Rpc ? responseBinding.Name : this.Operation.Name + "Response"; // per WSDL 1.1 sec 3.5 responseMessageName = XmlConvert.DecodeName(responseMessageName); } GenerateExtensionMetadata(metadata); GenerateHeaders(metadata, soapRequestBinding.Use, soapBindingStyle == SoapBindingStyle.Rpc, requestBinding, responseBinding); MessagePart[] requestParts = GetMessageParts(requestMessage, soapRequestBinding); bool hasWrapper; if (!CheckMessageStyles(MethodName, requestParts, soapRequestBinding, soapBindingStyle, out hasWrapper)) return null; MessagePart[] responseParts = null; if (responseMessage != null) { responseParts = GetMessageParts(responseMessage, soapResponseBinding); bool responseHasWrapper; if (!CheckMessageStyles(MethodName, responseParts, soapResponseBinding, soapBindingStyle, out responseHasWrapper)) return null; // since we're using a potentially inaccurate heuristic to determine whether there's a wrapper, // if we disagree about the request and response we should assume there isn't a wrapper. if (hasWrapper != responseHasWrapper) hasWrapper = false; } bool wrapperNamesMatter = (soapBindingStyle != SoapBindingStyle.Rpc && hasWrapper) || (soapRequestBinding.Use == SoapBindingUse.Literal && soapBindingStyle == SoapBindingStyle.Rpc); XmlMembersMapping request = ImportMessage(requestMessageName, requestParts, soapRequestBinding, soapBindingStyle, hasWrapper); if (request == null) return null; XmlMembersMapping response = null; if (responseMessage != null) { response = ImportMessage(responseMessageName, responseParts, soapResponseBinding, soapBindingStyle, hasWrapper); if (response == null) return null; } string methodName = CodeIdentifier.MakeValid(XmlConvert.DecodeName(this.Operation.Name)); if (ClassName == methodName) { methodName = "Call" + methodName; } string uniqueMethodName = MethodNames.AddUnique(CodeIdentifier.MakeValid(XmlConvert.DecodeName(methodName)), this.Operation); bool differentNames = methodName != uniqueMethodName; CodeIdentifiers localIdentifiers = new CodeIdentifiers(false); localIdentifiers.AddReserved(uniqueMethodName); SoapParameters parameters = new SoapParameters(request, response, parameterOrder, MethodNames); foreach (SoapParameter param in parameters.Parameters) { if ((param.IsOut || param.IsByRef) && !ServiceImporter.CodeGenerator.Supports(GeneratorSupport.ReferenceParameters)) { UnsupportedOperationWarning(Res.GetString(Res.CodeGenSupportReferenceParameters, ServiceImporter.CodeGenerator.GetType().Name)); return null; } param.name = localIdentifiers.AddUnique(param.name, null); if (param.mapping.CheckSpecified) param.specifiedName = localIdentifiers.AddUnique(param.name + "Specified", null); } if (!(Style == ServiceDescriptionImportStyle.Client) || differentNames) { BeginMetadata(); if (differentNames) AddMetadataProperty("MessageName", uniqueMethodName); EndMetadata(metadata, typeof(WebMethodAttribute), null); } BeginMetadata(); if (wrapperNamesMatter && request.ElementName.Length > 0 && request.ElementName != uniqueMethodName) AddMetadataProperty("RequestElementName", request.ElementName); if (request.Namespace != null) AddMetadataProperty("RequestNamespace", request.Namespace); if (response == null) { AddMetadataProperty("OneWay", true); } else { if (wrapperNamesMatter && response.ElementName.Length > 0 && response.ElementName != (uniqueMethodName + "Response")) AddMetadataProperty("ResponseElementName", response.ElementName); if (response.Namespace != null) AddMetadataProperty("ResponseNamespace", response.Namespace); } if (soapBindingStyle == SoapBindingStyle.Rpc) { if (soapRequestBinding.Use != SoapBindingUse.Encoded) { AddMetadataProperty("Use", new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(typeof(SoapBindingUse).FullName), Enum.Format(typeof(SoapBindingUse), soapRequestBinding.Use, "G"))); } EndMetadata(metadata, typeof(SoapRpcMethodAttribute), soapOperationBinding.SoapAction); } else { AddMetadataProperty("Use", new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(typeof(SoapBindingUse).FullName), Enum.Format(typeof(SoapBindingUse), soapRequestBinding.Use, "G"))); AddMetadataProperty("ParameterStyle", new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(typeof(SoapParameterStyle).FullName), Enum.Format(typeof(SoapParameterStyle), hasWrapper ? SoapParameterStyle.Wrapped : SoapParameterStyle.Bare, "G"))); EndMetadata(metadata, typeof(SoapDocumentMethodAttribute), soapOperationBinding.SoapAction); } IsEncodedBinding = IsEncodedBinding || (soapRequestBinding.Use == SoapBindingUse.Encoded); CodeAttributeDeclarationCollection[] paramsMetadata = new CodeAttributeDeclarationCollection[parameters.Parameters.Count + parameters.CheckSpecifiedCount]; int j = 0; CodeAttributeDeclaration ignoreAttribute = new CodeAttributeDeclaration(typeof(XmlIgnoreAttribute).FullName); foreach (SoapParameter parameter in parameters.Parameters) { paramsMetadata[j] = new CodeAttributeDeclarationCollection(); if (soapRequestBinding.Use == SoapBindingUse.Encoded) soapExporter.AddMappingMetadata(paramsMetadata[j], parameter.mapping, parameter.name != parameter.mapping.MemberName); else { string ns = soapBindingStyle == SoapBindingStyle.Rpc ? parameter.mapping.Namespace : parameter.IsOut ? response.Namespace : request.Namespace; bool forceUseMemberName = parameter.name != parameter.mapping.MemberName; xmlExporter.AddMappingMetadata(paramsMetadata[j], parameter.mapping, ns, forceUseMemberName); if (parameter.mapping.CheckSpecified) { j++; paramsMetadata[j] = new CodeAttributeDeclarationCollection(); xmlExporter.AddMappingMetadata(paramsMetadata[j], parameter.mapping, ns, parameter.specifiedName != parameter.mapping.MemberName + "Specified"); paramsMetadata[j].Add(ignoreAttribute); } } if (paramsMetadata[j].Count > 0 && !ServiceImporter.CodeGenerator.Supports(GeneratorSupport.ParameterAttributes)) { UnsupportedOperationWarning(Res.GetString(Res.CodeGenSupportParameterAttributes, ServiceImporter.CodeGenerator.GetType().Name)); return null; } j++; } CodeFlags[] parameterFlags = SoapParameter.GetCodeFlags(parameters.Parameters, parameters.CheckSpecifiedCount); string[] parameterTypes = SoapParameter.GetTypeFullNames(parameters.Parameters, parameters.CheckSpecifiedCount, ServiceImporter.CodeGenerator); string returnType = parameters.Return == null ? typeof(void).FullName : WebCodeGenerator.FullTypeName(parameters.Return, ServiceImporter.CodeGenerator); CodeMemberMethod mainCodeMethod = WebCodeGenerator.AddMethod(this.CodeTypeDeclaration, methodName, parameterFlags, parameterTypes, SoapParameter.GetNames(parameters.Parameters, parameters.CheckSpecifiedCount), paramsMetadata, returnType, metadata, CodeFlags.IsPublic | (Style == ServiceDescriptionImportStyle.Client ? 0 : CodeFlags.IsAbstract)); mainCodeMethod.Comments.Add(new CodeCommentStatement(Res.GetString(Res.CodeRemarks), true)); if (parameters.Return != null) { if (soapRequestBinding.Use == SoapBindingUse.Encoded) soapExporter.AddMappingMetadata(mainCodeMethod.ReturnTypeCustomAttributes, parameters.Return, parameters.Return.ElementName != uniqueMethodName + "Result"); else xmlExporter.AddMappingMetadata(mainCodeMethod.ReturnTypeCustomAttributes, parameters.Return, response.Namespace, parameters.Return.ElementName != uniqueMethodName + "Result"); if (mainCodeMethod.ReturnTypeCustomAttributes.Count != 0 && !ServiceImporter.CodeGenerator.Supports(GeneratorSupport.ReturnTypeAttributes)) { UnsupportedOperationWarning(Res.GetString(Res.CodeGenSupportReturnTypeAttributes, ServiceImporter.CodeGenerator.GetType().Name)); return null; } } string resultsName = localIdentifiers.MakeUnique("results"); if (Style == ServiceDescriptionImportStyle.Client) { bool oldAsync = (ServiceImporter.CodeGenerationOptions & CodeGenerationOptions.GenerateOldAsync) != 0; bool newAsync = (ServiceImporter.CodeGenerationOptions & CodeGenerationOptions.GenerateNewAsync) != 0 && ServiceImporter.CodeGenerator.Supports(GeneratorSupport.DeclareEvents) && ServiceImporter.CodeGenerator.Supports(GeneratorSupport.DeclareDelegates); CodeExpression[] invokeParams = new CodeExpression[2]; CreateInvokeParams(invokeParams, uniqueMethodName, parameters.InParameters, parameters.InCheckSpecifiedCount); CodeMethodInvokeExpression invoke = new CodeMethodInvokeExpression(new CodeThisReferenceExpression(), "Invoke", invokeParams); WriteReturnMappings(mainCodeMethod, invoke, parameters, resultsName); if (oldAsync) { int inCount = parameters.InParameters.Count + parameters.InCheckSpecifiedCount; string[] asyncParameterTypes = new string[inCount + 2]; SoapParameter.GetTypeFullNames(parameters.InParameters, asyncParameterTypes, 0, parameters.InCheckSpecifiedCount, ServiceImporter.CodeGenerator); asyncParameterTypes[inCount] = typeof(AsyncCallback).FullName; asyncParameterTypes[inCount + 1] = typeof(object).FullName; string[] asyncParameterNames = new string[inCount + 2]; SoapParameter.GetNames(parameters.InParameters, asyncParameterNames, 0, parameters.InCheckSpecifiedCount); asyncParameterNames[inCount] = "callback"; asyncParameterNames[inCount + 1] = "asyncState"; CodeFlags[] asyncParameterFlags = new CodeFlags[inCount + 2]; CodeMemberMethod beginCodeMethod = WebCodeGenerator.AddMethod(this.CodeTypeDeclaration, "Begin" + uniqueMethodName, asyncParameterFlags, asyncParameterTypes, asyncParameterNames, typeof(IAsyncResult).FullName, null, CodeFlags.IsPublic); beginCodeMethod.Comments.Add(new CodeCommentStatement(Res.GetString(Res.CodeRemarks), true)); invokeParams = new CodeExpression[4]; CreateInvokeParams(invokeParams, uniqueMethodName, parameters.InParameters, parameters.InCheckSpecifiedCount); invokeParams[2] = new CodeArgumentReferenceExpression("callback"); invokeParams[3] = new CodeArgumentReferenceExpression("asyncState"); invoke = new CodeMethodInvokeExpression(new CodeThisReferenceExpression(), "BeginInvoke", invokeParams); beginCodeMethod.Statements.Add(new CodeMethodReturnStatement(invoke)); int outCount = parameters.OutParameters.Count + parameters.OutCheckSpecifiedCount; string[] asyncReturnTypes = new string[outCount + 1]; SoapParameter.GetTypeFullNames(parameters.OutParameters, asyncReturnTypes, 1, parameters.OutCheckSpecifiedCount, ServiceImporter.CodeGenerator); asyncReturnTypes[0] = typeof(IAsyncResult).FullName; string[] asyncReturnNames = new string[outCount + 1]; SoapParameter.GetNames(parameters.OutParameters, asyncReturnNames, 1, parameters.OutCheckSpecifiedCount); asyncReturnNames[0] = "asyncResult"; CodeFlags[] asyncReturnFlags = new CodeFlags[outCount + 1]; for (int i = 0; i < outCount; i++) asyncReturnFlags[i + 1] = CodeFlags.IsOut; CodeMemberMethod codeMethod = WebCodeGenerator.AddMethod(this.CodeTypeDeclaration, "End" + uniqueMethodName, asyncReturnFlags, asyncReturnTypes, asyncReturnNames, parameters.Return == null ? typeof(void).FullName : WebCodeGenerator.FullTypeName(parameters.Return, ServiceImporter.CodeGenerator), null, CodeFlags.IsPublic); codeMethod.Comments.Add(new CodeCommentStatement(Res.GetString(Res.CodeRemarks), true)); CodeExpression invokeParam = new CodeArgumentReferenceExpression("asyncResult"); invoke = new CodeMethodInvokeExpression(new CodeThisReferenceExpression(), "EndInvoke", new CodeExpression[] { invokeParam }); WriteReturnMappings(codeMethod, invoke, parameters, resultsName); } // new RAD Async pattern if (newAsync) { string methodKey = MethodSignature(uniqueMethodName, returnType, parameterFlags, parameterTypes); DelegateInfo delegateInfo = (DelegateInfo)ExportContext[methodKey]; if (delegateInfo == null) { string handlerType = ClassNames.AddUnique(uniqueMethodName + "CompletedEventHandler", uniqueMethodName); string handlerArgs = ClassNames.AddUnique(uniqueMethodName + "CompletedEventArgs", uniqueMethodName); delegateInfo = new DelegateInfo(handlerType, handlerArgs); } string handlerName = MethodNames.AddUnique(uniqueMethodName + "Completed", uniqueMethodName); string asyncName = MethodNames.AddUnique(uniqueMethodName + "Async", uniqueMethodName); string callbackMember = MethodNames.AddUnique(uniqueMethodName + "OperationCompleted", uniqueMethodName); string callbackName = MethodNames.AddUnique("On" + uniqueMethodName + "OperationCompleted", uniqueMethodName); // public event xxxCompletedEventHandler xxxCompleted; WebCodeGenerator.AddEvent(this.CodeTypeDeclaration.Members, delegateInfo.handlerType, handlerName); // private SendOrPostCallback xxxOperationCompleted; WebCodeGenerator.AddCallbackDeclaration(this.CodeTypeDeclaration.Members, callbackMember); // create the pair of xxxAsync methods string[] inParamNames = SoapParameter.GetNames(parameters.InParameters, parameters.InCheckSpecifiedCount); string userState = UniqueName("userState", inParamNames); CodeMemberMethod asyncCodeMethod = WebCodeGenerator.AddAsyncMethod(this.CodeTypeDeclaration, asyncName, SoapParameter.GetTypeFullNames(parameters.InParameters, parameters.InCheckSpecifiedCount, ServiceImporter.CodeGenerator), inParamNames, callbackMember, callbackName, userState); // Generate InvokeAsync call invokeParams = new CodeExpression[4]; CreateInvokeParams(invokeParams, uniqueMethodName, parameters.InParameters, parameters.InCheckSpecifiedCount); invokeParams[2] = new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), callbackMember); invokeParams[3] = new CodeArgumentReferenceExpression(userState); invoke = new CodeMethodInvokeExpression(new CodeThisReferenceExpression(), "InvokeAsync", invokeParams); asyncCodeMethod.Statements.Add(invoke); // private void On_xxx_OperationCompleted(object arg) {..} bool methodHasOutParameters = parameters.Return != null || parameters.OutParameters.Count > 0; WebCodeGenerator.AddCallbackImplementation(this.CodeTypeDeclaration, callbackName, handlerName, delegateInfo.handlerArgs, methodHasOutParameters); if (ExportContext[methodKey] == null) { // public delegate void xxxCompletedEventHandler(object sender, System.ComponentModel.AsyncCompletedEventArgs args); WebCodeGenerator.AddDelegate(ExtraCodeClasses, delegateInfo.handlerType, methodHasOutParameters ? delegateInfo.handlerArgs : typeof(AsyncCompletedEventArgs).FullName); // Create strongly-typed Args class if (methodHasOutParameters) { int outCount = parameters.OutParameters.Count + parameters.OutCheckSpecifiedCount; string[] asyncReturnTypes = new string[outCount + 1]; SoapParameter.GetTypeFullNames(parameters.OutParameters, asyncReturnTypes, 1, parameters.OutCheckSpecifiedCount, ServiceImporter.CodeGenerator); asyncReturnTypes[0] = parameters.Return == null ? null : WebCodeGenerator.FullTypeName(parameters.Return, ServiceImporter.CodeGenerator); string[] asyncReturnNames = new string[outCount + 1]; SoapParameter.GetNames(parameters.OutParameters, asyncReturnNames, 1, parameters.OutCheckSpecifiedCount); asyncReturnNames[0] = parameters.Return == null ? null : "Result"; ExtraCodeClasses.Add(WebCodeGenerator.CreateArgsClass(delegateInfo.handlerArgs, asyncReturnTypes, asyncReturnNames, ServiceImporter.CodeGenerator.Supports(GeneratorSupport.PartialTypes))); } ExportContext[methodKey] = delegateInfo; } } } return mainCodeMethod; }