Search code examples
c#.nethttphttpwebrequesthttpwebresponse

.net twitter api Missing required parameter: grant_type:forbidden_missing_parameter


Simply trying to get an access token to Twitter API with a c# .net program. I have composed the http post request as follows (leaving out the catch statements to save space):

        HttpWebRequest request;
        request = (HttpWebRequest)WebRequest.Create("https://api.twitter.com/oauth2/token");

        request.Method = "POST";
        request.Host = "api.twitter.com";
        request.UserAgent = "Dev Site"; 
        request.Headers.Set("Authorization", "Basic " + credentialBase64);
        request.ContentType = "application/x-www-form-urlencoded;charset=UTF-8";
        //request.Headers.Set("Accept-Encoding", "gzip");

        try
        {
            WebResponse response = (HttpWebResponse)request.GetResponse();
            Stream dataStream = response.GetResponseStream();
            byte[] requestBody = ASCIIEncoding.ASCII.GetBytes(HttpUtility.UrlEncode("grant_type=client_credentials"));
            request.ContentLength = requestBody.Length;
            dataStream.Write(requestBody, 0, requestBody.Length);
            StreamReader reader = new StreamReader(dataStream);
            twitterString = reader.ReadToEnd();


        }

Twitter api is sending back the response: {"errors":[{"code":"170","message":"Missing required parameter: grant_type","label":"forbidden_missing_parameter}]}

I understand what the error means. It is telling me that I am not including the content-body grant_type=client_credentials. But as you can see I AM sending that content-body with the Stream.Write method.

At first I assumed it was because the string was not UrlEncoded, maybe it needed a backslash before the equals sign or something. So I UrlEncoded the string just to make sure. I think it must still be in the wrong format somehow but I am not sure how.

Why is the Twitter api not getting the content-body I am sending to them?

Update: I have taken the advice of @Linvi and copied exactly the format of the article at How to set the content of an HttpWebRequest in C#? . Here is my current code:

        byte[] buffer = ASCIIEncoding.ASCII.GetBytes(HttpUtility.UrlEncode("grant_type=client_credentials"));
        var webReq = (HttpWebRequest)WebRequest.Create("https://api.twitter.com/oauth2/token");
        webReq.Method = "POST";
        webReq.Host = "api.twitter.com";
        webReq.Headers.Set("Authorization", "Basic " + credentialBase64);
        webReq.ContentType = "application/x-www-form-urlencoded;charset=UTF-8";
        webReq.ContentLength = buffer.Length;

        var reqStream = webReq.GetRequestStream();
        reqStream.Write(buffer, 0, buffer.Length);
        reqStream.Close(); 
        var webResp = (HttpWebResponse)webReq.GetResponse();

I am still getting a response of '403' in the format: {"errors":[{"code":"170","message":"Missing required parameter: grant_type","label":"forbidden_missing_parameter}]}.

I have tested this with a local program that looks at the content body, and it is coming out null. I cannot figure out why my content body isn't being written.


Solution

  • Finally got it to work. I had to stop urlencoding the grant type request. For anyone else trying to get the access token from Twitter api, here is the code that works:

            byte[] buffer = ASCIIEncoding.ASCII.GetBytes("grant_type=client_credentials");
            var webReq = (HttpWebRequest)WebRequest.Create("https://api.twitter.com/oauth2/token");
    
            webReq.Method = "POST";
            webReq.Host = "api.twitter.com";
            webReq.Headers.Set("Authorization", "Basic " + credentialBase64);
            webReq.ContentType = "application/x-www-form-urlencoded;charset=UTF-8";
            webReq.ContentLength = buffer.Length;
    
            var reqStream = webReq.GetRequestStream();
            reqStream.Write(buffer, 0, buffer.Length);
            reqStream.Close();
            var webResp = (HttpWebResponse)webReq.GetResponse();