实现要求的一种方法是使用 Soap Extensions -
我正在获取以下网站的代码并尝试相应地解释 -
https://expertsys.hu/2017/10/11/renaming-asmx-webmethod-parameter-preserving-compatibility/
- 创建 Soap 扩展类。
- 整个处理过程发生在 processmessage 调用中。如果您看到名为 beforeSerialize 的“updateMessage”方法,则此方法会解析并提取带有输入的 XML节点“inp1”并根据您的要求用拆分运算符替换该值。如果需要,您可以进一步更改!
- “ParameterValueChangedSoapExtensionAttribute”类有助于指定 Soap 扩展类。
- 所有其他方法都是帮助类来实现需求。
public class ParameterValueChangedSoapExtension : SoapExtension
{
private Stream streamChainedAfterUs = null;
private Stream streamChainedBeforeUs = null;
private const int STREAMBUFFERSIZE = 65535;
private ParameterValueChangedSoapExtensionAttribute ParameterValueChangedSoapExtensionAttribute = null;
public override Stream ChainStream(Stream stream)
{
if (stream == null)
{
throw new ArgumentNullException("stream");
}
Stream ret = null;
this.streamChainedBeforeUs = stream;
this.streamChainedAfterUs = new MemoryStream();
ret = this.streamChainedAfterUs;
return ret;
}
public override object GetInitializer(Type serviceType)
{
throw new NotSupportedException();
}
public override object GetInitializer(LogicalMethodInfo methodInfo, SoapExtensionAttribute attribute)
{
if (attribute == null)
{
throw new ArgumentNullException("attribute");
}
object ret = attribute;
return ret;
}
public override void Initialize(object initializer)
{
if (initializer == null)
{
throw new ArgumentNullException("initializer");
}
ParameterValueChangedSoapExtensionAttribute = initializer as ParameterValueChangedSoapExtensionAttribute;
if (ParameterValueChangedSoapExtensionAttribute == null)
{
throw new InvalidOperationException(String.Format("initializer must be of type {0}, but its a {1}!", typeof(ParameterValueChangedSoapExtensionAttribute), initializer.GetType()));
}
}
public override void ProcessMessage(SoapMessage message)
{
if (message == null)
{
throw new ArgumentNullException("message");
}
switch(message.Stage)
{
case SoapMessageStage.BeforeSerialize:
break;
case SoapMessageStage.AfterSerialize:
streamChainedAfterUs.Position = 0;
Copy(streamChainedAfterUs, streamChainedBeforeUs);
break;
case SoapMessageStage.BeforeDeserialize:
UpdateMessage(message);
streamChainedAfterUs.Position = 0;
break;
case SoapMessageStage.AfterDeserialize:
break;
default:
throw new NotImplementedException(message.Stage.ToString());
}
}
private void UpdateMessage(SoapMessage message)
{
var soapMsgAsString = ReadOriginalSoapMessage();
var soapMsgRootNode = XElement.Parse(soapMsgAsString);
var callDescriptorNode = FindCallDescriptorNode(soapMsgRootNode, message.MethodInfo.Name);
var ns = callDescriptorNode.Name.Namespace;
var originalNameWeLookFor = ns + ParameterValueChangedSoapExtensionAttribute.OriginalParameterName;
var nodeWithOriginalName = callDescriptorNode.Elements().FirstOrDefault(i => i.Name == originalNameWeLookFor);
if (nodeWithOriginalName != null)
{
//Here implement according to your need!
nodeWithOriginalName.Value = nodeWithOriginalName.split(' ')[0];
var nodeWithCurrentName = new XElement(ns + ParameterValueChangedSoapExtensionAttribute.CurrentParameterName, nodeWithOriginalName.Value);
nodeWithOriginalName.AddAfterSelf(nodeWithCurrentName);
nodeWithOriginalName.Remove();
}
WriteResultSoapMessage(soapMsgRootNode.ToString());
}
private XElement FindCallDescriptorNode(XElement soapMsgRootNode, string methodName)
{
XElement ret = null;
var soapBodyName = soapMsgRootNode.Name.Namespace + "Body";
var soapBodyNode = soapMsgRootNode.Elements().First(i => i.Name == soapBodyName);
ret = soapBodyNode.Elements().First(i => i.Name.LocalName == methodName);
return ret;
}
private void WriteResultSoapMessage(string msg)
{
streamChainedAfterUs.Position = 0;
using (var sw = new StreamWriter(streamChainedAfterUs, Encoding.UTF8, STREAMBUFFERSIZE, true))
{
sw.Write(msg);
}
}
private string ReadOriginalSoapMessage()
{
string ret = null;
using (var sr = new StreamReader(streamChainedBeforeUs, Encoding.UTF8, false, STREAMBUFFERSIZE, true))
{
ret = sr.ReadToEnd();
}
return ret;
}
private void Copy(Stream from, Stream to)
{
using (var sr = new StreamReader(from, Encoding.UTF8, false, STREAMBUFFERSIZE, true))
{
using (var sw = new StreamWriter(to, Encoding.UTF8, STREAMBUFFERSIZE, true))
{
var content = sr.ReadToEnd();
sw.Write(content);
}
}
}
}
[AttributeUsage(AttributeTargets.Method, AllowMultiple=true)]
public class ParameterValueChangedSoapExtensionAttribute : SoapExtensionAttribute
{
public override Type ExtensionType
{
get { return typeof(ParameterNameChangedSoapExtension); }
}
public override int Priority { get; set; }
public string CurrentParameterName { get; private set; }
public string OriginalParameterName { get; private set; }
public ParameterValueChangedSoapExtensionAttribute()
{
this.CurrentParameterName = "inp1";
this.OriginalParameterName = "inp1";
}
}
请通过以下链接了解有关 SOAP 扩展的更多信息 -
Soap Extensions
SoapExtensionAttribute