【学】SoapExtension 学习
SoapExtension.ChainStream 方法:
当在派生类中被重写时,允许 SOAP 扩展访问包含 SOAP 请求或响应的内存缓冲区。
命名空间:System.Web.Services.Protocols 程序集:System.Web.Services(在 system.web.services.dll 中)
ChainStream 确保具有最高优先级的 SOAP 扩展可以修改与通过网络发送或返回的 SOAP 消息最接近的实际数据。
SOAP 扩展应保存传入 ChainStream 的 Stream 和从 ChainStream 返回的 Stream 的引用。如果将 SOAP 扩展配置为与 XML Web services 方法一起运行,则传递到 ChainStream 中的 Stream 在 BeforeDeserializeSoapMessageStage 阶段包含已序列化的 SOAP 请求。同样,当发生序列化时,从 ChainStream 返回的 Stream 引用被写入,从而在 AfterSerializeSoapMessageStage 中包含已序列化的 SOAP 响应。
public override Stream ChainStream( Stream stream ){
oldStream = stream;
newStream = new MemoryStream();
return newStream;
}
SoapMessageStage 枚举:
| 成员名称 | 说明 | |
|---|---|---|
![]() |
AfterDeserialize | 恰好在将 SoapMessage 从 SOAP 消息反序列化到对象之后的阶段。
在 SoapClientMessage 处理过程中,AfterDeserialize 阶段发生在 SOAP 消息(包含来自 XML Web services 方法调用的响应)反序列化到对象之后,但在客户端接收到反序列化结果之前。 在 SoapServerMessage 处理过程中,AfterDeserialize 阶段出现在这种情形下:在包含 SOAP 消息的网络请求(表示已将 XML Web services 方法调用反序列化为对象)之后,对对象执行方法(表示 XML Web services 方法已调用)之前。 |
![]() |
AfterSerialize | 恰好在序列化 SoapMessage 之后,但在通过网络发送 SOAP 消息之前的阶段。
在 SoapClientMessage 处理过程中,AfterSerialize 阶段发生在客户端调用 XML Web services 方法并且参数序列化到 XML 之后,但在包含此 XML 的 SOAP 消息被通过网络发送之前。 在 SoapServerMessage 处理过程中,AfterSerialize 阶段发生在 XML Web services 方法返回并且所有返回值都序列化到 XML 之后,但在包含此 XML 的 SOAP 消息被通过网络发送之前。 |
![]() |
BeforeDeserialize | 恰好在将 SoapMessage 从通过网络发送的 SOAP 消息反序列化到对象之前的阶段。
在 SoapClientMessage 处理过程中,BeforeDeserialize 阶段发生在接收到来自 XML Web services 方法调用的网络响应之后,但在包含 SOAP 消息的响应反序列化到对象之前。 在 SoapServerMessage 处理过程中,BeforeDeserialize 阶段发生在 Web 服务器接收到网络请求(包含 XML Web services 方法调用的 SOAP 消息)之后,但在 SOAP 消息反序列化到对象之前。 |
![]() |
BeforeSerialize | 恰好在序列化 SoapMessage 之前的阶段。
在 SoapClientMessage 处理过程中,BeforeSerialize 阶段发生在客户端调用 XML Web services 方法之后,但在该调用被序列化之前。 在 SoapServerMessage 处理过程中,BeforeSerialize 阶段发生在对 XML Web services 方法的调用返回之后,但在将返回值序列化并通过网络发送回客户端之前。 |
// Process the SOAP message received and write to log file.
public override void ProcessMessage(SoapMessage message)
{
switch (message.Stage)
{
case SoapMessageStage.BeforeSerialize:
break;
case SoapMessageStage.AfterSerialize:
WriteOutput( message );
break;
case SoapMessageStage.BeforeDeserialize:
WriteInput( message );
break;
case SoapMessageStage.AfterDeserialize:
break;
default:
throw new Exception("invalid stage");
}
}
LogicalMethodInfo 类:
表示 XML Web services 方法的属性 (Attribute) 和元数据。无法继承此类。
LogicalMethodInfo 主要由 SOAP 扩展用来询问 SOAP 扩展被配置为与之一起运行的 XML Web services 方法的详细信息。根据 SOAP 扩展的配置情况,它可以找到有关采用 LogicalMethodInfo 的 SoapExtension 的 GetInitializer 方法中的 XML Web services 方法的详细信息。LogicalMethodInfo 通过使用 GetCustomAttributes 属性 (Property) 访问应用于 XML Web services 方法的 Parameters 属性 (Property) 和任何自定义属性 (Attribute) 来提供诸如 XML Web services 方法参数等详细信息。
// Process the SOAP message received and write to log file.
public override void ProcessMessage(SoapMessage message)
{
switch (message.Stage)
{
case SoapMessageStage.BeforeSerialize:
break;
case SoapMessageStage.AfterSerialize:
WriteOutput((SoapServerMessage)message);
break;
case SoapMessageStage.BeforeDeserialize:
WriteInput((SoapServerMessage)message);
break;
case SoapMessageStage.AfterDeserialize:
break;
default:
throw new Exception("invalid stage");
}
} // Write the contents of the incoming SOAP message to the log file.
public void WriteInput(SoapServerMessage message)
{
// Utility method to copy the contents of one stream to another.
Copy(oldStream, newStream);
FileStream myFileStream = new FileStream(filename, FileMode.Append, FileAccess.Write);
StreamWriter myStreamWriter = new StreamWriter(myFileStream);
myStreamWriter.WriteLine("================================== Request at "
+ DateTime.Now);
myStreamWriter.WriteLine("The method that has been invoked is : ");
myStreamWriter.WriteLine("\t" + message.MethodInfo.Name);
myStreamWriter.WriteLine("The contents of the SOAP envelope are : ");
myStreamWriter.Flush();
newStream.Position = ;
Copy(newStream, myFileStream);
myFileStream.Close();
newStream.Position = ;
} // Write the contents of the outgoing SOAP message to the log file.
public void WriteOutput(SoapServerMessage message)
{
newStream.Position = ;
FileStream myFileStream = new FileStream(filename, FileMode.Append, FileAccess.Write);
StreamWriter myStreamWriter = new StreamWriter(myFileStream);
myStreamWriter.WriteLine("---------------------------------- Response at "
+ DateTime.Now);
myStreamWriter.Flush();
// Utility method to copy the contents of one stream to another.
Copy(newStream, myFileStream);
myFileStream.Close();
newStream.Position = ;
Copy(newStream, oldStream);
}
SoapExtensionAttribute 类:
当在派生类中重写时,指定 SOAP 扩展应该与 XML Web services 方法一起运行。
使用 ASP.NET 创建的 XML Web services 方法可以配置为与 SOAP 扩展一起运行,方法是将一项属性应用于该 XML Web services 方法。将自定义扩展属性添加到 XML Web services 方法或客户端代理类中的方法后,ASP.NET 将在适当的时间调用关联的扩展。扩展属性是从 SoapExtensionAttribute 派生的自定义属性类。派生属性必须重写 ExtensionType 属性以返回与该属性关联的扩展的类型。
下面的 TraceExtensionAttribute 类从 SoapExtensionAttribute 派生,以支持将该属性应用于 XML Web services 方法或 XML Web services 客户端代理类中的方法。当应用于上述两种方法中的任意一个时,TraceExtension SOAP 扩展将与该方法一起运行。
// Create a SoapExtensionAttribute for a SOAP extension that can be
// applied to an XML Web service method.
[AttributeUsage(AttributeTargets.Method)]
public class TraceExtensionAttribute : SoapExtensionAttribute { private string myFilename;
private int myPriority; // Set the name of the log file were SOAP messages will be stored.
public TraceExtensionAttribute() : base()
{
myFilename = "C:\\logClient.txt";
} // Return the type of 'TraceExtension' class.
public override Type ExtensionType
{
get
{
return typeof(TraceExtension);
}
} // User can set priority of the 'SoapExtension'.
public override int Priority
{
get
{
return myPriority;
}
set
{
myPriority = value;
}
} public string Filename
{
get
{
return myFilename;
}
set
{
myFilename = value;
}
}
}
【摘】http://www.cnblogs.com/wobushixiaocai/archive/2008/04/11/1148196.html
1、SOAP扩展是在SoapMessage (SoapClientMessage和SoapServerMessage类型)传输过程中对其SOAP消息处理过程的拦截器,其可以在SoapMessage的四个阶段进行拦截并且插入代码,这四个阶段分别是BeforeSerialize"AfterSerialize"BeforeDeserialize和AfterDeserialize。
2、 在整个WebService访问过程中,ChainStream一共执行四次,在客户端执行两次,在服务器端执行两次。ChainStream的调用是按照Soap扩展的高优先级到低优先级的调用顺序依次调用的。
3、 每次SoapMessage的Stage状态发生改变时都会调用SoapExtension的ProcessMessage。所以这个函数一共执行8次。其中需要特别注意的是,不同优先级的Soap扩展在Soap消息传输的不同阶段其调用顺序是不一样的,具体可以分为两个阶段:即Serialize阶段,其调用是按照Soap扩展的优先级从低到高执行的,在Deserialize阶段,其调用是按照Soap扩展优先级从高到低执行的。
项目实践:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services.Protocols;
using System.IO;
using System.Xml;
using BillingWS.Common; namespace BillingWS.BusinessLogic
{
public class TraceExtension : SoapExtension
{
private Stream oldStream;
private Stream newStream; private string category;
private string methodName; private XmlDocument xmlRequest;
/// <summary>
/// Gets the outgoing XML request sent to PayPal
/// </summary>
private XmlDocument XmlRequest
{
get { return xmlRequest; }
} private XmlDocument xmlResponse;
/// <summary>
/// Gets the incoming XML response sent from PayPal
/// </summary>
private XmlDocument XmlResponse
{
get { return xmlResponse; }
} /// <summary>
/// Save the Stream representing the SOAP request
/// or SOAP response into a local memory buffer.
/// </summary>
/// <param name="stream"></param>
/// <returns></returns>
public override Stream ChainStream(Stream stream)
{
oldStream = stream;
newStream = new MemoryStream();
return newStream;
} public override object GetInitializer(Type serviceType)
{
return null;
} public override object GetInitializer(LogicalMethodInfo methodInfo, SoapExtensionAttribute attribute)
{
return null;
} public override void Initialize(object initializer)
{ } public override void ProcessMessage(SoapMessage message)
{
try
{
string serviceName = message.MethodInfo.DeclaringType.Name;
category = Common.PublicEnums.WSCallSource.Zuora.ToString(); switch (message.Stage)
{
case SoapMessageStage.BeforeSerialize:
break; case SoapMessageStage.AfterSerialize:
xmlRequest = GetSoapEnvelope(newStream);
CopyStream(newStream, oldStream);
break; case SoapMessageStage.BeforeDeserialize:
CopyStream(oldStream, newStream);
xmlResponse = GetSoapEnvelope(newStream); if (serviceName.IndexOf("ZuoraService") != -)
{
methodName = message.MethodInfo.Name;
LogMessage();
}
break; case SoapMessageStage.AfterDeserialize:
break;
} }
catch (Exception ex)
{
ZuoraException exception = new ZuoraException(PublicEnums.ExceptionType.LogTraceFailed, "ProcessMessage Failed:" + ex.Message, ex);
exception.Log();
}
} #region Method
public void LogMessage()
{
try
{
HttpContext content = HttpContext.Current;
if (content != null && content.Session != null)
{
if (content.Session[PublicConstants.SESSION_TRANSACTIONLOGID] != null)
{
Guid transactionId = new Guid(content.Session[PublicConstants.SESSION_TRANSACTIONLOGID].ToString()); TransactionConverter converter = new TransactionConverter(transactionId, category, methodName, xmlRequest, xmlResponse);
converter.LogDB();
}
}
}
catch (Exception ex)
{
ZuoraException exception = new ZuoraException(PublicEnums.ExceptionType.LogTraceFailed, "LogMessage Failed:" + ex.Message, ex);
exception.Log();
}
}
private XmlDocument GetSoapEnvelope(Stream stream)
{
XmlDocument xml = new XmlDocument();
try
{
stream.Position = ;
StreamReader reader = new StreamReader(stream);
xml.LoadXml(reader.ReadToEnd());
stream.Position = ;
}
catch (Exception ex)
{
ZuoraException exception = new ZuoraException(PublicEnums.ExceptionType.LogTraceFailed, "GetSoapEnvelope Failed:" + ex.Message, ex);
exception.Log();
}
return xml;
} /// <summary>
/// Copies a stream.
/// </summary>
/// <param name="from"></param>
/// <param name="to"></param>
private void CopyStream(Stream from, Stream to)
{
try
{
TextReader reader = new StreamReader(from);
TextWriter writer = new StreamWriter(to);
writer.WriteLine(reader.ReadToEnd());
writer.Flush();
}
catch (Exception ex)
{
ZuoraException exception = new ZuoraException(PublicEnums.ExceptionType.LogTraceFailed, "CopyStream Failed:" + ex.Message, ex);
exception.Log();
}
}
#endregion
}
}
【学】SoapExtension 学习的更多相关文章
- 从零开始学深度学习mxnet教程:安装以及基本操作
一.导言 本教程适合对人工智能有一定的了解的同学,特别是对实际使⽤深度学习感兴趣的⼤学⽣.⼯程师和研究⼈员.但本教程并不要求你有任何深度学习或者机器学习的背景知识,我们将从头开始解释每⼀个概念.虽然深 ...
- 对比《动手学深度学习》 PDF代码+《神经网络与深度学习 》PDF
随着AlphaGo与李世石大战的落幕,人工智能成为话题焦点.AlphaGo背后的工作原理"深度学习"也跳入大众的视野.什么是深度学习,什么是神经网络,为何一段程序在精密的围棋大赛中 ...
- 【动手学深度学习】Jupyter notebook中 import mxnet出错
问题描述 打开d2l-zh目录,使用jupyter notebook打开文件运行,import mxnet 出现无法导入mxnet模块的问题, 但是命令行运行是可以导入mxnet模块的. 原因: 激活 ...
- 小白学习之pytorch框架(2)-动手学深度学习(begin-random.shuffle()、torch.index_select()、nn.Module、nn.Sequential())
在这向大家推荐一本书-花书-动手学深度学习pytorch版,原书用的深度学习框架是MXNet,这个框架经过Gluon重新再封装,使用风格非常接近pytorch,但是由于pytorch越来越火,个人又比 ...
- python之感知器-从零开始学深度学习
感知器-从零开始学深度学习 未来将是人工智能和大数据的时代,是各行各业使用人工智能在云上处理大数据的时代,深度学习将是新时代的一大利器,在此我将从零开始记录深度学习的学习历程. 我希望在学习过程中做到 ...
- 学java得这样学,学习确实也得这样
引言 软件开发之路是充满荆棘与挑战之路,也是充满希望之路.Java学习也是如此,没有捷径可走.梦想像<天龙八部>中虚竹一样被无崖子醍醐灌顶而轻松获得一甲子功力,是很不现实的.每天仰天大叫& ...
- 《linux就该这么学》学习笔记
本篇文章是根据刘遄老师的<linux就该这么学>中个人易忘知识点的读书笔记,结合的是个人弱点,可能不适合广大的网友同学,并在此声明本篇文章只是用于学习之用,绝无侵犯版权之意 linux就该 ...
- 8年开发老司机告诉你啥是java开发?如何学?学习什么内容?
什么是Java? 我从Java的官网上抄下来下面这段话:97% 的企业桌面运行 Java美国有 89% 的桌面(或计算机)运行 Java全球有 900 万 Java 开发人员开发人员的头号选择排名第一 ...
- [跟我学spring学习笔记][更多DI知识]
延迟初始化Bean 定义: 延迟初始化也叫做惰性初始化,指不提前初始化Bean,在真正使用时才创建并初始化Bean 如何延迟: 配置方式很简单只需在标签上指定 “lazy-init” 属性值为“tru ...
随机推荐
- SQL SERVER--单回话下的死锁
很多时候,死锁由两个或多个会话请求其他Session持有的锁而同时又持有其他Session,但也有一些特殊的死锁仅由单个Session锁触发,今天看到一篇相关的文章,搬运过来与各位共享! 引发死锁的代 ...
- 04-Vue入门系列之Vue事件处理
4.1. 监听事件的Vue处理 Vue提供了协助我们为标签绑定时间的方法,当然我们可以直接用dom原生的方式去绑定事件.Vue提供的指令进行绑定也是非常方便,而且能让ViewModel更简洁,逻辑更彻 ...
- Nginx学习笔记(六) 源码分析&启动过程
Nginx的启动过程 主要介绍Nginx的启动过程,可以在/core/nginx.c中找到Nginx的主函数main(),那么就从这里开始分析Nginx的启动过程. 涉及到的基本函数 源码: /* * ...
- [51单片机] SPI nRF24L01无线 [可以放在2个单片机里实现通信]
main.c #include<reg51.h> #include"2401.h" #define uint unsigned int #define uchar un ...
- [ucgui] 彩色条函数
/* 颜色条 */ void ShowColorBar(void) { , y0 = , yStep = , i; int NumColors = LCD_GetDevCap(LCD_DEVCAP_N ...
- webview长按事件js监听
做app开发时,用到了webview,需要监听webview的长按事件,使用原生的js处理监听如下: ; //定时器 //开始按 function gtouchstart() { timeOutEve ...
- iOS开发中使用CocoaPods来管理第三方的依赖程序
之前也碰到类似的问题,怎样去管理这些第三方的文件,虽然手动添加也不算麻烦. 写这篇文章主要参考了唐巧的博文,链接如下: http://blog.devtang.com/blog/2012/12/02/ ...
- linux平台下防火墙iptables原理(转)
原文地址:http://www.cnblogs.com/ggjucheng/archive/2012/08/19/2646466.html iptables简介 netfilter/iptables( ...
- Java性能提示(全)
http://www.onjava.com/pub/a/onjava/2001/05/30/optimization.htmlComparing the performance of LinkedLi ...
- 2013年的一些常用PHP資源整理下載
這些資源基本上都是一些免積分或只需要1個積分就能下載的資源,經過整理篩選最後分享給大家,希望大家喜歡: PHP手册(chm) http://download.csdn.net/detail/u0118 ...
