UWP - writing to JSON without owerwrite data - json

I want to write data to JSON file, without overwriting them. I am using this code
Item test = new Item("test", 23);
try
{
var Folder = Windows.Storage.ApplicationData.Current.LocalFolder;
//var file = await Folder.CreateFileAsync("data.json", Windows.Storage.CreationCollisionOption.ReplaceExisting);
var file = await Folder.GetFileAsync("data.json");
var data = await file.OpenStreamForWriteAsync();
using (StreamWriter r = new StreamWriter(data))
{
var serelizedfile = JsonConvert.SerializeObject(test);
r.Write(serelizedfile);
}
}
catch (Exception a)
{
throw a;
}

Noticed that you're possibly using the Json.NET for serialization and deserialization the Json file. I think it's better to deserialize the list of Json object and you can operate on this list, then serialize the new list to Json and save into the file, not directly serialize one item and write it into the file.
For example, my Json file is like this:
[
{"color":"red","value":"#f00"},
{"color":"green","value":"#0f0"},
{"color":"blue","value":"#00f"},
{"color":"cyan","value":"#0ff"},
{"color":"magenta","value":"#f0f"},
{"color":"yellow","value":"#ff0"},
{"color":"black","value":"#000"}
]
code for adding one item to this file:
if (file != null)
{
using (var streamIn = await file.OpenAsync(FileAccessMode.ReadWrite))
{
DataReader reader = new DataReader(streamIn);
await reader.LoadAsync((uint)streamIn.Size);
var jsonInstring = reader.ReadString((uint)streamIn.Size);
var JobjList = JsonConvert.DeserializeObject<List<JsonColor>>(jsonInstring);
reader.Dispose();
JobjList.Add(new JsonColor() { color = "pink", value = "#c0c" });
JsonOutstring = JsonConvert.SerializeObject(JobjList);
}
using (var streamOut = await file.OpenAsync(FileAccessMode.ReadWrite))
{
DataWriter writer = new DataWriter(streamOut);
writer.WriteString(JsonOutstring);
await writer.StoreAsync();
writer.DetachStream();
writer.Dispose();
}
}
else
{
}
My class object:
public class JsonColor
{
public string color { get; set; }
public string value { get; set; }
}
As you can see, I deserialized the Json file and get the List<JsonColor>, then I added one item new JsonColor() { color = "pink", value = "#c0c" } to this list, and finally serialized this new list and save it. So for your scenario, you can modify the Json file and my JsonColor class to fit your need.
Update:
private string JsonOutstring;
private async void Button_Click(object sender, RoutedEventArgs e)
{
//create a json file, if the file is exit, then open it.
var local = Windows.Storage.ApplicationData.Current.LocalFolder;
var Jsonfile = await local.CreateFileAsync("test.json", Windows.Storage.CreationCollisionOption.OpenIfExists);
if (Jsonfile != null)
{
ReadAndWriteJsonFile(Jsonfile);
}
else
{
}
}
public async void ReadAndWriteJsonFile(StorageFile file)
{
using (var streamIn = await file.OpenAsync(FileAccessMode.ReadWrite))
{
DataReader reader = new DataReader(streamIn);
await reader.LoadAsync((uint)streamIn.Size);
var jsonInstring = reader.ReadString((uint)streamIn.Size);
var JobjList = JsonConvert.DeserializeObject<List<JsonColor>>(jsonInstring);
reader.Dispose();
if (JobjList == null)
{
JobjList = new List<JsonColor>();
}
JobjList.Add(new JsonColor() { color = "pink", value = "#c0c" });
JsonOutstring = JsonConvert.SerializeObject(JobjList);
}
using (var streamOut = await file.OpenAsync(FileAccessMode.ReadWrite))
{
DataWriter writer = new DataWriter(streamOut);
writer.WriteString(JsonOutstring);
await writer.StoreAsync();
writer.DetachStream();
writer.Dispose();
}
}
public class JsonColor
{
public string color { get; set; }
public string value { get; set; }
}

Related

how to get a specfic value form httpClient response in Razorpages

