3

I would like help how I can append Soap Header with following header in C#. Currently we are passing user credentials in the header. I need a help how we can replace with FuelOauth node in C#? As per Using Fuel oAuth with the SOAP API

enter image description here

<Header>
    <fueloauth xmlns="http://exacttarget.com">YOURACCESSTOKEN</fueloauth>
</Header>

_etSoapApiClient.ClientCredentials.UserName.UserName =  ConfigurationManager.AppSettings["wsUserName"];

_etSoapApiClient.ClientCredentials.UserName.Password = ConfigurationManager.AppSettings["wsPassword"];

  var clientID = new ClientID { ID = XXXXXXX, IDSpecified = true }; 


        var definition = new TriggeredSendDefinition { CustomerKey = "TEST", Client = clientID };


        var triggeredSend = new TriggeredSend
        {
            TriggeredSendDefinition = definition,
            Client = clientID,
            Subscribers = CreateSubscribers()
        };



        APIObject[] apiObject = { triggeredSend };
        String requestId;
        String overAllStatus;
        var createOptionsAsynchronous = new CreateOptions { RequestType = RequestType.Asynchronous, RequestTypeSpecified = true };

        var createOptionsSynchronous = new CreateOptions { RequestType = RequestType.Synchronous, RequestTypeSpecified = true };

           var createResults = _etSoapApiClient.Create(createOptionsAsynchronous, apiObject, out requestId, out overAllStatus);

        var tsCreateResults = createResults[0] as TriggeredSendCreateResult;

        SubscriberResult[]  subscriberResult = tsCreateResults.SubscriberFailures;

Thanks Daniel.

I am getting below exception

System.InvalidOperationException was unhandled

