Asp.Net Core 2.0 WCF Client CustomBinding PlatformNotSupportedException: BuildChannelFactoryCore is not supported
Asked Answered
J

1

6

I need to be able to send authorization in my Client using custom bindings in Asp.Net Core 2.0. It works in Asp.net 4.6.1 and doesn't work in Core 2.2. I am trying to connect to a Workday Public Web Service in our Tenant. Since I was able to make this work in Asp.Net 4.6.1, I completed my development there, but would like to figure this out for possible future development.

I created the custom bindings that I used in code. see below, however, I always get this error: Full Message:

System.PlatformNotSupportedException : TransportSecurityBindingElement.BuildChannelFactoryCore is not supported.

My implementation in Asp.Net Core 2.0 MVC:

     public async Task<bool> ImportTimeEntryBlockAsync(TimeEntry item)
       {
           bool isValid = true;
           //Create the update object to update the webservice           

           //setup Header
           Workday_Common_HeaderType header = new Workday_Common_HeaderType
           {
               Include_Reference_Descriptors_In_Response = true
           };

           //setup reported time block data from item
           Reported_Time_Block_DataType timeBlockData = new Reported_Time_Block_DataType();

           PopulateTimeBlock(item, ref timeBlockData);
           Reported_Time_Block_DataType[] timeBlocks = new Reported_Time_Block_DataType[1];
           timeBlocks[0] = timeBlockData;

           //setup import reported time block request
           Import_Reported_Time_Blocks_RequestType request = new Import_Reported_Time_Blocks_RequestType
           {
               version = "v29.0",
               Reported_Time_Block_Data = timeBlocks
           };
           Import_Reported_Time_BlocksInput timeBlock = new Import_Reported_Time_BlocksInput(header, request);

           //create client object
           Time_TrackingPortClient timeTracking = new Time_TrackingPortClient();
           timeTracking.ClientCredentials.UserName.UserName = IntegrationUser + @"@" + IntegrationDomain;
           timeTracking.ClientCredentials.UserName.Password = IntegrationPassword;

           SetupCustomBinding(timeTracking);

           //Set endpoint address
           Uri uri = new Uri(WorkdayHost + @"/Time_Tracking/v29.0");
           EndpointAddress endpoint = new EndpointAddress(uri);
           timeTracking.Endpoint.Address = endpoint;

           await timeTracking.OpenAsync();
           var result = await timeTracking.Import_Reported_Time_BlocksAsync(timeBlock);


           if (result == null)
               isValid = false;
           return isValid;
       }

       private static void SetupCustomBinding(Time_TrackingPortClient timeTracking)
       {
           // Create a custom binding that contains two binding elements; Security, Encoding and Transport

           //Security
           TransportSecurityBindingElement transportSecurity = SecurityBindingElement.CreateUserNameOverTransportBindingElement();
           transportSecurity.IncludeTimestamp = true;

           XmlDictionaryReaderQuotas readerQuotas = new XmlDictionaryReaderQuotas
           {
               MaxArrayLength = int.MaxValue,
               MaxBytesPerRead = int.MaxValue,
               MaxDepth = int.MaxValue,
               MaxNameTableCharCount = int.MaxValue,
               MaxStringContentLength = int.MaxValue
           };
           //encoding
           TextMessageEncodingBindingElement textEncoding = new TextMessageEncodingBindingElement
           {
               MessageVersion = MessageVersion.Soap11,
               ReaderQuotas = readerQuotas
           };

           // transport       
           HttpsTransportBindingElement httpsTransport = new HttpsTransportBindingElement
           {
               AuthenticationScheme = AuthenticationSchemes.Basic,
               MaxBufferSize = int.MaxValue,
               MaxReceivedMessageSize = int.MaxValue,
               TransferMode = TransferMode.Buffered
           };

           SynchronizedCollection<BindingElement> coll = new SynchronizedCollection<BindingElement>
           {
               transportSecurity,
               textEncoding,
               httpsTransport
           };

           //Set Custom Binding
           CustomBinding binding = new CustomBinding(coll);
           timeTracking.Endpoint.Binding = binding;
       }

Expected it to give me a response, since I was able to make it work in Asp.Net in a web.config setting:

  <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="IntegrationsBinding">
          <security mode="Transport"/>
        </binding>
        <binding name="IntegrationsBinding1"/>
      </basicHttpBinding>
      <customBinding>
        <binding name="WDWebServiceCustomBinding">
          <security authenticationMode="UserNameOverTransport" includeTimestamp="false">
            <secureConversationBootstrap/>
          </security>
          <textMessageEncoding messageVersion="Soap11">
            <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647"/>
          </textMessageEncoding>
          <httpsTransport maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" realm=""/>
        </binding>
      </customBinding>
    </bindings>
    <client>
      <endpoint address="https://[webserver]/Time_Tracking/v31.0" binding="customBinding" bindingConfiguration="WDWebServiceCustomBinding" contract="TimeTracking.Time_TrackingPort" name="Time_Tracking"/>
      <endpoint address="https://[webserver]/Integrations/v31.0" binding="customBinding" bindingConfiguration="WDWebServiceCustomBinding" contract="Integration.IntegrationsPort" name="Integrations"/>
      <endpoint address="https://[webserver]/Absence_Management/v31.0" binding="customBinding" bindingConfiguration="WDWebServiceCustomBinding" contract="Absence.Absence_ManagementPort" name="Absence_Management"/>
    </client>
  </system.serviceModel>

I don't think that I implemented it incorrectly, but need to know if I missed something or if the BuildChannelFactoryCore is still not supported, then when will it be?

Reference blogs where this is mentioned:

https://github.com/dotnet/wcf/issues/13

https://github.com/dotnet/wcf/issues/1257

Thanks,

Paul

Jordon answered 12/2, 2019 at 19:18 Comment(4)
Note, I have this same question on MSDN and it has not been answered. It's been there since Nov/2017.Jordon
Out of curiosity did you managed to get a working fix for this?Screw
I didn't, but haven't tried since .Net Core 3.0 came out.Jordon
Still, I appreciate the feedback. Thanks!Screw
P
0
Uri epUri = new Uri(_serviceUri);
CustomBinding binding = new CustomBinding();
SecurityBindingElement sbe = SecurityBindingElement.CreateUserNameOverTransportBindingElement();
sbe.MessageSecurityVersion = MessageSecurityVersion.WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11;        
sbe.SecurityHeaderLayout = SecurityHeaderLayout.Strict;
sbe.IncludeTimestamp = false;
sbe.SetKeyDerivation(true);
sbe.KeyEntropyMode = System.ServiceModel.Security.SecurityKeyEntropyMode.ServerEntropy;
binding.Elements.Add(sbe);
binding.Elements.Add(new TextMessageEncodingBindingElement(MessageVersion.Soap11, System.Text.Encoding.UTF8));
binding.Elements.Add(new HttpsTransportBindingElement());
EndpointAddress endPoint = new EndpointAddress(epUri);
Portent answered 13/5, 2020 at 13:27 Comment(1)
What version of .Net Core are you using?Jordon

© 2022 - 2024 — McMap. All rights reserved.