return await request.Content.ReadAsStringAsync();
This line of code returns me a response from API which is fine but I want a specific object only, how can i do that
using (var _client = new HttpClient())
{
try
{
var gettokenasyn = await GetTokenAsync();
//_client.DefaultRequestHeaders.Clear();
//_client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(gettokenasyn);
_client.DefaultRequestHeaders.Add("token", gettokenasyn);
var body = new StringContent(JsonConvert
.SerializeObject(payproModels), Encoding.UTF8, "application/json");
var request = await _client.PostAsync(endPointForOrder, body);
return await request.Content.ReadAsStringAsync();
}
catch (Exception exp)
{
return exp.Message;
}
}
You can parse the json string to a JsonDocument and then access the json properties.
Let's say you have this sample json response and you want to take the speed value:
{
"speed": 4,
"deg": 95,
"gust": 3.27
}
Then you can do:
var response = await _client.PostAsync(endPointForOrder, body);
var stream = await response.Content.ReadAsStreamAsync();
using (var jsonDocument = await JsonDocument.ParseAsync(stream))
{
JsonElement speed = jsonDocument.RootElement.GetProperty("speed");
return speed.GetDouble();
}
Alternative you can create a class and deserialize the json to an instance of that class:
public class Wind
{
public double Speed { get; set; }
public int Deg { get; set; }
public double Gust { get; set; }
}
.
var response = await _client.PostAsync(endPointForOrder, body);
var stream = await response.Content.ReadAsStreamAsync();
var wind = await JsonSerializer.DeserializeAsync<Wind>(stream);
return wind.Speed;
You also need to import System.Text.Json namespace:
using System.Text.Json;
https://learn.microsoft.com/en-us/dotnet/api/system.text.json?view=net-6.0

Using Newtonsoft JsonConverter to Encrypt JSON object

