6

I have some existing code that was working and all-of-a-sudden quit.

I can't figure out why...

Here is my code:

public static string RequestToken(string u, string pw)
{
    string result = string.Empty;

    string strUrl = "https://xxx.cloudforce.com/services/oauth2/token?grant_type=password&client_id=XXXX&client_secret=XXXX&username=" + u + "&password=" + pw;
    HttpWebRequest tokenRequest = WebRequest.Create(strUrl) as HttpWebRequest;
    Debug.Print(strUrl);
    tokenRequest.Method = "POST";
    try
    {
        using (HttpWebResponse tokenResponse = tokenRequest.GetResponse() as HttpWebResponse)
        {
            if (tokenResponse.StatusCode != HttpStatusCode.OK)
                throw new Exception(String.Format(
                    "Server error (HTTP {0}: {1}).",
                    tokenResponse.StatusCode,
                    tokenResponse.StatusDescription));
            DataContractJsonSerializer jsonSerializer2 = new DataContractJsonSerializer(typeof(ResponseAuthentication));
            object objTokenResponse = jsonSerializer2.ReadObject(tokenResponse.GetResponseStream());
            ResponseAuthentication jsonResponseAuthentication = objTokenResponse as ResponseAuthentication;
            result = jsonResponseAuthentication.strAccessToken;
        }
    }
    catch (Exception ex)
    {
        Debug.Print(ex.InnerException.ToString());
    }
    return result;
}

I am now getting a 500 Internal Server Error where before this was working cleanly.

When I try to debug using Postman, I pass the URL directly and it works fine. Even when I put a stop in the code and use the exact same URL that then fails from inside the code, it works in Postman, but not in C#.

Out of Postman, I get an orderly...

{
  "access_token": "XXXXXX",
  "instance_url": "https://xxx.cloudforce.com",
  "id": "https://login.salesforce.com/id/XXXXXX",
  "token_type": "Bearer",
  "issued_at": "XXXXXX",
  "signature": "XXXXXX"
}

To clarify, I have tried a GET request instead of POST and I receive the following response (in Postman):

{
  "error": "invalid_request",
  "error_description": "must use HTTP POST"
}

Any ideas here?

4
  • are you sure method type should be 'POST' ? Commented Mar 7, 2017 at 18:28
  • @levent - yes, that's what i'm using in Postman too... GET does NOT work. Commented Mar 7, 2017 at 18:31
  • what is request.contentType on postman success case? Commented Mar 7, 2017 at 18:36
  • @levent - works with any content type in Postman. form-data, x-www-form-urlencoded, raw, or binary Commented Mar 7, 2017 at 18:38

1 Answer 1

13

So, the answer ended up being that Salesforce ended their support for TLS 1.0, which is the default in .NET 4.5.

In this link, they mention this should happen in July of 2017, but somehow it hit our instance early. https://help.salesforce.com/articleView?id=000221207&type=1

We later confirmed that it would work in .NET 4.6, but NOT in 4.5...

Turns out .NET 4.6 defaults to using TLS 1.2.

It was a very simple fix, which took a LONG time to figure out.

Added this one line of code and it immediately worked:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

Hope that helps someone else with the same problem!

A little frustrating when such a simple one-line solution takes days to find.

Sign up to request clarification or add additional context in comments.

4 Comments

Thank you for saving me. Wish I could upvote more than once.
where did you add this line?
For me, just near the beginning of the main program.
It is not specific to salesforce. I have stroggled with issue for a lot of hours, when finally stumbeling over this solution. And it worked upgrading to .NET 4.6 thanks.!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.