1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
|
//------------------------------------------------------------------------------
// <copyright file="Soap12ProtocolReflector.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
namespace System.Web.Services.Description {
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Xml;
using System.Xml.Serialization;
using System.Xml.Schema;
using System.Collections;
using System;
using System.Reflection;
using System.Web.Services.Configuration;
internal class Soap12ProtocolReflector : SoapProtocolReflector {
Hashtable requestElements;
Hashtable actions;
XmlQualifiedName soap11PortType;
internal override WsiProfiles ConformsTo {
get { return WsiProfiles.None; }
}
public override string ProtocolName {
get { return "Soap12"; }
}
protected override void BeginClass() {
requestElements = new Hashtable();
actions = new Hashtable();
soap11PortType = null;
base.BeginClass();
}
protected override bool ReflectMethod() {
if (base.ReflectMethod()) {
if (Binding != null) {
// SoapMethod.portType tracks the first portType created for this method
// we want to make sure there's only one portType and set of messages per method
// so we delete ours if an existing portType already exists for this method.
soap11PortType = SoapMethod.portType;
if (soap11PortType != Binding.Type)
HeaderMessages.Clear();
}
return true;
}
return false;
}
protected override void EndClass() {
if (PortType == null || Binding == null) return; // external binding;
if (soap11PortType != null && soap11PortType != Binding.Type) {
// we want to share soap 1.1's portType and messages so we delete ours and reference theirs
foreach (Operation op in PortType.Operations) {
foreach (OperationMessage msg in op.Messages) {
ServiceDescription sd = GetServiceDescription(msg.Message.Namespace);
if (sd != null) {
Message m = sd.Messages[msg.Message.Name];
if (m != null)
sd.Messages.Remove(m);
}
}
}
Binding.Type = soap11PortType;
PortType.ServiceDescription.PortTypes.Remove(PortType);
}
}
protected override SoapBinding CreateSoapBinding(SoapBindingStyle style) {
Soap12Binding soapBinding = new Soap12Binding();
soapBinding.Transport = Soap12Binding.HttpTransport;
soapBinding.Style = style;
return soapBinding;
}
protected override SoapAddressBinding CreateSoapAddressBinding(string serviceUrl) {
Soap12AddressBinding soapAddress = new Soap12AddressBinding();
soapAddress.Location = serviceUrl;
if (this.UriFixups != null)
{
this.UriFixups.Add(delegate(Uri current)
{
soapAddress.Location = DiscoveryServerType.CombineUris(current, soapAddress.Location);
});
}
return soapAddress;
}
protected override SoapOperationBinding CreateSoapOperationBinding(SoapBindingStyle style, string action) {
Soap12OperationBinding soapOperation = new Soap12OperationBinding();
soapOperation.SoapAction = action;
soapOperation.Style = style;
soapOperation.Method = SoapMethod;
DealWithAmbiguity(action, SoapMethod.requestElementName.ToString(), soapOperation);
return soapOperation;
}
protected override SoapBodyBinding CreateSoapBodyBinding(SoapBindingUse use, string ns) {
Soap12BodyBinding soapBodyBinding = new Soap12BodyBinding();
soapBodyBinding.Use = use;
if (use == SoapBindingUse.Encoded)
soapBodyBinding.Encoding = Soap12.Encoding;
soapBodyBinding.Namespace = ns;
return soapBodyBinding;
}
protected override SoapHeaderBinding CreateSoapHeaderBinding(XmlQualifiedName message, string partName, SoapBindingUse use) {
return CreateSoapHeaderBinding(message, partName, null, use);
}
protected override SoapHeaderBinding CreateSoapHeaderBinding(XmlQualifiedName message, string partName, string ns, SoapBindingUse use) {
Soap12HeaderBinding soapHeaderBinding = new Soap12HeaderBinding();
soapHeaderBinding.Message = message;
soapHeaderBinding.Part = partName;
soapHeaderBinding.Namespace = ns;
soapHeaderBinding.Use = use;
if (use == SoapBindingUse.Encoded)
soapHeaderBinding.Encoding = Soap12.Encoding;
return soapHeaderBinding;
}
private void DealWithAmbiguity(string action, string requestElement, Soap12OperationBinding operation) {
Soap12OperationBinding duplicateActionOperation = (Soap12OperationBinding)actions[action];
if (duplicateActionOperation != null) {
operation.DuplicateBySoapAction = duplicateActionOperation;
duplicateActionOperation.DuplicateBySoapAction = operation;
CheckOperationDuplicates(duplicateActionOperation);
}
else
actions[action] = operation;
Soap12OperationBinding duplicateRequestElementOperation = (Soap12OperationBinding)requestElements[requestElement];
if (duplicateRequestElementOperation != null) {
operation.DuplicateByRequestElement = duplicateRequestElementOperation;
duplicateRequestElementOperation.DuplicateByRequestElement = operation;
CheckOperationDuplicates(duplicateRequestElementOperation);
}
else
requestElements[requestElement] = operation;
CheckOperationDuplicates(operation);
}
private void CheckOperationDuplicates(Soap12OperationBinding operation) {
// we require soap action if we can't route on request element
if (operation.DuplicateByRequestElement != null) {
// except if we also can't route on soap action, which is an error
if (operation.DuplicateBySoapAction != null)
throw new InvalidOperationException(Res.GetString(Res.TheMethodsAndUseTheSameRequestElementAndSoapActionXmlns6, operation.Method.name, operation.DuplicateByRequestElement.Method.name, operation.Method.requestElementName.Name, operation.Method.requestElementName.Namespace, operation.DuplicateBySoapAction.Method.name, operation.Method.action));
else
operation.SoapActionRequired = true;
}
else
operation.SoapActionRequired = false;
}
}
}
|