I'm developing a project that will require me to include credentials for things like an SMTP server. I'd like to store this information along with the complete details of the endpoint in an embedded JSON file, but I would like to have that information encrypted and then let my application decrypt it when it needs to establish a connection and log in. The JSON structure looks something like this:
{
"Endpoints" : [
{
"Endpoint" : {
"Host": "smtp.mydomain.tld",
"Port": 587,
"Username": "user#mydomain.tld",
"Password": "mYp#s$w0?d"
}
}
]
}
While what I'd really like to have actually stored in the file would look something like this:
{
"Endpoints" : [
{
"Endpoint" : "<BASE64_ENCODED_STRING>"
}
]
}
Using Newtonsoft's Json.NET, I've built the class object/properties to desriealize this structure:
<JsonProperty("Endpoints")>
Public Property Endpoints As List(Of EndpointContainer) = Nothing
Public Class EndpointContainer
<EditorBrowsable(EditorBrowsableState.Never)> <DebuggerBrowsable(DebuggerBrowsableState.Never)>
Private Const EncryptedPrefix As String = "myappcipher:"
<EditorBrowsable(EditorBrowsableState.Never)> <DebuggerBrowsable(DebuggerBrowsableState.Never)>
<JsonProperty("Endpoint")> <JsonConverter(GetType(EndpointProtector))>
Public Property Endpoint As Endpoint = Nothing
End Class
And I've built the inherited JsonConverter class ("EndpointProtector") like this:
Public Class EndpointProtector
Inherits JsonConverter
Public Sub New()
Using SHAEncryption = New SHA256Managed()
_EncryptionKey = SHAEncryption.ComputeHash(Encoding.UTF8.GetBytes(TestEncryptionKey))
End Using
End Sub
Public Overrides Sub WriteJson(writer As JsonWriter, value As Object, serializer As JsonSerializer)
Dim clearText As String = JsonConvert.SerializeObject(value)
If clearText Is Nothing Then
Throw New ArgumentNullException(NameOf(clearText))
End If
writer.WriteValue(EncryptEndpoint(clearText))
End Sub
Public Overrides Function ReadJson(reader As JsonReader, objectType As Type, existingValue As Object, serializer As JsonSerializer) As Object
Dim DecryptString As String = TryCast(reader.Value, String)
If String.IsNullOrEmpty(DecryptString) Then
Return reader.Value
ElseIf Not DecryptString.StartsWith(EncryptedPrefix, StringComparison.OrdinalIgnoreCase) Then
Return DecryptString
Else
Return DecryptEndpoint(DecryptString)
End If
End Function
Public Overrides Function CanConvert(objectType As Type) As Boolean
Throw New NotImplementedException()
End Function
End Class
Currently I have the JSON file itself with the full object definition (as in the first code block). When my application reads that JSON, it correctly moves to the overridden ReadJson() method I have, but the reader.Value is null (Nothing), so it never actually gets to the DecryptEndpoint() method. Of course, that means there's nothing to encrypt, so the application won't even step into the WriteJson() method.
I've tried a couple of variations, including making the Endpoint property into a private variable with a generic Object type, and then having a separate public property with the <JsonIgnore> decoration to "read" from that, but nothing seems to get me where I need to be. I'm sure I'm overlooking something here, but I can't seem to figure out why it's not getting anything at all.
I looked at a few other SO questions like Encrypt and JSON Serialize an object, but I've still not yet been able to figure out quite where I've gone wrong here.
NOTE: I intentionally didn't include the code for the EncryptEndpoint() or DecryptEndpoint() methods here simply because the code is never making it that far in the process. If you feel it's needed to fully answer the question, please let me know.
this is a linqpad example of working encrypt/decrypt base on JsonAttribute
void Main()
{
string str = "";
var t = new Test() { encName = "some long text some long text some long text", Name = "test" };
JsonSerializerSettings theJsonSerializerSettings = new JsonSerializerSettings();
theJsonSerializerSettings.TypeNameHandling = TypeNameHandling.None;
str = JsonConvert.SerializeObject(t, theJsonSerializerSettings).Dump();
JsonConvert.DeserializeObject<Test>(str, theJsonSerializerSettings).Dump();
}
public class Test
{
[JsonConverter(typeof(EncryptingJsonConverter))]
public string encName { get; set; }
public string Name { get; set; }
}
/// <summary>[JsonConverter(typeof(EncryptingJsonConverter), string 32byte array)]</summary>
public class EncryptingJsonConverter : JsonConverter
{
private readonly byte[] _encryptionKeyBytes;
private readonly string _encryptionKeyString;
///<summary>Key must be 32char length</summary>
public EncryptingJsonConverter()
{
string encryptionKey = "E546C8DF278CD5931069B522E695D4F2"; //get from config
if (string.IsNullOrEmpty(encryptionKey))
throw new ArgumentNullException(nameof(encryptionKey));
_encryptionKeyString = encryptionKey;
_encryptionKeyBytes = Convert.FromBase64String(encryptionKey);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var stringValue = (string)value;
if (string.IsNullOrEmpty(stringValue))
{
writer.WriteNull();
return;
}
//string enc = stringValue.Encrypt(_encryptionKeyString);
string enc = Crypto.Encrypt(stringValue, _encryptionKeyBytes);
writer.WriteValue(enc);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var value = reader.Value as string;
if (string.IsNullOrEmpty(value))
return reader.Value;
try
{
//return value.Decrypt(_encryptionKeyString);
return Crypto.Decrypt(value, _encryptionKeyBytes);
}
catch
{
return string.Empty;
}
}
/// <inheritdoc />
public override bool CanConvert(Type objectType)
{
return objectType == typeof(string);
}
}
public static class Crypto
{
public static string Encrypt(this string text, string key)
{
if (string.IsNullOrEmpty(key))
throw new ArgumentException("Key must have valid value.", nameof(key));
if (string.IsNullOrEmpty(text))
throw new ArgumentException("The text must have valid value.", nameof(text));
var buffer = Encoding.UTF8.GetBytes(text);
var hash = SHA512.Create();
var aesKey = new byte[24];
Buffer.BlockCopy(hash.ComputeHash(Encoding.UTF8.GetBytes(key)), 0, aesKey, 0, 24);
using (var aes = Aes.Create())
{
if (aes == null)
throw new ArgumentException("Parameter must not be null.", nameof(aes));
aes.Key = aesKey;
using (var encryptor = aes.CreateEncryptor(aes.Key, aes.IV))
using (var resultStream = new MemoryStream())
{
using (var aesStream = new CryptoStream(resultStream, encryptor, CryptoStreamMode.Write))
using (var plainStream = new MemoryStream(buffer))
{
plainStream.CopyTo(aesStream);
}
var result = resultStream.ToArray();
var combined = new byte[aes.IV.Length + result.Length];
Array.ConstrainedCopy(aes.IV, 0, combined, 0, aes.IV.Length);
Array.ConstrainedCopy(result, 0, combined, aes.IV.Length, result.Length);
return Convert.ToBase64String(combined);
}
}
}
public static string Decrypt(this string encryptedText, string key)
{
if (string.IsNullOrEmpty(key))
throw new ArgumentException("Key must have valid value.", nameof(key));
if (string.IsNullOrEmpty(encryptedText))
throw new ArgumentException("The encrypted text must have valid value.", nameof(encryptedText));
var combined = Convert.FromBase64String(encryptedText);
var buffer = new byte[combined.Length];
var hash = new SHA512CryptoServiceProvider();
var aesKey = new byte[24];
Buffer.BlockCopy(hash.ComputeHash(Encoding.UTF8.GetBytes(key)), 0, aesKey, 0, 24);
using (var aes = Aes.Create())
{
if (aes == null)
throw new ArgumentException("Parameter must not be null.", nameof(aes));
aes.Key = aesKey;
var iv = new byte[aes.IV.Length];
var ciphertext = new byte[buffer.Length - iv.Length];
Array.ConstrainedCopy(combined, 0, iv, 0, iv.Length);
Array.ConstrainedCopy(combined, iv.Length, ciphertext, 0, ciphertext.Length);
aes.IV = iv;
using (var decryptor = aes.CreateDecryptor(aes.Key, aes.IV))
using (var resultStream = new MemoryStream())
{
using (var aesStream = new CryptoStream(resultStream, decryptor, CryptoStreamMode.Write))
using (var plainStream = new MemoryStream(ciphertext))
{
plainStream.CopyTo(aesStream);
}
return Encoding.UTF8.GetString(resultStream.ToArray());
}
}
}
public static string Encrypt(string text, byte[] key)
{
//string keyString = "encrypt123456789";
//var key = Encoding.UTF8.GetBytes(keyString);//16 bit or 32 bit key string
using (var aesAlg = Aes.Create())
{
using (var encryptor = aesAlg.CreateEncryptor(key, aesAlg.IV))
{
using (var msEncrypt = new MemoryStream())
{
using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
using (var swEncrypt = new StreamWriter(csEncrypt))
{
swEncrypt.Write(text);
}
var iv = aesAlg.IV;
var decryptedContent = msEncrypt.ToArray();
var result = new byte[iv.Length + decryptedContent.Length];
Buffer.BlockCopy(iv, 0, result, 0, iv.Length);
Buffer.BlockCopy(decryptedContent, 0, result, iv.Length, decryptedContent.Length);
return Convert.ToBase64String(result);
}
}
}
}
public static string Decrypt(string cipherText, byte[] key)
{
var fullCipher = Convert.FromBase64String(cipherText);
var iv = new byte[16];
var cipher = new byte[fullCipher.Length - iv.Length];//new byte[16];
Buffer.BlockCopy(fullCipher, 0, iv, 0, iv.Length);
Buffer.BlockCopy(fullCipher, iv.Length, cipher, 0, cipher.Length);
//var key = Encoding.UTF8.GetBytes(keyString);//same key string
using (var aesAlg = Aes.Create())
{
using (var decryptor = aesAlg.CreateDecryptor(key, iv))
{
string result;
using (var msDecrypt = new MemoryStream(cipher))
{
using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
using (var srDecrypt = new StreamReader(csDecrypt))
{
result = srDecrypt.ReadToEnd();
}
}
}
return result;
}
}
}
}
to activate encryption just add a tag
[JsonConverter(typeof(EncryptingJsonConverter))]

