2

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>

closed as off-topic by Eric, Himanshu, Raul, Martin Lezer, Ratan Paul May 31 '17 at 11:10

This question appears to be off-topic. The users who voted to close gave this specific reason:

  • "Programming questions not specific to Salesforce are off-topic here, but can be asked on Stack Overflow." – Eric, Himanshu, Raul, Martin Lezer, Ratan Paul
If this question can be reworded to fit the rules in the help center, please edit the question.

  • Are you using WCF to interact with the Marketing Cloud SOAP API? – Daniel Ballinger May 24 '17 at 21:49
  • I am consuming SOAP API from .NET application. – Reddy May 25 '17 at 12:55
  • I am implemented the changes. But I see the exception. – Reddy May 31 '17 at 4:43
3

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)
);
  • 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 May 26 '17 at 18:28
  • Thanks Daniel. I implemented same. But I am getting below exception – Reddy May 31 '17 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. – Daniel Ballinger May 31 '17 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 Jun 29 '17 at 16:11

Not the answer you're looking for? Browse other questions tagged or ask your own question.