"Unexpected character encountered" with Newtonsoft.Json reading GCP auth file - c#

I'm trying to get a local c# program that I have to connect to GCP (Bigquery).
I have gotten a credentials json file from GCP which looks something like:
{
"type": "service_account",
"project_id": "project-id-1",
"private_key_id": "veryprivatekeything",
"private_key": "-----BEGIN PRIVATE KEY-----\nmany_letters_and_symbols_here\n-----END PRIVATE KEY-----\n",
"client_email": "bq-access-for-test#project-id-1.iam.gserviceaccount.com",
"client_id": "1234567891011",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/bq-access-for-test%40project-id-1.iam.gserviceaccount.com"
}
My code looks something like:
string path2key = "C:/Users/me/Downloads/project-id-1-letters.json";
byte[] jsonBytes = File.ReadAllBytes(path2key);
// I also tried another encoding but same deal
// string jsonString = Encoding.UTF32.GetString(jsonBytes);
string jsonString = File.ReadAllText(path2key);
Console.WriteLine(jsonString);
// This is where the error is
string jsonStringDeserialized = JsonConvert.DeserializeObject<string>(jsonString);
Console.WriteLine(jsonStringDeserialized);
// I presume I'm passing json as a string???
var credential = GoogleCredential.FromJson(jsonStringDeserialized);
if (credential.IsCreateScopedRequired)
{
credential = credential.CreateScoped(new[]
{
BigqueryService.Scope.Bigquery
});
}
Console.WriteLine("Credentials Created");
var client = BigQueryClient.Create("projectId", credential);
Console.WriteLine("Client Created");
var table = client.GetTable("bigquery-public-data", "samples", "shakespeare");
var sql =
$" SELECT corpus AS title" +
$" , COUNT(word) AS unique_words " +
$" FROM {table} " +
$" GROUP BY title " +
$" ORDER BY unique_words DESC " +
$" LIMIT 10"
;
var results = client.ExecuteQuery(sql, parameters: null);
foreach (var row in results)
{
Console.WriteLine($"{row["title"]}: {row["unique_words"]}");
}
However when I get to the line that tries to deserialize the jsonString it complains that
Newtonsoft.Json.JsonReaderException: 'Unexpected character encountered while parsing value: {. Path '', line 1, position 1.'
I'm assuming the json isn't malformed as it was downloaded directly from GCP and I've checked with linters that it's valid.
What's the next thing I should be trying?

you don' t need this code, it doesn' t create anything , except the error
string jsonStringDeserialized = JsonConvert.DeserializeObject<string>(jsonString);
Console.WriteLine(jsonStringDeserialized);
try just this
string jsonString = File.ReadAllText(path2key);
var credential = GoogleCredential.FromJson(jsonString);
.... your code

Related

Get parts of a string - C# .NET Core 3.1

I have a string line from a log:
2020-09-07 14:41:17.268 +01:00 [Information] Hello, Serilog!
I would like to pull out the word Information from the string, however, this will change as it could be debug, or any other known logging level.
I would also like the message, which is one space after the ] which in this case is Hello, Serilog!. This is also subject to change but it wont be any longer than the existing message.
The string is coming from a StringReader
using (StringReader reader = new StringReader(message.ToString())) // message from StringWriter
{
var readText = reader.ReadLine();
Console.WriteLine(readText);
}
What is the best way to do this?
Using Regex will output Information: Hello, Serilog!
string type;
string message;
string text = "2020-09-07 14:41:17.268 +01:00 [Information] Hello, Serilog!";
string pattern = "\\[(.*?)\\]";
var match = Regex.Match(text, pattern);
if (match.Success)
{
type = match.Groups[1].Value;
message = text.Substring(match.Groups[1].Index + match.Groups[1].Length + 1);
Console.WriteLine(type + ": " + message);
}
You can use regular expression as follows:
var regex = new Regex("\\[([^\\]]+)\\]");
var match = regex.Match(readText);
if (match.Success)
{
var value = match.Groups[1].Value;
// value == "Information" or whatever between [ and ]
}
else
{
// Handle pattern not matching
}

Find element in json file

