168 lines
7.3 KiB
C#
168 lines
7.3 KiB
C#
//------------------------------------------------------------------------------
|
|
// <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;
|
|
}
|
|
}
|
|
}
|