From 8777c0b816545276e0eae812689a769d08cabe9f Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Thu, 25 Jun 2026 20:37:38 -0400 Subject: [PATCH] =?UTF-8?q?fix(wcf):=20set=20Via=20via=20CreateChannel(add?= =?UTF-8?q?ress,=20via)=20=E2=80=94=20ClientViaBehavior=20absent=20in=20.N?= =?UTF-8?q?ET=20WCF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ClientViaBehavior is a .NET Framework type not present in the System.ServiceModel client libraries. Use the portable ChannelFactory.CreateChannel(EndpointAddress, Uri) overload instead, via a CreateChannel helper applied at the history-open and retrieval-query sites (the critical event path). Fixes the build break in 954b9cc. Claude-Session: https://claude.ai/code/session_012SDSQ3AcaXqPcBtDESBRii --- .../Wcf/HistorianWcfAuthChainHelper.cs | 2 +- .../HistorianWcfClientCredentialsHelper.cs | 25 +++++++++++++------ .../Wcf/HistorianWcfEventOrchestrator.cs | 2 +- 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/AVEVA.Historian.Client/Wcf/HistorianWcfAuthChainHelper.cs b/src/AVEVA.Historian.Client/Wcf/HistorianWcfAuthChainHelper.cs index 5031b24..934d5ed 100644 --- a/src/AVEVA.Historian.Client/Wcf/HistorianWcfAuthChainHelper.cs +++ b/src/AVEVA.Historian.Client/Wcf/HistorianWcfAuthChainHelper.cs @@ -41,7 +41,7 @@ internal static class HistorianWcfAuthChainHelper try { - IHistoryServiceContract2 historyChannel = historyFactory.CreateChannel(); + IHistoryServiceContract2 historyChannel = HistorianWcfClientCredentialsHelper.CreateChannel(historyFactory, options); ICommunicationObject historyChannelCo = (ICommunicationObject)historyChannel; try { diff --git a/src/AVEVA.Historian.Client/Wcf/HistorianWcfClientCredentialsHelper.cs b/src/AVEVA.Historian.Client/Wcf/HistorianWcfClientCredentialsHelper.cs index b8689f5..83bec42 100644 --- a/src/AVEVA.Historian.Client/Wcf/HistorianWcfClientCredentialsHelper.cs +++ b/src/AVEVA.Historian.Client/Wcf/HistorianWcfClientCredentialsHelper.cs @@ -2,7 +2,6 @@ using System.IdentityModel.Selectors; using System.IdentityModel.Tokens; using System.Security.Cryptography.X509Certificates; using System.ServiceModel; -using System.ServiceModel.Description; using System.ServiceModel.Security; namespace AVEVA.Historian.Client.Wcf; @@ -29,14 +28,24 @@ internal static class HistorianWcfClientCredentialsHelper RevocationMode = X509RevocationMode.NoCheck, }; } + } - // Tunnel/proxy support: connect to the Via address while still addressing the message To the - // logical endpoint (Host/Port). Lets a port-forward whose local port differs from the server's - // real service port satisfy the server-side WCF AddressFilter (which checks the To header). - if (!string.IsNullOrWhiteSpace(options.ConnectViaAddress)) - { - factory.Endpoint.EndpointBehaviors.Add(new ClientViaBehavior(new Uri(options.ConnectViaAddress))); - } + /// + /// Creates a channel from , honoring + /// when set: the channel connects to + /// the Via address while still addressing the SOAP message To the factory's logical endpoint. + /// This lets a port-forward whose local port differs from the server's real service port satisfy the + /// server-side WCF AddressFilter (which validates the To header). Use this in place of + /// factory.CreateChannel() at every WCF event/read channel-creation site. + /// + public static TChannel CreateChannel(ChannelFactory factory, HistorianClientOptions options) + { + ArgumentNullException.ThrowIfNull(factory); + ArgumentNullException.ThrowIfNull(options); + + return string.IsNullOrWhiteSpace(options.ConnectViaAddress) + ? factory.CreateChannel() + : factory.CreateChannel(factory.Endpoint.Address, new Uri(options.ConnectViaAddress)); } private sealed class AcceptAnyCertificateValidator : X509CertificateValidator diff --git a/src/AVEVA.Historian.Client/Wcf/HistorianWcfEventOrchestrator.cs b/src/AVEVA.Historian.Client/Wcf/HistorianWcfEventOrchestrator.cs index c8f81a5..d1aaca5 100644 --- a/src/AVEVA.Historian.Client/Wcf/HistorianWcfEventOrchestrator.cs +++ b/src/AVEVA.Historian.Client/Wcf/HistorianWcfEventOrchestrator.cs @@ -167,7 +167,7 @@ internal sealed class HistorianWcfEventOrchestrator try { - IRetrievalServiceContract4 channel = factory.CreateChannel(); + IRetrievalServiceContract4 channel = HistorianWcfClientCredentialsHelper.CreateChannel(factory, _options); ICommunicationObject channelCo = (ICommunicationObject)channel; try {