Parsing UTF8 encoded data from a Web Service - c#

I'm parsing the date from http://toutankharton.com/ws/localisations.php?l=75
As you can see, it's encoded (<name>Paris 2ème</name>).
My code is the following :
using (var reader = new StreamReader(stream, Encoding.UTF8))
{
var contents = reader.ReadToEnd();
XElement cities = XElement.Parse(contents);
var t = from city in cities.Descendants("city")
select new City
{
Name = city.Element("name").Value,
Insee = city.Element("ci").Value,
Code = city.Element("code").Value,
};
}
Isn't new StreamReader(stream, Encoding.UTF8) sufficient ?

That looks like something that happens if you take utf8-bytes and output them with a incompatible encoding like ISO8859-1. Do you know what the real character is? Going back, using ISO8859-1 to get a byte array, and UTF8 to read it, gives "è".
var input = "è";
var bytes = Encoding.GetEncoding("ISO8859-1").GetBytes(input);
var realString = Encoding.UTF8.GetString(bytes);

Related

Saving/Loading Json string to/from .dat

I am trying to learn how to save a json string in a .dat file, but I have trouble converting it back to the correct json string. My new string at the end starts with 2 special characters (rest of it is correct) and I am not sure why.
//Saving
string save = "a json string";
string path = #"E:\tempTest\MyTest.dat";
if (!File.Exists(path))
{
FileStream myFile = File.Create(path);
BinaryWriter binaryfile = new BinaryWriter(myFile);
binaryfile.Write(save);
binaryfile.Close();
myFile.Close();
}
//Loading
string path = #"E:\tempTest\MyTest.dat";
StreamReader objInput = new StreamReader(path, System.Text.Encoding.Default);
string contents = objInput.ReadToEnd().Trim();
string [] split = System.Text.RegularExpressions.Regex.Split(contents, "\\s+", RegexOptions.None);
StringBuilder sb = new StringBuilder();
foreach (string s in split)
{
sb.AppendLine(s);
}
string save = sb.ToString(); //string starts with 2 wrong special characters
I can obviously fix it with a simple save = save.Substring(2), but I would like to understand what the error was in my code (I guess the "\\s+" part of Regex is wrong).
Also, I am not exactly sure if this is still a good way of converting json to a data file and back. This example of how to do it, is from a 10 year old post I found online.
As posted in the comments, I should have used BinaryReader to read the file. This solved the problem.
//Loading
string path = #"E:\tempTest\MyTest.dat";
var stream = File.Open(path, FileMode.Open);
var reader = new BinaryReader(stream, Encoding.UTF8, false);
string save = reader.ReadString();
stream.Close();
reader.Close();

System.ArgumentNullException for Xamarin.Forms using StreamReader

In public ScenarioPage() of ScenarioPage.cs I have the following code to read from a json file:
var assembly = typeof(ScenarioPage).GetTypeInfo().Assembly;
Stream stream = assembly.GetManifestResourceStream("firstSession.json");
using (StreamReader reader = new StreamReader(stream)) // System.ArgumentNullException
{
var json = reader.ReadToEnd();
List<SessionModel> data = JsonConvert.DeserializeObject<List<SessionModel>>(json);
foreach(SessionModel scenario in data)
{
label.Text = scenario.title;
break;
};
}
I am getting an ArgumentNullException for the stream input. firstSession.json is in the same folder as ScenarioPage.cs, and it is set as an embedded resource. It seems like Visual Studio is not recognizing that my json file is there. Is this is a bug? Or is there something wrong with my code?
Where did you put the Json File, I put it in the Json File in the root Of PCL like following screenshot.
Then use following code to read the Json File.
void GetJsonData()
{
string jsonFileName = "firstSession.json";
ContactList ObjContactList = new ContactList();
var assembly = typeof(MainPage).GetTypeInfo().Assembly;
Stream stream = assembly.GetManifestResourceStream($"{assembly.GetName().Name}.{jsonFileName}");
using (var reader = new System.IO.StreamReader(stream))
{
var jsonString = reader.ReadToEnd();
//Converting JSON Array Objects into generic list
ObjContactList = JsonConvert.DeserializeObject<ContactList>(jsonString);
}
EmployeeView.ItemsSource = ObjContactList.contacts;
}
And here is running GIF.
I update my demo to you. you can test it
https://github.com/851265601/Xamarin.Android_ListviewSelect/blob/master/PlayMusicInBack.zip

.pkpass create fail because of manifest pass.json string format?

