Incorrect Format for JSON deserialization - c#

I am very much out of my element on this. In C# I am writing a method to get data back from a website using REST. Per the documentation on the website I should use something like this:
var client = new RestClient(url + "token");
var request = new RestRequest(Method.POST);
request.AddParameter("application/x-www-form-urlencoded",
"grant_type=password&username=" + UserName +
"&password=" + Password +
"&tenant=" + Company,
ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
to get a response that looks like this:
{
"access_token": "generated_token_value",
"token_type": "bearer",
"expires_in": 2591999
}
However, I have no earthly clue to how to read that info. I'm assuming that the JSON response is in my "response" variable, but beyond that I'm at a loss. I've done a little digging and have found Json.NET should be helpful, but it's over my head. Their documentation suggests:
Product deserializedProduct = JsonConvert.DeserializeObject<Product>(output);
However if I convert that into something that looks correct for mine (creating a "Responses" Class and then):
Responses responses = JsonConvert.DeserializeObject<Responses>(response);
I get an error in VS under the "response" saying "cannot convert from 'RestSharp.IRestResponse' to 'string'.
I feel like I just need a little nudge to get over this hump.

If you go to the repository of RestSharp you'll see that it has special property called Content which contains JSon in a string format.
Now you can use JsonConvert.DeserializeObject<Responses>(response.Content); to retrieve your object.

Responses responses = JsonConvert.DeserializeObject<Responses>(response.Content);

Another option could be declaring the response for the out type you're expecting
IRestResponse<Responses> response = client.Execute<Responses>(request);

Related

How to call ChatGPT from C# using HttpClientFactory, I keep getting errors and no responses

Getting really irritated with this. The playground gives only python and node, trying to use this in C# and I keep getting errors. Here is how I have it setup.
First in the Program / Startup file, I am setting it up like so: (URL: https://api.openai.com/)
services.AddHttpClient("ChatGptAPI", client =>
{
client.DefaultRequestHeaders.Clear();
client.BaseAddress = aiOptions.Url;
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + aiOptions.Bearer);
});
Then in my method, I am calling this:
var client = _httpFactory.CreateClient("ChatGptAPI");
var payload = new
{
prompt = $"Create a first person story\n\n{storyText}",
temperature = "0.5",
max_tokens = "1500",
model = "text-davinci-003"
};
var content = new StringContent(JsonSerializer.Serialize(payload), Encoding.UTF8, "application/json");
var response = await client.PostAsync("v1/completions", content);
Console.WriteLine("ChatGptAPI result:");
Console.WriteLine(response.RequestMessage);
I at first I kept getting Bad Request errors, but once I tried other URLs for the request, it appears to go through, but the response is blank.
For the life of me, I cannot find any samples out there that has C# calling these services.
Any help would be great.
I have tried multiple URLs, I've tried running this in Playground and view code and I've searched for other samples, but this keeps failing or returning nothing. Also tried using the OpenAI Nuget package, that was a waste of time.
If you are actually managing to reach the completions endpoint and you have a valid key then you are just reading the wrong object back.
After you get your response you should read it, something like:
var gptResponse = await response.Content.ReadAsStringAsync();
you can then parse or better deserialize the API response

Error while trying to get data from httprequest

I'm trying to build an application that gets data from a webservice and allows me to process it in my application.
The data I need is being published on a website so in order to get access to the data I had to use the Developer Tools to try and find the call that returns the data on the website.
I have found the call and I can see the requests which are being made so as a first step I'm trying to mimic this call so I get the same results before I do anything else.
However, when I request the data, I'm getting an error stating:
key must be a string at line 1 column 2
So I'm asssuming there's something wrong with the data I'm sending in the body of my request but I don't know what.
Since the error states that the "Key" must be a string, I thought that I might had to use a Key/Value pair but I can clearly see in the Developer Tools that there is a content type mentioned:
content-type: application/json
so it seems to me that I need to send JSON.
Also when I look at the Request Payload I am seeing a JSON-formatted string being sent:
{"query":"\n query getData {\n other data which I have removed for clarity \n }\n "}
So even when I copy the entire string that I see in the Developer Tools and send that as a JSON-formatted string to the service. I still get the errormessage.
Below is the code that I'm using:
using (var client = new HttpClient())
{
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
client.BaseAddress = new Uri("https://api.thesite.com");
string json = "{'query':'\n query getData {\n yada yada yada ... }\n '}";
var content = new StringContent(json, Encoding.UTF8, "application/json");
var result = await client.PostAsync("/data/history", content);
string resultContent = await result.Content.ReadAsStringAsync();
}
I know it's difficult to troubleshoot it like that without having access to the actual data itself. But I'm not looking for someone to fix the problem for me, I'm just trying to understand what the problem actually is.
Am I using the wrong functions? Do I need to actually encode it in JSON again and then serialize it into a json instead of using the actual serialized JSON-string?
Those are the things I'm wondering right now.
I hope someone can enlighten me.
Thanks

Is there a way to retrieve the String the way it is actually uploaded to the server (as a whole)?

I am currently working on a OAuth2 implementation. However I am stuck on an Error 401. It seems like there is something wrong with my post request that is supposed to retrieve the access token from the Company the User logged in to. This is my code:
internal void RequestAccessToken(string code)
{
string requestBody = "grant_type="+ WebUtility.UrlEncode(GRANTTYPE)+ "&code=" + WebUtility.UrlEncode(code)+"&redirect_uri="+ WebUtility.UrlEncode(REDIRECT_URI);
WebClient client = new WebClient();
client.Headers.Add("Authorization",HeaderBase64Encode(CLIENT_ID, SECRETKEY));
var response = client.UploadString("https://thewebsiteiamcallingto.com/some/api", requestBody);
var responseString = client.OpenRead("https://thewebsiteiamcallingto.com/some/api");
}
My Questions are:
Is there anything wrong with the way I try to make the POST request ?
Is there a way to retrieve the whole string that is posted to the URI using UploadString?
P.S. I have seen this post regarding the POST creation. However I find the async part to be too complicated for my case.
Since we dont know the api documentation, I would suggest you to make a postman request and view the actual request sent and response received, and secondly make a request using your method and capture using a utility like wireshark and compare the difference.

What is the equivalent of using StringContent (System.Net.Http) to make a post request in Python

I have some C# code that does the following post request:
string postData = newFormUrlEncodedContent(params).ReadAsStringAsync().Result;
var postContent = new StringContent(postData, UTF8Encoding.UTF8, "application/x-www-form-urlencoded");
var responseMessage = httpClient.PostAsync(url, postContent).Result;
I would like to do the equivalent in Python using the Requests library. This is what I have:
headers = {'content-type':'application/x-www-form-urlencoded'}
postContent = requests.post(url, params=params, headers=headers, cookies=previousResponse.cookies)
But postContent.status_code for the Python code is 404, whereas the C# request returns 200. It's possible that there's something wrong with the params since I retrieve those via some Regex matching from a previous request, but that seems to be working.
Edit: I think setting the params parameter is for get requests, not post requests. Also I believe Requests takes care of form encoding:
Typically, you want to send some form-encoded data — much like an HTML form. To do this, simply pass a dictionary to the data argument. Your dictionary of data will automatically be form-encoded when the request is made
So now I have:
postContent = requests.post(url, data = params, cookies = previousResponse.cookies)
Now postContent.status_code == 500. The stack trace says the data is invalid at the root level. I will look into it.

How to Post a JSON and an Image to WCF (Using Content-type: application/JSON)

I am trying to post an Image with JSON object to wcf service in a Request.
Also i need to have Contant-Type: application/json on the request. How can i do that?
Can anyone please show me how the request will look like and also how do i receive in WCF.
Currently i am receiving like that-
And sending request like-
I would like to be able to do something like that-
Any suggestion or link or code would be appreciated.
Thanks
Just convert image binary data to base64 and send it as a regular field:
var imageBin = new byte[]{}; // need image data here
var base64Img = Convert.ToBase64String(imageBin);
var json =
#"{
'someData' : 'someValue',
'image' : '" + base64Img + #"'
}";

Categories