From c8f2e8e2b5acfa48839749ef06a9430403d9c83c Mon Sep 17 00:00:00 2001 From: reuben-geonet Date: Thu, 7 May 2026 13:34:38 +1200 Subject: [PATCH 1/3] feat: add save button --- BinaryMessageFiddlerExtension/XmlTreeView.cs | 53 ++++++++++++++++++++ README.md | 1 + 2 files changed, 54 insertions(+) diff --git a/BinaryMessageFiddlerExtension/XmlTreeView.cs b/BinaryMessageFiddlerExtension/XmlTreeView.cs index ab1ff02..a034085 100644 --- a/BinaryMessageFiddlerExtension/XmlTreeView.cs +++ b/BinaryMessageFiddlerExtension/XmlTreeView.cs @@ -7,6 +7,7 @@ using System.Text; using System.Windows.Forms; using System.Xml; +using System.IO; namespace BinaryMessageFiddlerExtension { @@ -38,10 +39,12 @@ private void BuildContextMenu() // NodeMouseClick doesn't fire for middle click, so emulate that using mouseup/mousedown TreeView.MouseUp += new MouseEventHandler(TreeView_MouseUp); TreeView.MouseDown += new MouseEventHandler(TreeView_MouseDown); + TreeView.KeyDown += new KeyEventHandler(TreeView_KeyDown); TreeView.ContextMenu.MenuItems.Add(new MenuItem("Expand All", ExpandAll_Click, Shortcut.AltRightArrow)); TreeView.ContextMenu.MenuItems.Add(new MenuItem("Collapse All", CollapseAll_Click, Shortcut.AltLeftArrow)); TreeView.ContextMenu.MenuItems.Add(new MenuItem("Copy", CopyMenuItem_Click, Shortcut.CtrlC)); TreeView.ContextMenu.MenuItems.Add(new MenuItem("Copy Tree", CopyTreeMenuItem_Click, Shortcut.CtrlShiftC)); + TreeView.ContextMenu.MenuItems.Add(new MenuItem("Save Tree...", SaveTreeMenuItem_Click, Shortcut.CtrlS)); } public void LoadXml(XmlDocument doc) @@ -207,6 +210,41 @@ private void CopySubtreeContentToClipboard() System.Windows.Forms.Clipboard.SetText(subtreeContent); } + private void SaveSubtreeContentToFile() + { + if (TreeView.SelectedNode == null) + return; + + String subtreeContent = GenerateSubtreeString(TreeView.SelectedNode); + if (subtreeContent == null) + return; + + using (SaveFileDialog saveFileDialog = new SaveFileDialog()) + { + saveFileDialog.AddExtension = true; + saveFileDialog.DefaultExt = "xml"; + saveFileDialog.Filter = "XML Files (*.xml)|*.xml|All Files (*.*)|*.*"; + saveFileDialog.OverwritePrompt = true; + saveFileDialog.Title = "Save decoded WCF XML"; + + if (saveFileDialog.ShowDialog(this) != DialogResult.OK) + return; + + try + { + File.WriteAllText(saveFileDialog.FileName, subtreeContent, Encoding.UTF8); + } + catch (Exception ex) + { + MessageBox.Show(this, + "Unable to save decoded XML: " + ex.Message, + "Save decoded WCF XML", + MessageBoxButtons.OK, + MessageBoxIcon.Error); + } + } + } + private string GenerateSubtreeString(TreeNode treeNode) { XmlNode xml = treeNode.Tag as XmlNode; @@ -264,6 +302,16 @@ private void TreeView_MouseUp(object sender, MouseEventArgs e) } } + private void TreeView_KeyDown(object sender, KeyEventArgs e) + { + if (e.Control && !e.Shift && e.KeyCode == Keys.S) + { + SaveSubtreeContentToFile(); + e.SuppressKeyPress = true; + e.Handled = true; + } + } + private void CopyMenuItem_Click(Object sender, System.EventArgs e) { CopySelectedNodeContentToClipboard(); @@ -274,6 +322,11 @@ private void CopyTreeMenuItem_Click(Object sender, System.EventArgs e) CopySubtreeContentToClipboard(); } + private void SaveTreeMenuItem_Click(Object sender, System.EventArgs e) + { + SaveSubtreeContentToFile(); + } + private void ExpandAll_Click(Object sender, System.EventArgs e) { ExpandAllSelectedNode(); diff --git a/README.md b/README.md index 34c4bf7..8db44f5 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,7 @@ The tree view provides the following shortcuts: * Ctrl+c — Copy current node XML * Ctrl+Shift+c — Copy tree XML +* Ctrl+s — Save tree XML to a file * Alt+→ — Expand node and all child nodes * Alt+← — Collapse node and all child nodes * Middle-click — Toggle expand/collapse of node and all child nodes From b637dad7ee1ffe0028254a682542d903743fa057 Mon Sep 17 00:00:00 2001 From: reuben-geonet Date: Thu, 7 May 2026 13:56:49 +1200 Subject: [PATCH 2/3] feat: add default file name to save --- .../BinaryRequestInspector.cs | 11 +++++++++++ .../BinaryResponseInspector.cs | 11 +++++++++++ BinaryMessageFiddlerExtension/XmlTreeView.cs | 3 +++ 3 files changed, 25 insertions(+) diff --git a/BinaryMessageFiddlerExtension/BinaryRequestInspector.cs b/BinaryMessageFiddlerExtension/BinaryRequestInspector.cs index 06c1bd0..3f72a3a 100644 --- a/BinaryMessageFiddlerExtension/BinaryRequestInspector.cs +++ b/BinaryMessageFiddlerExtension/BinaryRequestInspector.cs @@ -102,6 +102,14 @@ public override int GetOrder() return 1; } + public override void AssignSession(Session oS) + { + if (viewControl != null && oS != null) + viewControl.DefaultSaveFileName = String.Format("request{0}.xml", oS.id); + + base.AssignSession(oS); + } + public bool bDirty { get; set; } public bool bReadOnly @@ -130,6 +138,9 @@ public byte[] body { // when fiddler updates this inspector's content, our controls' content binaryContent = value; + if (viewControl != null && String.IsNullOrEmpty(viewControl.DefaultSaveFileName)) + viewControl.DefaultSaveFileName = "request.xml"; + UpdateControlContent(); } } diff --git a/BinaryMessageFiddlerExtension/BinaryResponseInspector.cs b/BinaryMessageFiddlerExtension/BinaryResponseInspector.cs index db2dfc8..65207fe 100644 --- a/BinaryMessageFiddlerExtension/BinaryResponseInspector.cs +++ b/BinaryMessageFiddlerExtension/BinaryResponseInspector.cs @@ -57,6 +57,14 @@ public override int GetOrder() return 1; } + public override void AssignSession(Session oS) + { + if (viewControl != null && oS != null) + viewControl.DefaultSaveFileName = String.Format("response{0}.xml", oS.id); + + base.AssignSession(oS); + } + public bool bDirty { get { return false; } @@ -80,6 +88,9 @@ public byte[] body { // when fiddler updates this inspector's content, our control's content binaryContent = value; + if (viewControl != null && String.IsNullOrEmpty(viewControl.DefaultSaveFileName)) + viewControl.DefaultSaveFileName = "response.xml"; + UpdateControlContent(); } } diff --git a/BinaryMessageFiddlerExtension/XmlTreeView.cs b/BinaryMessageFiddlerExtension/XmlTreeView.cs index a034085..bb2ff86 100644 --- a/BinaryMessageFiddlerExtension/XmlTreeView.cs +++ b/BinaryMessageFiddlerExtension/XmlTreeView.cs @@ -18,6 +18,8 @@ public partial class XmlTreeView : UserControl // if the message body has fewer than this number of nodes, expand the entire body subtree. private const int AutoExpandAllThreshold = 50; //entirely arbitrary. + public string DefaultSaveFileName { get; set; } + public TreeView TreeView { get @@ -223,6 +225,7 @@ private void SaveSubtreeContentToFile() { saveFileDialog.AddExtension = true; saveFileDialog.DefaultExt = "xml"; + saveFileDialog.FileName = String.IsNullOrEmpty(DefaultSaveFileName) ? "decoded-wcf.xml" : DefaultSaveFileName; saveFileDialog.Filter = "XML Files (*.xml)|*.xml|All Files (*.*)|*.*"; saveFileDialog.OverwritePrompt = true; saveFileDialog.Title = "Save decoded WCF XML"; From 289807b1c32fb862e55bebe5ffb334301c0c8294 Mon Sep 17 00:00:00 2001 From: reuben-geonet Date: Thu, 7 May 2026 14:00:22 +1200 Subject: [PATCH 3/3] feat: rebuild dll --- .../Release/BinaryMessageFiddlerExtension.dll | Bin 44032 -> 46080 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/BinaryMessageFiddlerExtension/bin/Release/BinaryMessageFiddlerExtension.dll b/BinaryMessageFiddlerExtension/bin/Release/BinaryMessageFiddlerExtension.dll index 17254ad4ac1fc1851f9abb9afb2194dffc708157..2a66f8b7b45856fc31ed6806e362b34012954952 100644 GIT binary patch delta 14282 zcmb`Od3+RAw#Uz{?ylaOq(c^#kU$7DNk9@rK>-sWNMtueKxGM}g-DWu?nFSu?$)P> zBWUaaA2Z+xxS^n;gN!~$%!~_u#C;odM1A4{I-`s@BjZ!v@7}7U4(glv=QZ}J?^*7- z_uQ(wRb3U6f6|hlX}8?a@A5CcYb5LQ0re~Ni=jmK!Qe5Ce?8EC-$kJ<2Z*Lg!v{op z&i20D{el8e8=fQTovzQw^h+Oe^d0t+*`%zSigMOGwNMxAPS5ZOzd!i!LEW@mtCB~-wo0>~}IVBZlGeedxD@4I&g%Yfk zs8Hrp6^`sGQFYO5mzX6pbXMh+X@*3KU`t~1oS4q^Ew21tLr`+$3<$qFpt}tmZ@$Am zPnqs9%F_p21M4c3D>4k5faWpI#MWbA9)0ed%Z;<-);Jq7%Nce?MgSrsA%foZ<1qt1 zx1QrQ&VgZo+c+1S!#;NzIw?<&*NYR_>%QXHS~=d)GNd?m7vp`5-NKHU!FWF7X2x;G zYZ$jPzAM2Lhh}%+XI#K|7~_$Qr!n5fcpu{z7=LVWLRS1ea|9jsAo3YcVZ4IzwTy3O z{2*hO)6RJV<42v8=$iHe%yEQqiOX)hiSgZxC+T*~&5S=}EZlZXu!|GLvA$hOaqMiy zQO4IX-obc3<98W<&p69tcU;Q&HOUFlm+RyqWPn#vP1bWc)Vck4;XfQ|?RVILX)%um_RJIG^!g#x;!V7|&u{ z&vx@VCwiDgV_)Ess z`F6}s#@{in>0`%iW_+{{TmR25u!D9m&Mma<>llB|_#4J28T59P?61lV!X4zZJ$?cbFTq5KOwnu{eOiydJnXN9%1|*V|T=k8OXSl z@hrwm8D|W#+a~rf<>C_C@fXI)Qrq6G%;qA-a~U@?-pY6n;}=af*Z)tM!!_9MAeV79 z<2uG`7;j{}pYhv_KV>Y2u=RiO5WC}-8Nbc=j5F+*-HZnhwe33?7nIxfI~n(^udkTNrzW*^P4;pUHSSKgsx8#{CoL+8s<~d^O`c7(c=IpNxH@>^yxKpUHRv;}(n6`k!Qu zUopOy@#Bo&VEk9cfzkFLdNMwX@db?Mjb`irO6ItR@g~N1Gk%Hj4~+Ydu?KNA<98VU zvx~9*XPjp@=+Afp<1LKuW&AkfgN$cY+BugpKE(Jv$(`%}_snrgmEE|Raf0zy#(NmQ z!1!avM;V_x*3O?;&y=lfxjK5Gk%Wo>x|!L{1M|*oh;Y?;`8ke zY8dZl{66EViFW)H#s=ed#-B4j$#`%LTmP3s>0JLeGv3Ge5MyzH9iPQ`IO9tgw=;gu z=0xnGNp_-d7}rm>?e8%jH^sIm81H9%i1A6r`BUw-!xUTV{|x46WBdZ+HyKw=vlH!R z+-tgRFJ(NM@ifMB6HGA}U&}bncpGEa47;;t#&0toeW4w*gR#HXw5#<$ZYlEq|82%2 zXWEV181G?xh_R@%!#*-K??qaO} zJGzwO*z=6vWqh1*^DMiwKC^9J$@o^r_c8u0<9>6{wsZZjkc#yzXanQB8UL1X_lxcL z3dY+Rhc2;W7Baq*abg!!9%cL#<5w8J!}tVay43EhH{-mp-{V)cPLgb_VpnNXh4=*zmz|c(^uGHe^ zAz%&Oy*RZ+ls0Bqzl$kp4*! z1I%Ht2K~(jIM1vG#fg8@VvN}WuM?~m? z`Yw?^r-3y9FXv_hq;W1pu(Zr;%mcKdDv^cvT{3U%QMAuA6JR3;V$6pa;58OtGx*@) z?%p;`w8(O0y2{*{E~6agKRb;+GO|F1WLlXHB9qy@G~gJFz1C&Hn?~82(O0&TrIlW4 zcIG!XWrM7~>)|UrfwIeU-8l-3g)qh5LMm0DA1}F7f?j&;FpOrq*k{tes53i;S1Gvx zB3RnXsvGCD$kH|4h{BwytG#QL`QA^VF(jEI!;7zyrVUu2VmZhjA&ECc8aA0x9Qh5?vhN&{; zTg+QF@aMDS7;ApiN)FaR5sbs#wR@b#)rfK$vIipxfq@6igu0P}j=?)9fyGXJoW?b< z6%tj_u<>TtPcpEv4Z-ok>be$f%dl&QV`svF7u|ZvlTPD5q#0|~b=VH><20_vwxD)c zcP)Z9e|9bnkNJevZ1 z&$-s8(+f&AIqH1f=v_3?>6eZpZk?)}Qub5wVI{A29!bD-n^NvqK}p9Fq?o6q3w9rU z;i&ZL^sHmJ%SWTB((9w)N@hZaC=jak`)H(B#*A~U^@S*3tM!Md(p`(UY^lHwJxmvR zcIZ0I2rNclL;Q=8^I^Bl^QOPjoA6Ozm97Iy4mE^!=sD!}$_5kNS5Xe#3Jy_!q|>RF zcW$sJUGA-i<<+3cS2fzfJLW|y-D!<4#}0;Vt0ss?~)nnJd%6+Wqc{5 zFF}`~`#yBg`+zG%YcTdjRESkSgu50Q^eBRKn(JNc4pVkert_1mBkfx3&Y^RCa=42y z=rA2qRZhjA!_;OLpdybtW#siPInccrbciN;rMy_l#1k+L6cwt=d8&@SsxmLqh3O5* z5M7JPLezl@LUd5c)_~-95UEp{Yi>}d7VRnwT3~mC=nhq1i^`T(JVeE3!P1A01Rikp zpZrpfoqClZV?L?*?}>4#+}i8T3+cgL@-p zrWo4T&@4^RDEGyXL*4Tr-wG_$GU)@?WndDvSK1S%BZpRoE{A)i%g|;d2Z~nkyY#RS zlpR0$}0cV!q z(ssF5Kszs?)K9#Rh7!U>=PT`cPe&*lC*^d@Hvm4JW?R~s@aeSJ)Wi{wj#F{HC;YcVd%YjlHeB2CPT}Zl>W zjq-4pfrbE zDS8NJNGAQ~XqAN?&|gO6F{veRWAU0d14p%UjOmnnG>giVmZC@XH?=IP?9%?Mb*E*O zGBQOsg>)=XUs>8@93wf@RAu@MrQK<17i-e@%dw_!n(GrShkmEDM2cQSXfAoina+=t zR%vM~J%7=1snyc{2(1UbW@)#1zR`M-Hr{Mkt*_Pc$!BRppcPQq(sH5orJk1djcct| zMEy)HK`uCpsYIzyQ;s7Wm!Qd3=q8*_@{UE&UMx_82H}=eqn@~43Cx?6y5gToGyeaI zDc5A%^#RO(XNr4Ny7$om&Uxi_U`f&}b}9?+{{M*+r`2>Peqq+2(|bxst1tOewhsQl~@*#ex~MO)L!b zqz-!8TL3v*9{@SRKbRg9dubSLQ=uK=BP|>Juzw`IDo%MT5mOkL0C`{FLPW{~w?>@s z&7(u&SfBy?g}#Iik>OfGJ1OeQpmm}c=g;$IHfjulvHt5Bbd=tp20AJ(2rQ>{Y8mNJ z>5htfLu+7>Bi#v^O~=I-!S$3WPI%Ht^bqZ!RU*fMxxs*R>MIi7edzdJ&r|s6a>Rv2 zO{?}i2YJkOka}oxC?AS}j#ps0pWcK_s36tYi(22qcx9q;Wf`Poxh5?gbVu+AjRecO z_jx{tyd1L1vi!pHH&|{7o}?PB+JB1X!0r+=w7rxeYDAvM6;IdepRS0x%8*Qz1^$GHTvGCD9x%n@=om5XDp2FQSGhLH9-qFhvq`G^eq zFB8kP?V zH$zs5VS#^O>Yfm%M7x;p(X~0^F`TuV#YtVt*#Rlni-5Knf1{mEo5ca#vL4dpI#Q*E z)j=g#e0Pe!I>XwB*eQ8h2R-iY19=MulsIacvRuV5od^m#4ojJKNL%8sfZQxb!af2O zcxWhHs13n&tCwR4mgxSFy>Qbxgo2v z3p}8bzuD=T5dP|wMkv`gBpgKF`gO>kvnTv;;A#Zr8zl4L}p703FOgC_EEM0=~AvN5bWq}7kYFOg4$(h7j ztL{HAX7jTFzbc%a3bvKn?MlNUPx;fn#Ck11m9oem#hLeyr?=gq|1|D7`MZU+#V-&%gNUxrVLt{P`F zMAL;8e<+mkwQUPqW6|h1qop<4(mKFVJ(7Iltwd}DnRo>Gl7nwyOlOQ~IAtN^B89)5O)jGKu8PKma( z)wD*N)2D{N=94|k5yy=5%V#Yum=cZ0>la7I8Y^oS87->+s)mN@m8dA*XtbmQ=k)PW zRXpCfxTQ84PuHIPR$hHWgPe--#)=k_=`U)Gu8@Xw{}KBfa{JPV8n>JVRQpKQ$g71i zu01E_vpY*4Kj)%y8B^P~Y*`FrK)dO3ON)%=Wkw6;GfuLj$ws_&g0ZMAPBQbna|aHT z1=KESysQFQB~JhNm#RZ~;Can!7gnpur4!zv&e@R$k{ntpOruD5IK>DNcy?x~4S zZEI?p7E3Q5ou6(WotubJl$KK)WSm;DNDReo!4O(W%~%8|_jGTUy+GRIw2TbG)PsN2 zuE&r4T`lvQ(UFg;*}fp}RsdyQYz{vU*ymx-Uef27EXstlECu+H7?WVkoQCs{0}g zK8n)t{3&;~+!N`Ht>L-P<}GrZzuET#=y28nm-N*&bcX>SFwJgOpeoj~KwA=S@tm2WSK?(HdbNOSMr zP&7I`s$TVQmm248bgTBsZdpPqs$?TFU}wr*X1X&| z%Vkt%s!iGg0aICJZq}rWelsL-ol{3Wn(mR?tx{}LJ9DlscYJucvyk##(vt52hF2-) zDqN;^owD!|MZHN)=mB563e6O#f1=4SU0RD*7k&s*CU z9TC!;5%dXx-XM}G*g}f7J@Vymo)J?!|L-{sSH#|eDES<|JBco=9bfz9juT(+ntjjs z-#u|#X7;2pFTzdZ&bhQM9*xB>UD4PQy>vX*+h(}}U%I%lbxGU8^q1Q{2|s-Ran|Rs n(} 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 Cfe(NH