Tuesday, October 20, 2015

Fix FaultException on ExactTarget API

Most of the time when you working with Salesforce ExactTarget SOAP api these type of exceptions might be very familiar 

Reason for this exception is request doesn't have valid authorized header informtion which we need to set before make request


private static string _authToken = string.Empty;
private static string _sandbox = string.Empty;
private const string Version = "FuelSDX-C#-V.9";
private static string _refreshKey = string.Empty;
private static string _clientId = string.Empty;
private static string _clientSecret = string.Empty;
private static string _appSignature = string.Empty;
private static string _soapEndPoint = string.Empty;
private static string _internalAuthToken = string.Empty;
private static DateTime _authTokenExpiration = DateTime.Now;

public static void PerformRetreiveWithAuthToken(bool force = false)
{
    var binding = new BasicHttpBinding
    {
        Name = "UserNameSoapBinding",
        Security = { Mode = BasicHttpSecurityMode.TransportWithMessageCredential },
        MaxReceivedMessageSize = 2147483647
    };

    var client = new SoapClient(binding, new EndpointAddress("https://webservice.s7.exacttarget.com/Service.asmx"));
    if ((!string.IsNullOrEmpty(_authToken) && DateTime.Now.AddSeconds(300) <= _authTokenExpiration) && !force)
        return;
    var strUrl = "https://auth.exacttargetapis.com/v1/requestToken?legacy=1";
    if (_sandbox == "true")
        strUrl = "https://auth-test.exacttargetapis.com/v1/requestToken?legacy=1";
    var request = (HttpWebRequest)WebRequest.Create(strUrl.Trim());
    request.Method = "POST";
    request.ContentType = "application/json";
    request.UserAgent = Version;
    using (var streamWriter = new StreamWriter(request.GetRequestStream()))
    {
        string json;
        if (_refreshKey.Length > 0)
            json =
                string.Format(
                    @"{{""clientId"": ""{0}"", ""clientSecret"": ""{1}"", ""refreshToken"": ""{2}"", ""scope"": ""cas:{3}"" , ""accessType"": ""offline""}}",
                    _clientId, _clientSecret, _refreshKey, _internalAuthToken);
        else
            json = string.Format(@"{{""clientId"": ""{0}"", ""clientSecret"": ""{1}""}}", _clientId, _clientSecret);
        streamWriter.Write(json);
    }

    var response = (HttpWebResponse)request.GetResponse();
    var dataStream = response.GetResponseStream();
    if (dataStream == null) return;
    var reader = new StreamReader(dataStream);
    var responseFromServer = reader.ReadToEnd();
    reader.Close();
    dataStream.Close();
    response.Close();
    var parsedResponse = JObject.Parse(responseFromServer);
        _internalAuthToken = parsedResponse["legacyToken"].Value().Trim();
        _authToken = parsedResponse["accessToken"].Value().Trim();
        _authTokenExpiration = DateTime.Now.AddSeconds(int.Parse(parsedResponse["expiresIn"].Value().Trim()));
    if (parsedResponse["refreshToken"] != null)
        _refreshKey = parsedResponse["refreshToken"].Value().Trim();

    using (var scope = new OperationContextScope(client.InnerChannel))
    {
        XNamespace ns = "http://exacttarget.com";
        var oauthElement = new XElement(ns + "oAuthToken", _internalAuthToken);
        var xmlHeader = MessageHeader.CreateHeader("oAuth", "http://exacttarget.com", oauthElement);
        OperationContext.Current.OutgoingMessageHeaders.Add(xmlHeader);
        var httpRequest = new HttpRequestMessageProperty();
        OperationContext.Current.OutgoingMessageProperties.Add(HttpRequestMessageProperty.Name, httpRequest);
        httpRequest.Headers.Add(HttpRequestHeader.UserAgent, Version);

        //then we make retrive, update, perform or delete request as usual
        client.Retrieve(request, out requestId, out results)

    }
}

now you good to go, Happy Coding!!