I would need some help for a string conversion from unicode (\u03a9\u039c\u0395\u0393\u0391) to normal string (ΩΜΕΓΑ).
I made a function that theoretically should work but it doesn't work instead. I don't understand what I'm doing wrong.
I receive json data with webclient.DownloadString:
{"id": "94401626335", "username": "\u03a9\u039c\u0395\u0393\u0391"}
I get the \u03a9\u039c\u0395\u0393\u0391 and send it to the function:
DecodeFromUtf8(username)
public string DecodeFromUtf8(string utf8String)
{
try
{
var output = WebUtility.HtmlDecode(utf8String);
return output;
}
catch (Exception ex)
{
return utf8String;
}
}
the function always returns me: \u03a9\u039c\u0395\u0393\u0391
and not: ΩΜΕΓΑ
Why?
i can't use external libraries like system.text.json
Thanks
use a json deserializer , let it do the work
public class Ooo {
public string id { get; set; }
public string username { get; set; }
}
var json = #"{""id"": ""94401626335"", ""username"": ""\u03a9\u039c\u0395\u0393\u0391""}";
var ooo = System.Text.Json.JsonSerializer.Deserialize<Ooo>(json) ;
Console.WriteLine("string = " + ooo.username);
}
gives (my console has a glyph misssing, but its show correctly in the debugger)
Related
I'm doing C# JSON <-> PHP JSON for the first time.
Thought I'd get on an easy road but seems like I've hit the rock.
I'm fairly sure that JSON from Newtonsoft allows "[" character but not sure why i have this error instead?
Here's my C# code:
public class SystemJSON
{
public bool Status { get; set; }
public string Message { get; set; }
public string ResponseData { get; set; }
}
public static class SystemCall
{
public static String Post(string uri, NameValueCollection pairs)
{
byte[] response = null;
using (WebClient wc = new WebClient())
{
response = wc.UploadValues(uri, pairs);
}
return Encoding.Default.GetString(response);
}
}
string system_Response = SystemCall.Post("http://127.0.0.1:8080/edsa-NEFS%20(PHP)/api.php", new NameValueCollection()
{
{"do_work", Functions.Get_Department_List.ToString()},
{"api_data", null }
});
**SystemJSON systemJSON = JsonConvert.DeserializeObject<SystemJSON>(system_Response);** //<-- Error happens here.
if(systemJSON.Status == true)
{
//do stuff here
}else
{
MessageBox.Show(this, systemJSON.Message, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
And here's my PHP code:
<?php
// Load Request
$function_name = isset($_POST['do_work']) ? $_POST['do_work'] : '';
$api_data = isset($_POST['api_data']) ? $_POST['api_data'] : '';
// Validate Request
if (empty($function_name))
{
SystemResponse(false, 'Invalid Request');
}
if (!function_exists($function_name))
{
SystemResponse(false, 'API Method Not Implemented');
}
// Call API Method
call_user_func($function_name, $api_data);
/* Helper Function */
function SystemResponse($responseStatus, $responseMessage, $responseData = '')
{
exit(json_encode(array(
'Status' => $responseStatus,
'Message' => $responseMessage,
'ResponseData' => $responseData
)));
}
/* API Methods */
function Get_Department_List($api_data)
{
//Test ------------------------------------------START
$node = array();
$dept = array();
$responseData = array();
$dept['id'] = 1;
$dept['name'] = "General";
$dept['description'] = "Forms, Samples, Templates, Catalogs, etc";
$dept['status'] = 1;
array_push($node, $dept);
$dept['id'] = 2;
$dept['name'] = "Test";
$dept['description'] = "Testing";
$dept['status'] = 1;
array_push($node, $dept);
$responseData["dept"] = $dept;
SystemResponse(true, 'SUCCESS', $responseData);
//Test ------------------------------------------END
}
?>
And here's my error:
Newtonsoft.Json.JsonReaderException HResult=0x80131500
Message=Unexpected character encountered while parsing value: {. Path
'ResponseData', line 1, position 51.
The problem is that your C# SystemJSON class does not match the structure of the incoming JSON correctly.
ResponseData in your C# SystemJSON class is listed as a string but your PHP appears to be pushing out a complex object inside that property. You can't deserialise an object into a string - there is no way for the deserialiser to know how to translate the object structure into a suitable string, and anyway it's not generally a useful or logical thing to do. So instead it throws an error to say the object structure doesn't match.
The specific error you're seeing means the deserialiser is expecting a " to denote the start of a string but instead it's seeing { denoting the start of another object.
Why is this happening? Well, your PHP code will produce a JSON response which looks like this:
{
"Status": true,
"Message": "SUCCESS",
"ResponseData": {
"dept": {
"id": 2,
"name": "Test",
"description": "Testing",
"status": 1
}
}
}
Live demo here
As you can see, ResponseData contains an object, which has a "dept" which in turn is another object with four more properties.
To deserialise this properly, your SystemJSON class will need to be altered, and you'll also need two sub-classes to help it out:
public class SystemJSON
{
public bool Status { get; set; }
public string Message { get; set; }
public ResponseData ResponseData { get; set; }
}
public class ResponseData {
public Department dept {get; set; }
}
public class Department {
public string id {get; set; }
public string description {get; set; }
public int status {get; set; }
}
You will now be able to deserialise the JSON correctly. Here is a live demo of the deserialisation.
P.S the [ character appears to be irrelevant here...it's unclear why you referred to that in your question.
P.P.S. From looking at your PHP I'm guessing that you may be intending to return different data structures in ResponseData depending on which parameter was specified for do_work - i.e. depending on which PHP function is called. If so then you'll need to amend your C# accordingly so that it deserialises to a different concrete class depending on which API method it requests. Or you could possibly cheat and specify ResponseData as dynamic, which will then accept any data structure it received, albeit with the caveat that it's now effectively loosely-typed and so you lose certain benefits when compiling the code such as checking for valid usage of property names, data types etc.
I am trying to get some currency values from an api. it's returning the data in the following format:
{"PKR_PKR":{"val":1}}
I want to show this value in textbox but there's an error
"Object reference not set to an instance of object".
I've tried the following code:
try
{
string endPoint = #"http:urlhere";
string ResultJson = "";
using (WebClient wc = new WebClient())
{
ResultJson = wc.DownloadString(endPoint);
}
JsonData values = JsonConvert.DeserializeObject<JsonData>(ResultJson);
txtBalanceRate.Text = values.CurrencyValue.ToString();
}
catch (Exception ex) { }
Class code:
class JsonData
{
public object CurrencyValue { get; set; }
}
**
UPDATE
**
Note: I can not update PKR_PKR Class becuase every time the name of variable is different for different currencies i.e. it can be USD_PKR , EUR_PKR etc
How can I resolve this?
FOLLOWING IS THE UPDATED CODE:
try
{
string endPoint = #"http://free.currencyconverterapi.com/api/v5/convert?q="+ddlCurrency.SelectedValue.ToString()+"_PKR&compact=y";
string ResultJson = "";
using (WebClient wc = new WebClient())
{
ResultJson = wc.DownloadString(endPoint);
}
RootObject rootObject = JsonConvert.DeserializeObject<RootObject>(ResultJson);
txtBalanceRate.Text = rootObject.PKR_PKR.val.ToString();
}
catch (Exception ex)
{
}
public class PKRPKR
{
public int val { get; set; }
}
public class RootObject
{
public PKRPKR PKR_PKR { get; set; }
}
If you are going to have dynamic object then you should try this out
dynamic data = Newtonsoft.Json.JsonConvert.DeserializeObject(json);
Type typeOfDynamic = data.GetType();
if( typeOfDynamic.GetProperties().Where(p => p.Name.Equals("PKR_PKR")).Any())
{
console.WriteLine(data.PKR_PKR.val);
}
else if( typeOfDynamic.GetProperties().Where(p => p.Name.Equals("USD_PKR")).Any())
{
console.WriteLine(data.USD_PKR.val);
}
else if( typeOfDynamic.GetProperties().Where(p => p.Name.Equals("EUR_PKR")).Any())
{
console.WriteLine(data.EUR_PKR.val);
}
above way is not tried and tested but you can have try like this as you json is dynamic.
Above way is checking property exist or not and get val from dynamci object
Your class structure is incorrect can you please try below class structure
public class PKRPKR
{
public int val { get; set; }
}
public class RootObject
{
public PKRPKR PKR_PKR { get; set; }
}
RootObject rootObject = JsonConvert.DeserializeObject<RootObject>(json);
Console.WriteLine(rootObject.PKR_PKR.val);
Mostly if you see above class structure , you josn each node is represent as class, but I dont go in much detail as Visual studio can do it for me.
When comes to json to object conversion ,I make use of utility provided by Visual studio. which does conversion of json string to proper class structure. here is image of it
Read how to do it full here :
Visual Studio Generate Class From JSON or XML
If you dont have visual studio with this feature you can use this online utility : json2csharp
Note: I can not update PKR_PKR Class becuase evert time the name of
variable is different for different currencies i.e. it can be USD_PKR
, EUR_PKR etc How can I resolve this?
SOLUTION
if json string {"PKR_PKR":{"val":1}} is fixed in your case, you can use following solution for any currency name you got.
static void Main(string[] args)
{
string json1 = "{ \"PKR_PKR\":{ \"val\":1}}";
string json2 = "{ \"USD_PKR\":{ \"val\":2}}";
string json3 = "{ \"EUR_PKR\":{ \"val\":3}}";
JToken token1 = (JToken)JsonConvert.DeserializeObject(json1);
Console.WriteLine(token1.First().First()["val"]);
JToken token2 = (JToken)JsonConvert.DeserializeObject(json2);
Console.WriteLine(token2.First().First()["val"]);
JToken token3 = (JToken)JsonConvert.DeserializeObject(json3);
Console.WriteLine(token3.First().First()["val"]);
Console.ReadLine();
}
I think your receiving object should contain a dictionary, not a single string:
Check this
Or you have to improve your object structure implementing a root item which contains a PKR_PKR sub object
I have the following working controller method, which returns the JSON in a simple text format.
[HttpPost]
public IActionResult DecodeBarcode(string productCodeScheme, string productCode, string serialNumber, string batch, string expirationDate, int commandStatusCode) {
string TextAreaResult = string.Empty;
try {
TextAreaResult = string.Format("{0} {1} {2}", request.getHttpInformation(), request.getHttpWarning(), request.getHttpResponseCode());
} catch (Exception exc) {
TextAreaResult = "Exception: " + exc.Message;
}
return Json(TextAreaResult);
}
The output after the above method is run looks something like
"The pack is active No warning 200"
whereas
request.getHttpInformation() is The pack is active
request.getHttpWarning() is No warning
request.getHttpResponseCode() is 200
Now, I am trying to split the response into 3 different key-value pairs so that my response will look like
{
httpInformation: "The pack is active",
httpWarning: "No Warning",
httpResponseCode: "200"
}
How do I pass the additional params in return Json(TextAreaResult) call?
If I do like the following it won't work
[HttpPost]
public IActionResult DecodeBarcode(string productCodeScheme, string productCode, string serialNumber, string batch, string expirationDate, int commandStatusCode) {
string TextAreaResult = string.Empty;
string TextAreaResultHttpInformation = string.Empty;
string TextAreaResultHttpWarning = string.Empty;
string TextAreaResultHttpResponseCode = string.Empty;
try {
TextAreaResultHttpInformation = string.Format("{0}}", request.getHttpInformation());
TextAreaResultHttpWarning = string.Format("{1}}", request.getHttpWarning());
TextAreaResultHttpResponseCode = string.Format("{2}}", request.getHttpResponseCode());
} catch (Exception exc) {
TextAreaResult = "Exception: " + exc.Message;
}
return Json(TextAreaResultHttpInformation, TextAreaResultHttpInformation, TextAreaResultHttpResponseCode);
}
How do I construct the key-value pairs and return as JSON? Perhaps, Json method is not the right choice over here, but being new to C#, I am not aware of any other c# inbuilt methods for constructing JSON
Assuming you actually want to consume the response as JSON, you could achieve this by doing
return Json(new
{
HttpInformation = TextAreaResultHttpInformation,
HttpWarning = TextAreaResultHttpWarning,
StatusCode = TextAreaResultHttpResponseCode
});
You can make wrapper class for these properties and return it.
public class BarcodeResultDto
{
[JsonProperty("httpInformation")]
public string HttpInformation { get; set; }
[JsonProperty("httpWarning")]
public string HttpWarning { get; set; }
[JsonProperty("httpResponseCode")]
public int GetHttpResponseCode { get; set; }
}
public IActionResult DecodeBarcode(string productCodeScheme, string productCode, string serialNumber,
string batch, string expirationDate, int commandStatusCode)
{
var barcodeResult = new BarcodeResultDto
{
GetHttpResponseCode = 200,
HttpInformation = "The pack is active",
HttpWarning = "No Warning"
};
// your code here
return Ok(barcodeResult);
}
Or you can change retuned value from IActionResult to JsonResult
If you want a different approach then you can use JsonSerializer in the following way :
// Creating BlogSites object
BlogSites bsObj = new BlogSites()
{
Name = "test-name",
Description = "test-description"
};
// Serializing object to json data
JavaScriptSerializer js = new JavaScriptSerializer();
string jsonData = js.Serialize(bsObj); // {"Name":"test-name","Description":"test-description"}
You will just need to create a class and store value in its objects then serialize it. If you have a list then you can use List of that class and then serialize.
I am posting to an API that may return either 1 of the following 2 formats of JSON strings:
{
"MessageType": 6,
"Message": "Unable to SAVE new record. Invalid posted data."
}
or
{
"Model": {
"Id": "1-6Q0RZ9",
...
},
"ResponseResult": {
"MessageType": 10,
"Message": "Successfully saved, Record Id = 1-6Q0RZ9"
}
}
I need to retrieve the results from MessageType and have tried every if condition I can think of to read the results, because the syntax or retrieving the key:value is different for each JSON string, and there are no other flags to trigger one or the other. So the code I used is:
string result = eml.PostData("API/Save", dataJSON.ToString());
var returnresult = new JavaScriptSerializer().Deserialize<dynamic>(result);
try {
var responseresults = returnresult["ResponseResult"];
rr = responseresults["MessageType"];
rrtxt = responseresults["Message"];
} catch (Exception ex) {
rr = returnresult["MessageType"];
rrtxt = returnresult["Message"];
}
Which works great. If there is a valid Db post it returns the second JSON which is parsed correctly by the TRY statement, if not it throws a "key not found" error and parses the returned string in the CATCH statement (the first JSON example). Obviously this is horrible code but I cannot think of another way to do this, and I was wondering if anyone had suggestions? (please?)
Thanx in advance.
How about deserializing the response to an object with all of the properties on each return type and then just checking the values?
public class ReturnObject
{
public YourModel Model {get;set;}
public ResultObject ResponseResult {get;set;}
public int? MessageType {get;set;}
public string Message {get;set;}
}
string result = eml.PostData("API/Save", dataJSON.ToString());
var returnresult = new JavaScriptSerializer().Deserialize<ReturnObject>(result);
{
if(returnresult.MessageType.HasValue)
{
var messageType = returnResult.MessageType.Value;
etc etc.
}
}
I am struggling with a subject that has a lot of variants in this forum but I can't seem to find one that suits me, and I think it's because of the way that my JSON array is :(
I'm not an expert but I already manage to "almost" get the end...
I need to get hand in "Success" and "Status" value. But also the different "Addresses".
My JSON (is called responseFromServer):
{
"success":true,
"addresses":
[
{"DPID":658584,"SourceDesc":"Postal\\Physical","FullAddress":"1/8 Jonas Street, Waimataitai, Timaru 7910"},
{"DPID":658585,"SourceDesc":"Postal\\Physical","FullAddress":"2/8 Jonas Street, Waimataitai, Timaru 7910"},
{"DPID":658583,"SourceDesc":"Postal\\Physical","FullAddress":"3/8 Jonas Street, Waimataitai, Timaru 7910"}
],
"status":"success"
}
Then, based on lot of examples in this forum, taking bits and pieces I created my classes:
public class jsonDataTable
{
public bool success { get; set; }
public IEnumerable<dtaddresses> addresses { get; set; }
public string status { get; set; }
}
public class dtaddresses
{
public int DPID { get; set; }
public string SourceDesc { get; set; }
public string FullAddress { get; set; }
}
Then I'm going to Deserialize:
public void _form_OnCallingAction(object sender, ActionEventArgs e)
{
...
...
JavaScriptSerializer js = new JavaScriptSerializer();
jsonDataTable jsonArray = js.Deserialize<jsonDataTable>(responseFromServer);
...
string tb = jsonArray.status.ToString();
string tb2 = jsonArray.success.ToString();
...
...
List<dtaddresses> _listAddresses = new List<dtaddresses>
{
new dtaddresses()
};
...
...
try
{
string tb3 = _listAddresses.Count.ToString();
string tb4 = _listAddresses[0].FullAddress;
}
catch (Exception ex)
{
CurrentContext.Message.Display(ex.Message + ex.StackTrace);
}
...
...
...
CurrentContext.Message.Display("Raw Response from server is: {0}", responseFromServer);
//Returns all the content in a string to check. OK! :)
CurrentContext.Message.Display("The success value is: {0} ", tb);
//Returns the Status Value (in this case "success") OK! :)
CurrentContext.Message.Display("The status value is: {0} ", tb2);
//Returns the Success Value (in this case "true") giggity giggity! All Right! :)
CurrentContext.Message.Display("The n. of addresses is: {0} ", tb3);
//Returns how many addresses ( in this case is returning 0) not ok... :(
CurrentContext.Message.Display("The address value is: {0} ", tb4);
// Returns the Fulladdress in index 0 (in this case nothing...) not ok... :(
Can any one help me to understand why I can access the values in the "dtaddresses" class?
This is the far that I went...
The following piece of code I copied from your question is creating a brand new list that has nothing to do with your deserialized data. Thus it's always going to be a single element list, where the first element contains only default values, which is what you are seeing in tb3 and tb4 later on.
List<dtaddresses> _listAddresses = new List<dtaddresses>
{
new dtaddresses()
};
Instead, assign jsonArray.addresses to _listAddresses, such as:
List<dtaddresses> _listAddresses = jsonArray.addresses.ToList()
Or you can forget about _listAddresses completely, and just simply reference jsonArray.addresses directly, such as:
string tb3 = jsonArray.addresses.Count().ToString();
string tb4 = jsonArray.addresses.First().FullAddress;