承上篇,進一步利用 SoapExtension 在不修改 WSDL 前提下,穿透傳輸自訂資料物件。採用 ContentType 附加標記 ExtInfo=true,於訊息流中夾帶自訂二進位資料(長度前綴 + BE 標記 + 序列化物件)。
public class StreamWSInvokeMonitorExtension : SoapExtension {
private const string WSInvokeMonitorKey = "__WSInvokeMonitorKey__";
private const int MaxDataLength = 5 * 1024 * 1024;
private XmlSerializer serializer = new XmlSerializer(typeof(DbConnInfo));
private Stream originStream, usingStream = new MemoryStream();
private WSInvokeInfo invokeInfo = new WSInvokeInfo();
public override Stream ChainStream(Stream stream) { originStream = stream; return usingStream; }
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) {
if (message is SoapClientMessage) { /* 客戶端發送/接收邏輯 */ }
else if (message is SoapServerMessage) { /* 伺服器端接收/回應邏輯 */ }
}
// 客戶端 BeforeSerialize 記錄開始時間、方法名
// AfterSerialize 將 usingStream 複製回 originStream
// BeforeDeserialize 檢查 ContentType 標記,解析自訂資料
// AfterDeserialize 記錄結束時間,寫入 HttpModule Items
// 伺服器端 BeforeSerialize 序列化自訂物件寫入流,附加 ContentType 標記
// AfterSerialize 複製流回 originStream
private void CopyStream(Stream src, Stream des) { /* 1KB 緩衝複製 */ }
}
[Serializable] public class DbConnInfo { public string Info { get; set; } public DbConnInfo() {} public DbConnInfo(string info) { Info = info; } }
此模式實現無侵入式跨服務邊界傳遞診斷資訊,配合 HttpModule 收集完整請求鏈路數據。