This is a very strange question.
I using C# to create a pass.json and save it to memoryStream, it work normally. After that I create the manifest.json SHA1 data which including that pass.json, the string of manifest.json like this and it is totally correct.
{"icon.png": "9423bd00e2b01c59a3265c38b5062fac7da0752d",
"icon#2x.png": "4d1db55bdaca70b685c013529a1c0dcbd7046524",
"logo.png": "ee5b053e63dbfe3b78378c15d163331d68a0ede8",
"logo#2x.png": "2f9e3a55bded1163620719a4d6c1ad496ed40c17",
"pass.json": "fd68bf77757d3057263a9aca0e5110ddd933934a"}
After generate pkpass as my phone, it can't open. I change the pass.json SHA1 code as "fd68bf77757d3057263a9aca0e5110ddd933934a" without using a value to save it, it work.
The coding like following:
// This version run success
var strPass = JavascriptSerialize(details);
var sw = new StreamWriter(assetsFolder + #"pass.json");
sw.Write(strPass);
sw.Close();
manifest.passjson = GetSha1Hash(assetsFolder + manifest.GetAssetBoardingPass(libPkPass_object_boardingPass.JsonObjects.AssetTypes.passjson));
//manifest.passjson = "2f9e3a55bded1163620719a4d6c1ad496ed40c17"
// end
// This version run fail
var strPass = JavascriptSerialize(details);
MemoryStream stream = new MemoryStream();
StreamWriter writer = new StreamWriter(strPass);
writer.Write(s);
writer.Flush();
stream.Position = 0;
var a = GetSha1HashMemory(passStream);
private static string GetSha1HashMemory(Stream passStream)
{
//var bs = new BufferedStream(passStream);
using (SHA1Managed sha = new SHA1Managed())
{
byte[] checksum = sha.ComputeHash(passStream);
string sendCheckSum = BitConverter.ToString(checksum)
.Replace("-", string.Empty);
return sendCheckSum.ToString().ToLower();
}
}
manifest.passjson = a;
//manifest.passjson = "2f9e3a55bded1163620719a4d6c1ad496ed40c17" (same data )
//end
What is going on?????? I can find out any question that string is wrong.
The pkpass provide in here (sendspace).
Can any body told me where is wrong?
Big Thank!
Two mistakes :
ComputeHash(Stream) and using Stream
ComputeHash(Stream) : ComputeHash stream only using System.IO.Stream, but not MemoryStream, change to ComputeHash(bytes[]) can handle it
using Stream: I try to pass the stream to other function, it is not a good example, the stream need to create a new one and it may replace some bytes at your computer stream. In this case, I just need to call this function will out open new one, it will fix
StringBuilder formatted;
using (var sha1 = new SHA1Managed())
{
//var bytePass = ReadFully(passStream);
var bytePass = passStream.ToArray();
var hash = sha1.ComputeHash(bytePass);
formatted = new StringBuilder(2 * hash.Length);
foreach (var b in hash)
{
formatted.AppendFormat("{0:X2}", b);
}
}
manifest.passjson = formatted.ToString().ToLower();

As3 bytearray to c# bytearray

I'm looking to convert this piece of code to c#:
var local1:ByteArray= new ByteArray();
var auth:String = root.loaderInfo.parameters.auth as String;
var key0:String = root.loaderInfo.parameters.key0 as String;
var key1:String = root.loaderInfo.parameters.key1 as String;
var key2:String = root.loaderInfo.parameters.key2 as String;
var key3:String = root.loaderInfo.parameters.key3 as String;
local1.writeUnsignedInt(parse(auth));
local1.writeUnsignedInt(parse(key0));
local1.writeUnsignedInt(parse(key1));
local1.writeUnsignedInt(parse(key2));
local1.writeUnsignedInt(parse(key3));
trace(local1)
You see how I directly print the byte array without converting it to a string. How can you do that in c#? Is suppose to print out something like this: TV˜ 3 R j i
If the array contains something that can be interpreted as character codes, then you can decode the bytes into text. For example:
string localText = Encoding.Default.GetString(local1);
The encoding to use would depend on how the text was converted to bytes in the first place.
You can use a MemoryStream and a BinaryWriter to put the integers in an array. Example:
string auth = "1"; // example data, would come from your object
string key0 = "2";
byte[] local1;
using (MemoryStream m = new MemoryStream()) {
using (BinaryWriter w = new BinaryWriter(m)) {
w.Write(Int32.Parse(auth));
w.Write(Int32.Parse(key0));
}
local1 = m.ToArray();
}
foreach(var g in local1)
{
Console.WriteLine((char)g);
}

JSON parsing trouble

WebClient client = new WebClient();
Stream stream = client.OpenRead(" some link ");
StreamReader reader = new StreamReader(stream);
Newtonsoft.Json.Linq.JObject jObject = Newtonsoft.Json.Linq.JObject.Parse(reader.ReadLine());
List<String> list = new List<string>();
//loading list
for (int i = 0; i < ((string)jObject["some_stream"][i]["some_channel"]["some_name"]).Count(); i++)
{
string result = ((string)jObject["some_streams"][i]["some_channel"]["some_name"]);
list.Insert(i, result);
}
stream.Close();
This code is working, but in json data I have 20+ results should be returned, but I only get 8.
What could be the cause?
you are counting the length of a string. at some point the length of that string is equal to or less than i (the 9th value of the string if you manage to iterate 8 times)
That is this piece of code
((string)jObject["some_stream"][i]["some_channel"]["some_name"]).Count()
returns the length of a string at location i so if you manage to iterate 8 times then the string at jObject["some_stream"][9]["some_channel"]["some_name"] has a length of 9 or less at which time the looping ends
From the usage it looks like jObject["Some_stream"] returns an array in that case what you could do is something like this:
var arr = (Treal[])jObject["Some_stream"];
var list = (from obj in arr
select ((string)obj["some_channel"]["some_name"])).ToList();
you will need to substitue TReal with the actual type of jObject["Some_stream"]
aside: when ever you are opening a stream it's a good idea to do this within a using statement. In your code the stream would not be closed in the case of an exception
the code would then be
WebClient client = new WebClient();
using(var stream = client.OpenRead(" some link ")) {
reader = new StreamReader(stream);
var jObject = Newtonsoft.Json.Linq.JObject.Parse(reader.ReadLine());
var arr = (Treal[])jObject["Some_stream"];
var list = (from obj in arr
select ((string)obj["some_channel"]["some_name"])).ToList();
}

Categories

Resources