Encoding/decoding issue with Facebook json messages. C# parsing - c#

I've download json with my conversations archive. I stuck with odd encoding.
Example of json:
{
"sender_name": "Micha\u00c5\u0082",
"timestamp": 1411741499,
"content": "b\u00c4\u0099d\u00c4\u0099",
"type": "Generic"
},
It should be something like this:
{
"sender_name": "Michał",
"timestamp": 1411741499,
"content": "będę",
"type": "Generic"
},
I'm trying to deserialize it like this:
var result = File.ReadAllText(jsonPath, encodingIn);
JavaScriptSerializer serializer = new JavaScriptSerializer();
serializer.MaxJsonLength = Int32.MaxValue;
var conversation = serializer.Deserialize<Conversation>(System.Net.WebUtility.HtmlDecode(result));
Unfortunately the output is like this:
{
"sender_name": "MichaÅ\u0082",
"timestamp": 1411741499,
"content": "bÄ\u0099dÄ\u0099",
"type": "Generic"
},
Anyone know how Facebook encoding the json? I've tried several methods but without results.
Thanks for your help.

Here is the answer:
private string DecodeString(string text)
{
Encoding targetEncoding = Encoding.GetEncoding("ISO-8859-1");
var unescapeText = System.Text.RegularExpressions.Regex.Unescape(text);
return Encoding.UTF8.GetString(targetEncoding.GetBytes(unescapeText));
}
I've collect all answers, mixed them and here we are. Thank you.

Related

How to access Json (which was a result of HttpMessage) in C#?