I have JSON file like below, and I want to find a specific string or list of strings in this file.
I need to know if the values are in this file:
{
"naglowek": {
"dataGenerowaniaDanych": "20200107",
"liczbaTransformacji": "5000",
"schemat": "RRRRMMDDNNNNNNNNNNBBBBBBBBBBBBBBBBBBBBBBBBBB, gdzie R to cyfra roku, M – miesiąca, D - dnia daty generowania pliku, N to cyfra NIPu, a B to cyfra rachunku bankowego"
},
"skrotyPodatnikowCzynnych": [
"0000023d01e60fa522c2535d37c93051bdb9bc74e31b824460cd743a66a5282abb45567e43f09cfb26cd454b75ee6d6b0dfa83ef26db33581510afa421c3d430",
"0000025fe2175d2639990a7918baf727c41bbf554b1a88b679e32f3dc460c4dc44454b6a98417c31c4f2ee9e1c705ff951a1d7601553b327ec380213f2186a0f",
"00000cd37d8ded5c477552f61b647bcf9e6a967036823b7515b1e01e7fe3fe1854c470fb30f56beef1bc80d83d7350a53fe8677cb932f4f251837a767e0f8d63",
"00000d939549219dd4cd795c9b9680a3e5147791b1ddc4148f3463d6b3aa22849bcc30729cc60fc1282977d52d635c70d353f450c2abaef22f7d22439ac7b6e6",
"00001df757bb678d654308b1137c7dc8381d0457043009f4fc63edab93b32f60e1f460375e7da6965dbfd58f447d173c4c6c42add0d3dac181816782cf297cd8",
"0000248aef22c8ebddebd272cdc03e023f1dca221a5c7a731ade2989f1996b00b440c7410d52b89ef6f7927608bed66ad42a230f8e2cf86b97037597640d1da0",
"00002c000cd48dc44e63fa56d314962ff16b08c2e135a4c5352261a8e1c6b6fed9fefa01f01494d554e3158039450811a727c32576656d80963ed7b81a3732e3",
"00003666894d6872169f1f5212ba30a7441580f90d115823ca2d9cb6c5aca6e58ce277943bb284dd52cd669e8f05adba8d406ea8fb81c3e26bfce46b1cf8f120",
"00003bb55a8f67914ff5553a42f2bf2c8456b4f5d1a140ffdb1069442122114c61ad7bcbc715b35862c9e4566a8ddfbe9d9ca25457daa4cda51cdd796252b770",
"000041debf38337bb23391ccc9624483370a4e2d63dc4634c4f7c8d9071e5337d65464e59feedebe082bb7cbf6bb0a132b92194be457c92b1111132a51c81dcf",
"00004c88c01bc05ed4aa0df33cdbbe41aa77d49f94a6c9ee35efe6a59eca5cdea735acff28f05fb3d960973227b27ec81444b9afe14323fd2fc53a991b42c6ce"]
}
I need to find in this file specific string (one of the hashes)
I tried this:
public bool FindInFile(string sha512, string filePath, string date)
{
JObject o1 = JObject.Parse(File.ReadAllText(filePath + date + ".json"));
// read JSON directly from a file
using (StreamReader file = File.OpenText(filePath + date + ".json"))
using (JsonTextReader reader = new JsonTextReader(file))
{
JObject o2 = (JObject)JToken.ReadFrom(reader);
IEnumerable<JToken> pricyProducts = o2.SelectTokens("[?($.skrotyPodatnikowCzynnych == " + sha512 + ")]");
}
return true;
}
This should do the trick
public bool FindInFile(string sha512, string filePath, string date)
{
var obj = JObject.Parse(File.ReadAllText(filePath + date + ".json"));
return obj["skrotyPodatnikowCzynnych"].Children().Values<string>().Contains(sha512);
}
if you are sure the file is a valid json and do not contain other fields, why bother parsing it ? just look for the strings in it...
Otherwise just use linq to see if the query you wrote yields Any result...
pricyProducts.Any()
If it does not return any results ever, just fix the query (which i think is wrong)...
https://www.newtonsoft.com/json/help/html/SelectToken.htm
o2.SelectTokens("[?($.skrotyPodatnikowCzynnych == " + sha512 + ")]")
probably should be
o2.SelectTokens("$.skrotyPodatnikowCzynnych[?(# == '" + sha512 + "')]"

How to send a POST in UWP c#

I need to send a POST method but it says invalid JSON content, do somebody knows what im doing wrong in the JSON format ¿?, ill apreciate a lot.
Uri resourceAddress;
if (!Helpers.TryGetUri(pcHost + pcPort + "/api/code/scan", out resourceAddress))
{
rootPage.NotifyUser("Invalid URI.", NotifyType.ErrorMessage);
return;
}
try
{
terminalRef = "1";
//code = "Uc0E17G4nW";
IHttpContent jsonContent = new HttpJsonContent(JsonValue.Parse("{\"code\":\"" + code +
",\"ref\" : \""+ terminalRef +
"\"}"));
HttpResponseMessage response = await httpClient.PostAsync(resourceAddress, jsonContent).AsTask(cts.Token);
Debug.WriteLine(".");
//await Helpers.DisplayTextResultAsync(response, cts.Token);
rootPage.NotifyUser("Completed", NotifyType.StatusMessage);
}
catch (Exception ex)
{
rootPage.NotifyUser("Error: " + ex.Message, NotifyType.ErrorMessage);
String errorMessage = ex.Message.ToString();
}
Noted that your string is not correctly formatted. Can you try the parsing below string,
"{\"code\" : \"" + code + "\", \"ref\" : \"" + terminalRef + "\"}"
The first way was as the Jaliya Udagedara's suggestion, you would need to check your json string's format to make sure that it's correct.
Another a simple way is using the Newtownsoft.Json to convert a c# object.
For example:
string jsonstring = JsonConvert.SerializeObject(new {code="code", Ref = "terminalRef" });
IHttpContent jsonContent = new HttpStringContent(jsonstring, Windows.Storage.Streams.UnicodeEncoding.Utf8, "application/json");
HttpResponseMessage response = await httpClient.PostAsync(resourceAddress, jsonContent).AsTask(cts.Token);
After multiple failures i found how to make it works ( at least for me) hope it can help people working with Windows 10 iot in Universal Windows Platform (UWP) i know how difficult can be to fin proper documentation.
Uri resourceAddress;
if (!Helpers.TryGetUri(Host + Port + "/XXX/YYY/directory", out resourceAddress))
{
return;
}
IHttpContent jsonContentCoordinates = new HttpJsonContent(JsonValue.Parse("{\"zzz\": \"" + something
+ "\", \"xxx\": \"" + somethingXXX
+ "\",\"yyy\": \"" + somethingYYY
+ "\" }"));
HttpResponseMessage httpResponseCoordinates = new HttpResponseMessage();
string httpResponseBodyCoordinates = "";
try
{
httpResponseCoordinates = await httpClient.PostAsync(resourceAddress, jsonContentCoordinates).AsTask(cts.Token);
httpResponseBodyCoordinates = await httpResponseCoordinates.Content.ReadAsStringAsync();
httpResponseCoordinates.EnsureSuccessStatusCode();
FlagInternetNotConnected = false;
}
catch (Exception)
{
//Catch it if it fails.
}

Extra character from WWW text (Compare with www.text not working)

I am programming a login system now on Unity, but I have this weird bug. For some reason when I get the output of the php file, the if statement in the C# file can't see that 'loginreturn' (= AccountDoesntExist) and the string "AccountDoesntExist" are the same. I don't know why but maybe you smart people see the bug and can help me out.
C# Code:
IEnumerator TryLogin(string username, string password)
{
WWWForm form = new WWWForm();
form.AddField("username", username);
form.AddField("password", password);
WWW loginWWW = new WWW(LoginURL, form);
yield return loginWWW;
if (!string.IsNullOrEmpty(loginWWW.error))
{
Debug.LogError("Cannot connect to LOGIN servers! Error: " + loginWWW.error);
}else
{
string loginreturn = loginWWW.text;
Debug.Log(loginWWW.text);
Debug.Log(loginreturn);
if (loginreturn == "AccountDoesntExist")
Debug.Log("WORKS!");
}
}
PHP Code (which will always return "AccountDoesntExist" because of the way I log in):
<?php
$inputusername = $_REQUEST["username"];
$password = $_REQUEST["password"];
$servername = "localhost";
$username = "chatsystem_accs";
$password = "CENCORED";
$dbname = "chatsystem_accs";
//Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
//Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
//Connected successfully
$sql = "SELECT `username`, `password` FROM `accounts`";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
while($row = $result->fetch_assoc()) {
if ($inputusername == $row["username"]) {
if (password_verify($password, $row["password"])) {
echo "Success";
}else {
echo "UsernameOrPasswordIncorrect";
}
}else {
echo "AccountDoesntExist";
}
}
}else {
echo "AccountDoesntExist";
}
//Close connection
$conn->close();
?>
Very likely a UTF-8 problem. There is an extra data in the received bytes. Convert the received data to UTF-8 before comparing it.
Replace
string loginreturn = loginWWW.text;
with
string loginreturn = System.Text.Encoding.UTF8.GetString(loginWWW.bytes, 3, loginWWW.bytes.Length - 3);
EDIT:
Did debugging like this:
Debug.Log("Received Length: "+ loginreturn.Length);
Debug.Log("Compare Length: " + "AccountDoesntExist".Length);
and the results were:
Received Length: 19
Compare Length: 18
This is wrong. There is an extra character somewhere.
Debugged again with the function below then called it with displayAsChar(loginreturn);
void displayAsChar(string badValue)
{
char[] values = badValue.ToCharArray();
for (int i = 0; i < values.Length; i++)
{
string tempResult = "Value at index " + i + " is: " + values[i];
Debug.Log(tempResult);
}
}
It shows there is an empty character at the end of the character. I thought that was just " " but it wasn't.
I made another function to see what this empty character is:
void showStringAsHex(string badValue)
{
foreach (char c in badValue)
Debug.Log("To Unicode: " + ((int)c).ToString("X2"));
}
Bingo. That last character is 0A (Hex) which is also represented as \n. This is used as a line feed.
FIX:
Before doing the compare action, trim the string. This will remove any escape character and empty strings in the beginning and end of the character.
To trim the character, simply add the code below before comparing the string.
loginreturn = loginreturn.Trim();
Why post the debugging process?
The characters might be different for different servers. Posting this will help others troubleshoot and fix this problem for them-selves in the future.

