57

I am using postman and making an api post request where I am adding body with x-www-form-urlencoded key/values and it works fine in postman.

The issue arrises when I try it from c# using RestSharp package.

I have tried the following code below but not getting the response. I get "BadRequest" invalid_client error.

public class ClientConfig {
    public string client_id { get; set; } = "value here";
    public string grant_type { get; set; } = "value here";
    public string client_secret { get; set; } = "value here";
    public string scope { get; set; } = "value here";
    public string response_type { get; set; } = "value here";
}

public void GetResponse() {
        var client = new RestClient("api-url-here");
        var req = new RestRequest("endpoint-here",Method.POST);
        var config = new ClientConfig();//values to pass in request

        req.AddHeader("Content-Type","application/x-www-form-urlencoded");
        req.AddParameter("application/x-www-form-urlencoded",config,ParameterType.RequestBody);

        var res = client.Execute(req);
        return;
    }

//Also tried this

    req.AddParameter("client_id",config.client_id,"application/x-www-form-urlencoded",ParameterType.RequestBody);
                req.AddParameter("grant_type",config.grant_type,"application/x-www-form-urlencoded",ParameterType.RequestBody);
                req.AddParameter("client_secret",config.client_secret,"application/x-www-form-urlencoded",ParameterType.RequestBody);
                req.AddParameter("scope",config.scope,ParameterType.RequestBody);
                req.AddParameter("response_type",config.response_type,"application/x-www-form-urlencoded",ParameterType.RequestBody);

//tried this too
var client = new RestClient("url-here");
            var req = new RestRequest("endpointhere",Method.POST);
            var config = new ClientConfig();
req.AddBody(config);
var res = client.Execute(req);
nicedev80
  • 1,575
  • 1
  • 13
  • 17
  • check my answer, if it is helpful for you, mark as accepted answer. :D – Kira Hao Dec 07 '17 at 05:44
  • in my case, grant_type was a header parameter. so i had to use req.Addheader method it worked. below is my code `RestRequest request = new RestRequest("", Method.POST); request.AddHeader("Content-Type", "application/x-www-form-urlencoded"); request.AddParameter("client_id", ClientId); request.AddParameter("client_secret", Secret); request.AddParameter("grant_type", "client_credentials");` – KKR Jun 20 '23 at 23:21

9 Answers9

66

this working for me, it was generator from postman

        var token = new TokenValidation()
        {
               app_id = CloudConfigurationManager.GetSetting("appId"),
               secret = CloudConfigurationManager.GetSetting("secret"),
               grant_type = CloudConfigurationManager.GetSetting("grant_type"),
               Username = CloudConfigurationManager.GetSetting("Username"),
               Password = CloudConfigurationManager.GetSetting("Password"),
        };

        var client = new RestClient($"{xxx}{tokenEndPoint}");
        var request = new RestRequest(Method.POST);
        request.AddHeader("content-type", "application/x-www-form-urlencoded");
        request.AddParameter("application/x-www-form-urlencoded", $"app_id={token.app_id}&secret={token.secret}&grant_type={token.grant_type}&Username={token.Username}&Password={token.Password}", ParameterType.RequestBody);
        IRestResponse response = client.Execute(request);

        if (response.StatusCode != HttpStatusCode.OK)
        {
            Console.WriteLine("Access Token cannot obtain, process terminate");
            return null;
        }

        var tokenResponse = JsonConvert.DeserializeObject<TokenValidationResponse>(response.Content);
Kira Hao
  • 1,077
  • 11
  • 17
  • This does not seem to encode the parameters espacping quotes etc. It also seems to add an extra set of quotes comparing it to postman. – John Feb 23 '18 at 14:47
  • RestSharp.Extensions.StringExtensions.UrlEncode method can encode the values before being sent in the requst. – hmadrigal Mar 11 '18 at 03:31
  • Worked for me. Been using Json deserializer without success – D_Edet Dec 10 '18 at 15:27
  • Another option is to use Request.AddObject like: var client = new RestClient(url); var request = new RestRequest(Method.POST); request.AddHeader("content-type", "application/x-www-form-urlencoded"); var loginData = new LoginRequest(username, password); request.AddObject(loginData); var result = await client.ExecuteAsync(request); – Tyson Swing Aug 04 '21 at 04:26
62

I personally find this way to work better for me when sending Form-UrlEncoded data.