I am writing two applications (Web API's) in .NET . From the app A I want to call a method in Controller of app B using Http Request.
Here
using (var askPensionerDetails = new HttpClient())
{
double pensionToDisburse = 0;
askPensionerDetails.BaseAddress = new Uri("http://localhost:55345/api/pensionerdetails/");
var responseTask = askPensionerDetails.GetAsync("getById?pan=" + inputOfPensioner.PAN);
responseTask.Wait();
var result =responseTask.Result ;
if (result.IsSuccessStatusCode)
{
var readTask = result.Content.ReadFromJsonAsync<object>();
readTask.Wait();
return Ok(readTask.Result);
}
}
The output for this in postman is
{
"name": "bunk seenu",
"dateOfBirth": "1990-01-02T00:00:00",
"pan": "ABCD12351E",
"salaryEarned": 45000,
"allowances": 500,
"pensionType": 1,
"bankDetails": {
"bankName": "SBI",
"accountNumber": "SBI00001BS",
"bankType": 0
}
}
That was a desired output. But the problem is how to access the properties like bankdetails,name,pan,salaryEarned.
I have tried using readTask.Result["name"] but it is throwing error.
I have also tried using result.Content.ReadAsStringASync();
But the output in postman is
{
"name": [],
"dateOfBirth": [],
"pan": [],
"salaryEarned": [],
"allowances": [],
"pensionType": [],
"bankDetails": [
[
[]
],
[
[]
],
[
[]
]
]
}
I don't have class associated with the result type of Json for statement readTask = result.Content.ReadFromJsonAsync(); (As per design constraints).
From the docs:
If you have JSON that you want to deserialize, and you don't have the class to deserialize it into, you have options other than manually creating the class that you need:
Deserialize into a JSON DOM (document object model) and extract what you need from the DOM.
The DOM lets you navigate to a subsection of a JSON payload and deserialize a single value, a custom type, or an array. For information about the JsonNode DOM in .NET 6, see Deserialize subsections of a JSON payload. For information about the JsonDocument DOM, see How to search a JsonDocument and JsonElement for sub-elements.
Use the Utf8JsonReader directly.
Use Visual Studio 2019 to automatically generate the class you need:
Copy the JSON that you need to deserialize.
Create a class file and delete the template code.
Choose Edit > Paste Special > Paste JSON as Classes. The result is a class that you can use for your deserialization target.
You can use Newtonsoft.Json
JObject jo = JObject.Parse(readTask.Result);
var name = jo["name"];
if(string.IsNnullOrEmpty(name)){
///some code
}

Parsing JSON Using Newtonsoft.Json Without Knowing the Structure

I'm working on a project that involves automating API calls using a Swagger Definition. I download the swagger.json file. The structure of the JSON Object I need to parse is not consistent. When parsing paths, there are a list of objects, then within that they have the methods that can be used for that specific path. I can retrieve just the path using various string methods but my question was, is there a good way to parse json if the JSON is structured in such a way that it does not have a firm key? Here is an example of what I mean:
{"/user": {
"post": {
"tags": [
"user"
],
"summary": "Create user",
"description": "This can only be done by the logged in user.",
"operationId": "createUser",
"consumes": [
"application/json"
],
"produces": [
"application/json",
"application/xml"
],
"parameters": [
{
"in": "body",
"name": "body",
"description": "Created user object",
"required": true,
"schema": {
"$ref": "#/definitions/User"
}
}
],
"responses": {
"default": {
"description": "successful operation"
}
}
}
}
If I wanted to just parse that path and retrieve the method object how could I go about that considering sometimes the object will be "post" or sometimes it will be "get", "put", etc depending on what is allowable for the path.
JObject jsonResp = swaggerDownload();
JObject paths = (JObject)jsonResp["paths"];
foreach (var i in paths)
{
string pathToString = i.ToString();
var shaveSomethings = pathToString.Substring(1, something.Length - 2);
var pathAndJson = shaveSomethings.Split(new[] { ',' }, 2);
string correctJsonStructure = "{\"" + pathAndJson[0] + "\":" + pathAndJson[1] + "}";
JObject bd = JObject.Parse(correctJsonStructure);
//dynamic pathsTest = JsonConvert.DeserializeObject<dynamic>(correctJsonStructure);
//JObject result = JsonConvert.DeserializeObject<JObject>(correctJsonStructure);
//Console.WriteLine(bd["/user"]);
}
The swagger.json file should have full definition of each entity that endpoints return. You can follow How to create Rest API client to get a working client.
I've dealt with an API where responses didn't always match the definition. I saved all responses to a store/log first and then would try to de-serialize JSON. In case of an exception I would go back to store/log and see what was different and update my code to accommodate for the change. After few iterations there were no new changes and the ordeal was over.
Hope that helps.

Converting a string to a JSON for a HTTP POST request

I'm trying to return a json file from a HTTP POST request from Slack. I am using netcoreapp3.1 along with the Newtonsoft.Json NuGet. Right now my HTTP POST function looks like this.
public async Task<ActionResult> SlashCommand([FromForm] SlackSlashCommand request)
{
var retVal = new JsonResult(GetBlock());
return retVal;
}
GetBlock() is a function that returns a class that I created. This works currently, but everytime I want to modify the json that it returns, I have to modify that class. I would really love to just have a json in string format that I can copy and paste into my code and then return to Slack in json format.
Is there a way to do this? I've been trying to use JsonConvert.DeserializeObject(str); but I'm using it incorrectly. From what I understand, that function takes in an string and converts it to an object. I need to take in a string and convert it to a Microsoft.AspNetCore.Mvc.ActionResult json.
Any help? Thanks.
An alternative option is to use an anonymous type, which will be less vulnerable to becoming invalid JSON (a simple typo in your JSON string could render the entire block of JSON unreadable):
var data = new
{
blocks = new object[] {
new {
type = "section",
text = new {
type = "plain_text",
text = "Hello!",
emoji = true
}
},
new {
type = "divider"
},
new {
type = "actions",
elements = new object[] {
new {
type = "button",
text = new {
type = "plain_text",
text = "Help"
},
value = "helpButton"
}
}
}
}
};
return new JsonResult(data);
Produces:
{
"blocks": [
{
"type": "section",
"text":
{
"type": "plain_text",
"text": "Hello!",
"emoji": true
}
},
{
"type": "divider"
},
{
"type": "actions",
"elements": [
{
"type": "button",
"text":
{
"type": "plain_text",
"text": "help"
},
"value": "helpButton"
}
]
}
]
}
Try it online
I found an answer.
This is my JSON in string format:
string str = "{\"blocks\": [{\"type\": \"section\",\"text\": {\"type\": \"plain_text\",\"text\": \"Hello!\",\"emoji\": true}},{\"type\": \"divider\"},{\"type\": \"actions\",\"elements\": [{\"type\": \"button\",\"text\": {\"type\": \"plain_text\",\"text\": \"Help\"},\"value\": \"helpButton\"}]}]}";
And then this is my function:
public async Task<ActionResult> SlashCommand([FromForm] SlackSlashCommand request)
{
var retVal = new JsonResult(JsonConvert.DeserializeObject<object>(str));
return retVal;
}
This works quite well. Sorry if I didn't give too much info.

Deserialize JSON response with unknown object names using c# ReadObject()

So i'm trying to deserialise a JSON response implicitly back into a object instance using the following code.
DataContractJsonSerializer jsonSerialiser = new DataContractJsonSerializer(responseType);
responseBase = jsonSerialiser.ReadObject(responseStream);
The response if piped out as a string looks as follows
{
"20170317112739": {
"start": {
"SQ": 4577,
"TS": "2017-03-17T11:26:59",
"FisCode": "_R1-AT1_001/1_SQ4577_2017-03-17T11:26:59_0,00_0,00_0,00_0,00_0,00_vr1zl86Y_49e862eb_rNvvLM3FKh4=_DGZt+z+A3fY8zLlt2E55R8zCD/wf7yw9q/VivAiaNtxNpaTkhlTONAsD6yc+8Vcxwnm/lBalIwEI6GswC04kqg=="
},
"close": {
"SQ": 4667,
"TS": "2017-03-17T11:27:39",
"FisCode": "_R1-AT1_001/1_SQ4667_2017-03-17T11:27:16_0,00_0,00_0,00_0,00_0,00_r/82sV+w_49e862eb_FD/gDnivnes=_LKmvkk5OEoL7EFIebQU73VDVfPGzRGOyKNLlIW1mJkvPpqS0oVdWmqiNGR0cnpT35ArF++XzO1D/q7keTJe4cA=="
}
},
"current": {
"start": {
"SQ": 4670,
"TS": "2017-03-17T11:27:39",
"FisCode": "_R1-AT1_0/1_SQ4670_2017-03-17T11:27:39_0,00_0,00_0,00_0,00_0,00_/agx6rsw_49e862eb_qTh1/lCawvo=_f7yNP/+WUWZCojerZ9fe/wID1gll0I37swEKsauV8h7g8gSCFZ2Ykg45JjkO7BrChCBkl0ewohuGdbP4haLbrQ=="
},
"2017-03": {
"SQ": 4673,
"TS": "2017-03-17T11:27:39",
"FisCode": "_R1-AT1_0/1_SQ4670_2017-03-17T11:27:39_0,00_0,00_0,00_0,00_0,00_/agx6rsw_49e862eb_qTh1/lCawvo=_f7yNP/+WUWZCojerZ9fe/wID1gll0I37swEKsauV8h7g8gSCFZ2Ykg45JjkO7BrChCBkl0ewohuGdbP4haLbrQ=="
}
},
"lic": "0SvXs"
}
Simple responses from the JSON service are no problem i can simply decorate these with [DataContract] and [DataMember].
The problem with this particular service response is that item names such as "2017-03" will change depending on when the call is made to during other months/years.
How do i deal with this in C#?, can someone supply an example of how my class should look?
For the life of me i cannot get this data into my object class!
You can have a dynamic dictionary as suggested in this post Deserialize JSON into C# dynamic object?
Or you can implement something like this with the help of System.Web.Helpers
using (StreamReader r = new StreamReader("sample.json"))
{
string json = r.ReadToEnd();
dynamic data = Json.Decode(json);
Console.WriteLine(data["20170317112739"].start.sq);
}
Here sample.json contains your sample JSON response.

How to parse JSON data

Can anyone tell me how I can parse this data in WCF Service with C#?
{"syncresp": {
"synchdr": {
"sessionref": "1234567890"
"syncref": "20110327T012000"
},
"syncbody": {
"syncedrecs": [
{
"recloc": "plog,0,123",
},
{
"recloc": "plog,0,123",
}
],
"serverdata": [
{
"table": " book",
"action": "new",
"recdata": {
"pnum": "67890",
"fname": "ghgfhn"
"lname": "M"
.
.
.
},
},
{
"table": "pins",
"action": "new",
"recdata": {
"patid": 123,
"insprovid": 5,
"insnum": "X34567",
"effdate": "6/3/2011",
"expdate": "5/3/2012",
"status": "a",
},
},
]
}
}}
If you want to create a data contract which can be used in WCF to consume / generate this kind of data, then take a look at http://blogs.msdn.com/b/carlosfigueira/archive/2011/01/11/inferring-schemas-for-json.aspx - it has a tool which "infers" the corresponding classes which can be used, with the DataContractJsonSerializer, to serialize / deserialize your example.
This is quite simple question, so read some manuals before asking such questions.
First search result in google:
http://blah.winsmarts.com/2009-12-How_to_parse_JSON_from_C-.aspx
JavaScriptSerializer jSerialize = new JavaScriptSerializer();
BusinessObjectType businessObject = jSerialize.Deserialize<BusinessObjectType>(configuration);

Categories

Resources