How to perform POST operation on Windows Phone 8.1

I am struggling to successfully implement a POST operation within Windows Phone 8.1.
PostMessage method executes without any exceptions being caught.
However, the POST method within MessagesController never gets invoked.
How do I perform a POST for Windows Phone 8.1?
The code is below:
internal async Task PostMessage(string text)
{
Globals.MemberId = 1;
int memberId = 2;
// server to POST to
string url = #"http://localhost:17634/api/messages";
try
{
// HTTP web request
var httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
httpWebRequest.ContentType = "text/plain; charset=utf-8";
httpWebRequest.Method = "POST";
// Write the request Asynchronously
using (var stream = await Task.Factory.FromAsync<Stream>(httpWebRequest.BeginGetRequestStream,
httpWebRequest.EndGetRequestStream, null))
{
//create some json string
var message = new Message() { FromId = Globals.MemberId, ToId = memberId, Content = text, Timestamp = DateTime.Now };
var json = string.Format("{0}{1}", "action=", JsonConvert.SerializeObject(message));
// convert json to byte array
byte[] jsonAsBytes = Encoding.UTF8.GetBytes(json);
// Write the bytes to the stream
await stream.WriteAsync(jsonAsBytes, 0, jsonAsBytes.Length);
}
}
catch(Exception ex)
{
Debug.WriteLine(ex.Message);
}
}
public class MessagesController : ApiController
{
public HttpResponseMessage Post(Message message)
{
throw new NotImplementedException();
}
}
public class Message
{
public int MessageId { get; set; }
public int FromId { get; set; }
public int ToId { get; set; }
public DateTime Timestamp { get; set; }
public string Content { get; set; }
}
The following link resolved my issue.
The updated client is as follows:
using (var client = new System.Net.Http.HttpClient())
{
// New code:
client.BaseAddress = new Uri(Globals.URL_PREFIX);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var message = new Message() { MessageId = 0, FromId = Globals.MemberId, ToId = memberId, Content = text, Timestamp = DateTime.Now };
var json_object = JsonConvert.SerializeObject(message);
var response = await client.PostAsync("api/messages", new StringContent(json_object.ToString(), Encoding.UTF8, "application/json"));
Debug.Assert(response.StatusCode == System.Net.HttpStatusCode.Accepted);
}
This works fine for me. The function accepts an payload of type T. The server accepts a JSON object and returns a JSON response.
public async static Task SendRequestPacket<T>(object payload)
{
Uri theUri = new Uri("the_uri");
//Create an Http client and set the headers we want
HttpClient aClient = new HttpClient();
aClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
aClient.DefaultRequestHeaders.Host = theUri.Host;
//Create a Json Serializer for our type
DataContractJsonSerializer jsonSer = new DataContractJsonSerializer(typeof(T));
// use the serializer to write the object to a MemoryStream
MemoryStream ms = new MemoryStream();
jsonSer.WriteObject(ms, payload);
ms.Position = 0;
//use a Stream reader to construct the StringContent (Json)
StreamReader sr = new StreamReader(ms);
StringContent theContent = new StringContent(sr.ReadToEnd(), Encoding.UTF8, "application/json");
//Post the data
HttpResponseMessage aResponse = await aClient.PostAsync(theUri, theContent);
if (aResponse.IsSuccessStatusCode)
{
string content = await aResponse.Content.ReadAsStringAsync();
System.Diagnostics.Debug.WriteLine(content);
}
else
{
// show the response status code
}
}
Just dont use HttpWebRequest if you are not forced to in any way.
This example is using HttpClient() and it is good to always have the client created once and not every time you make a request.
So in your class add:
private static HttpClient _client;
public static Uri ServerBaseUri
{
get { return new Uri("http://localhost:17634/api"); }
}
public ClassConstructor()
{
_client = new HttpClient();
}
internal async Task<ResponseType> PostMessage(string text)
{
Globals.MemberId = 1;
int memberId = 2;
try
{
var js = "{ JSON_OBJECT }";
var json = new StringContent(js);
json.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");
var response = await Client.PostAsync(new Uri(ServerBaseUri, "/messages"), json);
var reply = await response.Content.ReadAsStringAsync();
} catch (Exception)
{
return null;
}
}
More on HttpClient.