public void GetResponse() {
        var client = new RestClient("api-url-here");
        var req = new RestRequest("endpoint-here",Method.POST);
        var config = new ClientConfig();//values to pass in request

        // Content type is not required when adding parameters this way
        // This will also automatically UrlEncode the values
        req.AddParameter("client_id",config.client_id, ParameterType.GetOrPost);
        req.AddParameter("grant_type",config.grant_type, ParameterType.GetOrPost);
        req.AddParameter("client_secret",config.client_secret, ParameterType.GetOrPost);
        req.AddParameter("scope",config.scope, ParameterType.GetOrPost);
        req.AddParameter("response_type",config.response_type, ParameterType.GetOrPost);

        var res = client.Execute(req);
        return;
}

Details on this parameter type can be found here: https://github.com/restsharp/RestSharp/wiki/ParameterTypes-for-RestRequest#getorpost

Nosfera2
  • 945
  • 7
  • 7
15

Personally, I found AddObject() method quite useful, and cleaner when you have so many parameters to add.

public void GetResponse() {
        var client = new RestClient("api-url-here");
        var req = new RestRequest("endpoint-here",Method.POST);
        var config = new ClientConfig();//values to pass in request

        req.AddHeader("Content-Type","application/x-www-form-urlencoded");
        req.AddObject(config);

        var res = client.Execute(req);
        return res;
    }
Dinch
  • 548
  • 4
  • 9
5

If it worked on postman, you can just press the code button on the right hand side. This will provide a working example in multiple languages. It is the button above the information icon. I would post a screenshot of it, but I don't have 10 reputation to do so.

DavidH541
  • 59
  • 1
  • 4
2

i have found this good for my scenario , it is working perfect,

var client = new RestClient("https://test.salesforce.com/services/oauth2/token");
            var request = new RestRequest(Method.POST);
            request.AddHeader("content-type", "application/x-www-form-urlencoded");
            request.AddParameter("application/x-www-form-urlencoded", "grant_type=password&client_id=3MVG9U_dUptXGpYKew7P.oPwrIsvowP_K4CsnkxHJIEOUJzW0XBUUY3o12bLDasjeIPGVobvBZo8TNFcCY6J3&client_secret=3189542819149073716&username=integraciones%40lamarina.com.mx.dev&password=2Password!4iwZvMQKVAwkYyJRy50JlAHk", ParameterType.RequestBody);
            IRestResponse response = client.Execute(request);
    Console.WriteLine("Response.StatusCode: " + response.StatusCode);
    Console.WriteLine("Response.Content: " + response.Content);
    Console.WriteLine("Response.ErrorMessage: " + response.ErrorMessage);

https://dotnetfiddle.net/J64FR5

1

in my case this is what worked

req.AddParameter("client_id", "unigen-corporation", ParameterType.HttpHeader);
req.AddParameter("grant_type", "client_credentials", ParameterType.GetOrPost);
Derek C.
  • 890
  • 8
  • 22
1

If you've copied the code from the postman, try removing the following:

request.AlwaysMultipartFormData = true;

In my case after removing this line code worked.

0

var client1 = new RestClient(URI);
var request1 = new RestRequest(Method.POST);
request1.AddHeader("Content-Type", "application/x-www-form-urlencoded");
request1.AddParameter("client_id", "XX");
request1.AddParameter("client_secret", "XX");
request1.AddParameter("grant_type", "XX");
request1.AddParameter("role", "XX");
IRestResponse response1 = client1.Execute(request1);
System.Console.WriteLine(response1.Content);

Add parameters according to your needs. This work fine!

0

for my code, this works perfect.

// extention function for object->formed data body string
public static string toFormDataBodyString(this object src)
{
    var res = new List<string>();
    foreach (var key in src.GetType().GetProperties())
    {
        res.Add($"{key.Name}={src.GetType().GetProperty(key.Name)?.GetValue(src)}");
    }
    return string.Join("&", res);
}
//--------------------------------------

var data = new {
    param1 = xxxx,
    param2 = xxxx
}
var translateReq = new RestRequest("url_here")
                      .AddHeader("Content-Type", "application/x-www-form-urlencoded")
                      .AddParameter("application/x-www-form-urlencoded", data.toFormDataBodyString(), ParameterType.RequestBody);
N0I0C0K
  • 47
  • 3