Bing Geocoding Help

I'm trying to use Bing's REST api to geocode. But my 'y' value is always null when I check my database. Any help would be appreciated.
private void Bing(geodata address)
{
try
{
string query;
//Create a new instance for holding geocoded data
currentdata newaddress = new currentdata();
newaddress.agency = address.agency;
newaddress.calltime = address.calltime;
newaddress.city = address.city;
newaddress.state = address.state;
newaddress.incidentType = address.incidentType;
newaddress.intersection = address.intersection.Replace("&", "and");
query = newaddress.intersection.ToString() + " " + newaddress.city.ToString() + " " + newaddress.state.ToString();
// query = query.Replace("&", "and");
//Geocoder returns data in XML format so we need to
//create a new instance of XMLTextReader and provide an url
XmlTextReader reader = new XmlTextReader
("http://dev.virtualearth.net/REST/v1/Locations/" + query + "?o=xml&key=MYBINGKEY");
//Specify the way how white space is handled
reader.WhitespaceHandling = WhitespaceHandling.Significant;
//Start reading geocoded data
while (reader.Read())
{
string node = reader.Name.ToString(); //current node in XML document
string value = reader.ReadString(); //value/inner text of current XML node
switch (node)
{
case "Name":
newaddress.intersection = value;
break;
case "Latitude":
newaddress.y = double.Parse(value);
break;
case "Longitude":
newaddress.x = double.Parse(value);
break;
default:
continue;
}
}
//Add geocoded address to our table
cD.currentdatas.InsertOnSubmit(newaddress);
cD.SubmitChanges();
}
catch
{
}
}
Does your location info contains a period (.), a comma (,), a colon (:) or a plus sign (+)? You should use the Unstructured URL syntax if this is the case. Info here:

Categories