How cancel Async Call in Windows Phone?

I have a list wich is loaded with elements each time the user make a research...These elements contain an Icon which is dowloaded with an async method GetByteArrayAsync of the HttpClient object. I have an issue when the user make a second research while the icon of the first list are still downloading.Because the list of elements is changing while Icon downloads are processing on each element of the first list. So my guess is that I need to cancel these requests each time the user proceed to a new research...Ive readen some stuuf on Task.run and CancellationTokenSource but I can't find really helpful example for my case so here is my code...Hope you can help me with that ...Thank you
public static async Task<byte[]> DownloadElementFile(BdeskElement bdeskElement)
{
//create and send the request
DataRequest requesteur = new DataRequest();
byte[] encryptedByte = await requesteur.GetBytesAsync(dataRequestParam);
return encryptedByte;
}
public async Task<Byte[]> GetBytesAsync(DataRequestParam datarequesparam)
{
var handler = new HttpClientHandler { Credentials = new NetworkCredential(datarequesparam.AuthentificationLogin, datarequesparam.AuthentificationPassword, "bt0d0000") };
HttpClient httpClient = new HttpClient(handler);
try
{
byte[] BytesReceived = await httpClient.GetByteArrayAsync(datarequesparam.TargetUri);
if (BytesReceived.Length > 0)
{
return BytesReceived;
}
else
{
return null;
}
}
catch (WebException)
{
throw new MyException(MyExceptionsMessages.Webexception);
}
}
EDIT
public async Task<Byte[]> GetBytesAsync(DataRequestParam datarequesparam)
{
var handler = new HttpClientHandler { Credentials = new NetworkCredential(datarequesparam.AuthentificationLogin, datarequesparam.AuthentificationPassword, "bt0d0000") };
HttpClient httpClient = new HttpClient(handler);
try
{
cts = new CancellationTokenSource();
HttpResponseMessage reponse = await httpClient.GetAsync(datarequesparam.TargetUri,cts.Token);
if (reponse.StatusCode == HttpStatusCode.OK)
{
byte[] BytesReceived = reponse.Content.ReadAsByteArrayAsync().Result;
if (BytesReceived.Length > 0)
{
return BytesReceived;
}
else
{
return null;
}
}
else
{
return null;
}
}
catch (WebException)
{
throw new MyException(MyExceptionsMessages.Webexception);
}
catch(OperationCanceledException)
{
throw new OperationCanceledException();
}
EDIT2
I need to cancel this funntion when the user make a new research and the list "listBoxGetDocsLibs" changed.
private async void LoadIconDocLibs()
{
foreach (var doclib in listBoxGetDocsLibs)//ERROR HERE COLLECTION HAS CHANGED
{
doclib.Icon = new BitmapImage();
try
{
byte[] Icon = await ServerFunctions.GetDocLibsIcon(doclib);
if (Icon != null)
{
{
var ms = new MemoryStream(Icon);
BitmapImage photo = new BitmapImage();
photo.DecodePixelHeight = 64;
photo.DecodePixelWidth = 92;
photo.SetSource(ms);
doclib.Icon = photo;
}
}
}
catch(OperationCanceledException)
{
}
}
}
First you need to define CancellationTokenSource:
private System.Threading.CancellationTokenSource cts;
place above code somewhere, where you can access it with your Button or other method.
Unfortunately GetByteArrayAsync lacks Cancelling - so it cannot be used with cts.Token, but maybe you can accomplish your task using GetAsync - which supports Cancelling:
ctsDownload = new System.Threading.CancellationTokenSource();
HttpResponseMessage response = await httpClient.GetAsync(requestUri, cts.Token);
Then you can get your content from response.
And when you want to Cancel your Task it can look like this:
private void cancelBtn_Click(object sender, RoutedEventArgs e)
{
if (this.cts != null)
this.cts.Cancel();
}
When you Cancel task an Exception will be thrown.
If you want to cancel your own async Task, a good example you can find at Stephen Cleary blog.
EDIT - you can also build your own method (for example with HttpWebRequest) which will support Cancelling:
For this purpose you will have to extend HttpWebRequest (under WP it lacks GetResponseAsync):
// create a static class in your namespace
public static class Extensions
{
public static Task<HttpWebResponse> GetResponseAsync(this HttpWebRequest webRequest)
{
TaskCompletionSource<HttpWebResponse> taskComplete = new TaskCompletionSource<HttpWebResponse>();
webRequest.BeginGetResponse(
asyncResponse =>
{
try
{
HttpWebRequest responseRequest = (HttpWebRequest)asyncResponse.AsyncState;
HttpWebResponse someResponse = (HttpWebResponse)responseRequest.EndGetResponse(asyncResponse);
taskComplete.TrySetResult(someResponse);
}
catch (WebException webExc)
{
HttpWebResponse failedResponse = (HttpWebResponse)webExc.Response;
taskComplete.TrySetResult(failedResponse);
}
catch (Exception exc) { taskComplete.SetException(exc); }
}, webRequest);
return taskComplete.Task;
}
}
Then your method can look like this:
public async Task<Byte[]> GetBytesAsync(DataRequestParam datarequesparam, CancellationToken ct)
{
HttpWebRequest request = HttpWebRequest.CreateHttp(datarequesparam.TargetUri);
request.Method = "GET";
request.Credentials = new NetworkCredential(datarequesparam.AuthentificationLogin, datarequesparam.AuthentificationPassword, "bt0d0000");
request.AllowReadStreamBuffering = false;
try
{
if (request != null)
{
using (HttpWebResponse response = await request.GetResponseAsync())
using (Stream mystr = response.GetResponseStream())
using (MemoryStream output = new MemoryStream())
{
const int BUFFER_SIZE = 10 * 1024;
byte[] buf = new byte[BUFFER_SIZE];
int bytesread = 0;
while ((bytesread = await mystr.ReadAsync(buf, 0, BUFFER_SIZE)) > 0)
{
output.Write(buf, 0, bytesread);
ct.ThrowIfCancellationRequested();
}
return output.ToArray();
}
}
else return null;
}
catch (WebException)
{
throw new MyException(MyExceptionsMessages.Webexception);
}
}
You can freely change Buffer Size which will affect how often Cancellation will be checked.
I haven't tried this but I think it should work.

How can I read this json on windows phone 8?

I'm trying to read the following json in a windows phone app using newtonsoft.json
I can't read anything. the also looks pretty strange to me.
{"type": "Menu","menu":
[{"0":"antipasto","tipo_piatto":"antipasto","1":"porchetta","nome_piatto":"porchetta","2":"1","prezzo":"1"},
{"0":"primo","tipo_piatto":"primo","1":"matriciana","nome_piatto":"matriciana","2":"5","prezzo":"5"},
{"0":"secondo","tipo_piatto":"secondo","1":"salsicce","nome_piatto":"salsicce","2":"4","prezzo":"4"},
{"0":"contorno","tipo_piatto":"contorno","1":"patate","nome_piatto":"patate","2":"2","prezzo":"2"},
{"0":"dolce","tipo_piatto":"dolce","1":"gelato","nome_piatto":"gelato","2":"6","prezzo":"6"}]}
this is my c# code for now
public class piatto_menu_giorno
{
public string tipo_piatto { get; set; }
public string nome_piatto { get; set; }
public string prezzo { get; set; }
}
public menu()
{
InitializeComponent();
WebClient webClient = new WebClient();
Uri uri = new Uri("http://www.stepapp.it/areacli/extDevice/getMenuOdierno_101.php");
webClient.OpenReadCompleted += new OpenReadCompletedEventHandler(fine_lettura_web);
webClient.OpenReadAsync(uri);
}
private void fine_lettura_web(object sender, OpenReadCompletedEventArgs e)
{
DataContractJsonSerializer json = null;
json = new DataContractJsonSerializer(typeof(ObservableCollection<piatto_menu_giorno>));
ObservableCollection<piatto_menu_giorno> menu = json.ReadObject(e.Result) as ObservableCollection<piatto_menu_giorno>;
if(menu==null)
menu_giorno.Text = "null";
else
foreach (piatto_menu_giorno piatto in menu)
{
menu_giorno.Text += piatto.nome_piatto + "\n";
}
}
sorry for all the variables name that are in italian
I am writing a code for you it will help you to deserialize the object from json to yourClassCustomObject.
private async Task<List<piatto_menu_giorno>> MyDeserializerFunAsync()
{
List<piatto_menu_giorno> book = new List<piatto_menu_giorno>();
try
{
//I am taking my url from appsettings. myKey is my appsetting key. You can write direct your url.
string url = (string)appSettings["mykey"];
var request = HttpWebRequest.Create(url) as HttpWebRequest;
request.Accept = "application/json;odata=verbose";
var factory = new TaskFactory();
var task = factory.FromAsync<WebResponse>(request.BeginGetResponse,request.EndGetResponse, null);
var response = await task;
Stream responseStream = response.GetResponseStream();
string data;
using (var reader = new System.IO.StreamReader(responseStream))
{
data = reader.ReadToEnd();
}
responseStream.Close();
DataContractJsonSerializer json = new DataContractJsonSerializer(typeof(List<piatto_menu_giorno>));
MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(data));
book = (List<piatto_menu_giorno>)json.ReadObject(ms);
return book;
}
}
Above code is working in my wp8 application it is faster you can try, it will help you. I am performing asynchronous operation but you can create your simple method with piatto_menu_giorno return type.