HResult=-2146233079 Message=The username is not provided. Specify username in ClientCredentials. Source=mscorlib StackTrace: Server stack trace: at System.ServiceModel.ClientCredentialsSecurityTokenManager.CreateSecurityTokenProvider(SecurityTokenRequirement tokenRequirement, Boolean disableInfoCard) at System.ServiceModel.ClientCredentialsSecurityTokenManager.CreateSecurityTokenProvider(SecurityTokenRequirement tokenRequirement) at System.ServiceModel.Security.SecurityProtocol.AddSupportingTokenProviders(SupportingTokenParameters supportingTokenParameters, Boolean isOptional, IList1 providerSpecList) at System.ServiceModel.Security.SecurityProtocol.OnOpen(TimeSpan timeout) at System.ServiceModel.Security.WrapperSecurityCommunicationObject.OnOpen(TimeSpan timeout) at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) at System.ServiceModel.Security.SecurityProtocol.Open(TimeSpan timeout) at System.ServiceModel.Channels.SecurityChannelFactory1.ClientSecurityChannel`1.OnOpen(TimeSpan timeout) at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) at System.ServiceModel.Channels.ServiceChannel.OnOpen(TimeSpan timeout) at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) at System.ServiceModel.Channels.ServiceChannel.CallOpenOnce.System.ServiceModel.Channels.ServiceChannel.ICallOnce.Call(ServiceChannel channel, TimeSpan timeout) at System.ServiceModel.Channels.ServiceChannel.CallOnceManager.CallOnce(TimeSpan timeout, CallOnceManager cascade) at System.ServiceModel.Channels.ServiceChannel.EnsureOpened(TimeSpan timeout) at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout) at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs) at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation) at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message) Exception rethrown at [0]: at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg) at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type) at

and below is my WCF end point

<bindings>
  <customBinding>
    <binding name="SoapBinding" closeTimeout="00:40:00" openTimeout="00:40:00" receiveTimeout="00:40:00" sendTimeout="00:40:00">
      <security authenticationMode="UserNameOverTransport">
        <secureConversationBootstrap />
      </security>
      <textMessageEncoding messageVersion="Soap11WSAddressingAugust2004" />
      <httpsTransport maxReceivedMessageSize="655360000" />
    </binding>
  </customBinding>
</bindings>
<client>
  <endpoint address="https://webservice.exacttarget.com/Service.asmx" binding="customBinding" bindingConfiguration="SoapBinding" contract="ExactTargetClient.Soap" name="Soap" />
</client>
3
  • Are you using WCF to interact with the Marketing Cloud SOAP API? Commented May 24, 2017 at 21:49
  • I am consuming SOAP API from .NET application.
    – Reddy
    Commented May 25, 2017 at 12:55
  • I am implemented the changes. But I see the exception.
    – Reddy
    Commented May 31, 2017 at 4:43

1 Answer 1

5

I recently had some challenges adding a SOAP Header when creating a Universal Windows Platform (UWP) application in .NET against the SOAP based APIs.

The problem was that the WCF tooling for importing WSDLs in UWP apps doesn't automatically generate the SOAP Header classes. You need to create your own header by implementing System.ServiceModel.Channels.MessageHeader and a corresponding IClientMessageInspector.

There are some well written notes on how to implement this in Calling Salesforce SOAP APIs from a .NET Core or UWP App

For reference, there is the Marketing Cloud API - Connecting to the SOAP API using WCF, but it doesn't seem to reference FuelOauth in the linked WSDLs.


using System.ServiceModel.Channels;
using System.Xml;

namespace XYZ.ForceClient.Core
{
    internal class FuelOAuthHeader : MessageHeader
    {
        public FuelOAuthHeader(string accessToken)
        {
            _accessToken = accessToken;
        }

        private string _accessToken;

        public override string Name => "fueloauth";

        public override string Namespace => "http://exacttarget.com";

        protected override void OnWriteHeaderContents(XmlDictionaryWriter writer, MessageVersion messageVersion)
        {
            writer.WriteElementString("fueloauth", _accessToken);
        }
    }
}

using System;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Dispatcher;

namespace XYZ.ForceClient.Core
{
    internal class FuelOAuthInspector : IClientMessageInspector
    {
        public FuelOAuthInspector(string accessToken)
        {
            _accessToken = accessToken;
        }

        private string _accessToken;

        public void AfterReceiveReply(ref Message reply, object correlationState)
        {

        }

        public object BeforeSendRequest(ref Message request, IClientChannel channel)
        {
            request.Headers.Add(new FuelOAuthHeader(_accessToken));

            return Guid.NewGuid();
        }
    }
}

using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;

namespace XYZ.ForceClient.Core
{
    internal class FuelOAuthHeaderBehavior : IEndpointBehavior
    {
        public FuelOAuthHeaderBehavior(string accessToken)
        {
            _accessToken = accessToken;
        }

        private string _accessToken;

        public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
        {

        }

        public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
        {
            clientRuntime.ClientMessageInspectors.Add(new FuelOAuthInspector(_accessToken));
        }

        public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
        {

        }

        public void Validate(ServiceEndpoint endpoint)
        {

        }
    }
}

Then whey you need to use the header do something like:

_etSoapApiClient.Endpoint.EndpointBehaviors.Add(
    new FuelOAuthHeaderBehavior(fuelOAuthAccessToken)
);
4
  • Thanks. I am looking into this exactly "For reference, there is the Marketing Cloud API - Connecting to the SOAP API using WCF, but it doesn't seem to reference FuelOauth in the linked WSDLs." But I found below link and but I am not sure how to consume. kellyjandrews.com/2014/02/20/…
    – Reddy
    Commented May 26, 2017 at 18:28
  • Thanks Daniel. I implemented same. But I am getting below exception
    – Reddy
    Commented May 31, 2017 at 4:36
  • @Reddy You might need to verify the approach before trying it in C#. I find Soap UI to be really useful for experimenting with APIs. Commented May 31, 2017 at 9:25
  • Thanks again Danial. This works now. We are consuming SOAP API in .NET core and implemented above functionality. I am able to see the response.
    – Reddy
    Commented Jun 29, 2017 at 16:11

Not the answer you're looking for? Browse other questions tagged .