I need to send JSON to WebResourceResponse:
override this.ShouldInterceptRequest(view:WebView, request:IWebResourceRequest) =
let rows = Customer.fakeData 1 // Array of records
let st = Shared.jsonToStream(rows)
new WebResourceResponse("application/javascript", "UTF-8", st)
But don't see how do that. I use Json.NET and F#.
When I run:
let jsonToStream(value:'T) =
let serializer = new JsonSerializer()
let std = new IO.MemoryStream()
let sw = new IO.StreamWriter(std)
let json = new JsonTextWriter(sw)
serializer.Serialize(json, value)
//std.Position <- 0L
std
the response returns as a blank string.
You have the following issues:
You need to dispose of your StreamWriter and JsonTextWriter so that the serialized JSON is flushed to the underlying stream. This can be done by replacing let with use.
However, you need to do so without closing the underlying stream std, since you are going to read from it later.
Having done so, you need to reset the position of the std stream after sw and json have gone out of scope and been disposed. If you try to reset the position before then it won't work.
Thus the following will work:
let jsonToStream(value:'T) =
let serializer = new JsonSerializer()
let std = new IO.MemoryStream()
( use sw = new StreamWriter(std, new UTF8Encoding(false, true), 1024, true)
use json = new JsonTextWriter(sw, CloseOutput = false)
serializer.Serialize(json, value))
std.Position <- 0L
std
Note the use of parentheses to restrict the scope of sw and json so that std.Position can be reset after they go out of scope. jsonToStream(rows) will now return an open MemoryStream containing complete, serialized JSON and positioned at the beginning.
Sample working f# fiddle.
Related
I'm trying to parse some Json in Xamarin.Forms
I'm pretty new to Xamarin, though not to .net
Here's my simple dimple code
var htc = new HttpClient();
var rsp = await htc.GetStringAsync("myurl.com");
JArray lists = JArray.Parse(rsp);
var c = lists.Count();
var l = lists.ToList();
var w=lists.Where(x => true);
Even though c returns the correct count of items in the list, l & w are both null
How come? and how do I fix it?
Thanks!
PS. What I'm really trying to do is bind a ListView to a JArray, but it seems impossible directly,(Text={Binding MyPropertyName} crashes the app). so I'm trying to run a Select on the JArray to convert to a KeyValuePair. If you have any ideas to bind directly, that would be best!
UPDATE
The issue seems even odder
I tried this
var kvlist = new List<KeyValuePair<string, string>>();
foreach (JObject ll in lists)
{
kvlist.Add(new KeyValuePair<string, string>(ll["Name"].ToString(), ll["Name"].ToString()));
}
Here at least the iteration works nicely, but the kvlist is null the entire time. Trying to evaluate the kvlist variable, I get:
Unable to cast object of type 'System.RuntimeType' to type
'Mono.Debugger.Soft.TypeMirror'.
What can the matter be?
Thanks again!
You should not directly call .ToList on object type of JArray rather you should Select List of type you need. For ex.
var l = lists.Select(c => new MyList
{
Item1 = c.Value<int>("ItemName1"),
Item2 = c.Value<string>("ItemName2")
}).ToList(); //Replce MyList with your class name
On the second case where w is null, after getting list l you need to specify attribute, based of what you are using where clause. For ex.
var w=l.Where(x =>x.isAdmin==true); //l is list you selected above
Hope it help you.
Solution:
You can use code below to convert a JArray to a list<T>:
List<T> t =lists.ToObject<List<T>>();
Refer: https://www.newtonsoft.com/json/help/html/ToObjectType.htm
You could also use JsonConvert.DeserializeObject to convert it directly into the desired type. You have to define a jsonModel class with the same structure of your json fisrtly.
List<jsonModel> modelList = JsonConvert.DeserializeObject<List<jsonModel>>(jsonStr);
Refer :https://www.newtonsoft.com/json/help/html/SerializingCollections.htm
The documentation seems to indicate that JArray has properties for .Count, but no overload method because it does not implement IEnumerable, however as alluded to in the comments, it does implement the JToken type (which JArray is a collection of) and implements IEnumerable.
See the following documentation for JToken: https://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_Linq_JToken.htm
and JArray respectively:
https://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_Linq_JArray.htm
The preferred mechanism is to create a strong type and then run .ToObject();
You can access JArray.ChildrenTokens which may help
Is JSON parsing possible into a type data or any other form where I can access each individual item within F# using built-in Microsoft provided library?
Following is an output generated by the following code.
"{"account_type":"type1","address":"US","preferred_languages":["en","ar","cn"],"displayName":"John","last_name":"Doe"}"
type Token = {access_token: string; refresh_token: string}
type Authentication =
new() = {}
static member token = null;
member this.RequestToken(credentials) =
let url = "example.com"
let request = WebRequest.Create(url) :?> HttpWebRequest
request.Method <- "POST"
request.ContentLength <- (int64)data.Length
use requestStream = request.GetRequestStream()
requestStream.Write(data, 0, (data.Length))
requestStream.Flush()
requestStream.Close()
let response = request.GetResponse() :?> HttpWebResponse
use reader = new StreamReader(response.GetResponseStream())
let output = reader.ReadToEnd()
reader.Close()
response.Close()
request.Abort()
Authentication.token = JsonConvert.DeserializeObject<Token>(output)
// the value or constructor "Token" is not defined
Preferably in a type, for instance
type Token = {access_token: string; refresh_token: string}
Edit
Attempting using JSON.net
You will need to use an external library of some kind. If you want to get the most out of F#, you can solve this very nicely using the F# Data JSON type provider.
The type provider can infer type of JSON data from a sample, so you could parse the above data by using your sample response to guide the inference and then use the inferred type to parse more data:
open FSharp.Data
// Define a type using a sample JSON
type Account = JsonProvider<"""
{ "account_type":"type1","address":"US",
"preferred_languages":["en","ar","cn"],
"displayName":"John","last_name":"Doe"}""">
// Now, parse actual data you loaded from somewhere
let parsed = Account.Parse(data)
// Access all the members using a member generated by the type provider.
parsed.AccountType
parsed.Address
parsed.PreferredLanguages |> Seq.length
Here is my code
I am trying to insert Json values into Azure as Entity, but I always get only the first value when I get back from Azure..Is there anything I need to change in the below code?
string Emulators = "['TestEmulator1','Testemulator12','Testemulator2','TestEmulator3']";
List<string> Emulators = new List<string>();
EmulatorIDS.Add(Emulators);
var jsondata = JsonConvert.SerializeObject(Emulators);
Console.WriteLine(jsondata);
var EmulatorID = new EntityProperty(jsondata);
//Instantiate serializer
Random rnd = new Random();
int a = rnd.Next(1, 1000);
DynamicTableEntity actordata = new DynamicTableEntity();
actordata.RowKey = "Test"+a.ToString();
actordata.PartitionKey = "test#gmail.com";
actordata.Properties["DetailsValue"] = EmulatorID;
actordata.Properties["OtherData"] = EmulatorID;
TableOperation insertOperation = TableOperation.Insert(actordata);
table.Execute(insertOperation);
Have a look https://www.nuget.org/packages/ObjectFlattenerRecomposer/ version 2.0 it will automatically convert your complex objects to a writable form to table storage, it supports complex types and ICollection/IEnumerable type properties as well. You do not need to do any up front json conversion yourself either, the api automatically handles conversions.
If anybody is looking for answer for this..Please see here about how to insert Json values via TableEntity instead of using JsonPayload format
I have a JSON file that contains what I believe to be a correct JSON string:
{"title": "exampleTitle", "tipTitle": "exampleTipTitle", "tip": "exampleTip"}
I'm trying to parse said file and take out the 3 values then store them in variables, however currently, it parses each individual character as a separate object, therefore:
JSONobj[1] = "
and so on. Assuming that currentLocation = the directory location of the json file.
Code
var jsonLocation = currentLocation + "json.txt";
var request = new XMLHttpRequest();
request.open("GET", jsonLocation, false);
request.send(null);
var returnValue = request.responseText;
var JSONobj = JSON.parse(JSON.stringify(returnValue));
var headerTitle = JSONobj[0];
A few clarifications, the stringify is in because it was throwing an unexpected token error. I've tried changing the file tile to .json instead but that also makes no difference. "It also gives off a XMLHttpRequest on the main thread is deprecated" but I'm not particularly sure how to solve that issue. Any help would be appreciated.
var returnValue = request.responseText;
Here returnValue is a string of JSON.
"{\"title\": \"exampleTitle\", \"tipTitle\": \"exampleTipTitle\", \"tip\": \"exampleTip\"}
var JSONobj = JSON.parse(JSON.stringify(returnValue));
Here you convert the string of JSON to JSON. So you have a JSON string representing a string, and that string is a representation of a data structure in JSON.
"\"{\\"title\\": \\"exampleTitle\\", \\"tipTitle\\": \\"exampleTipTitle\\", \\"tip\\": \\"exampleTip\\"}"
Then you parse it and convert it back to the original string of JSON.
"{\"title\": \"exampleTitle\", \"tipTitle\": \"exampleTipTitle\", \"tip\": \"exampleTip\"}
So you end up back where you start.
Just don't use JSON.stringify here, and you'll convert your JSON to a JavaScript object:
var javascript_object = JSON.parse(returnValue);
Then you have an object, but it doesn't have a 0 property so it doesn't make sense to access it with javascript_object[0]. The properties have names, such as javascript_object.title.
Your JSON doesn't describe an array, so indexing into it with an index like 0 doesn't make sense. Your JSON describes an object, which will have properties with the names title, tipTitle, and tip.
Additionally, you're overdoing your parsing: You just want to parse, not stringify (which is the opposite of parsing):
var JSONobj = JSON.parse(returnValue);
So:
var JSONobj = JSON.parse(returnValue);
var headerTitle = JSONobj.title;
console.log(headerTitle); // "exampleTitle"
Side note: By the time you've assigned it to the variable you've called JSONobj, it isn't JSON anymore, it's just a normal JavaScript object, so that name is a bit misleading. If you're writing source code, and you're not dealing with a string, you're not dealing with JSON anymore. :-)
In a .NET 3.5 Compact Framework / Windows CE app, I need to consume some WebAPI methods that return json. RestSharp looks like it would be great for this, except that it's not quite CF-ready (see Is Uri available in some other assembly than System in .NET 3.5, or how can I resolve Uri in this RestSharp code otherwise? for details).
So, I will probably use HttpWebRequest. I can return the value from the WebAPI methods with this code:
string uri = "http://localhost:48614/api/departments";
var webRequest = (HttpWebRequest)WebRequest.Create(uri);
var webResponse = (HttpWebResponse)webRequest.GetResponse();
if ((webResponse.StatusCode == HttpStatusCode.OK) && (webResponse.ContentLength > 0))
{
StreamReader reader = new StreamReader(webResponse.GetResponseStream());
MessageBox.Show("Content is " + reader.ReadToEnd());
}
else
{
MessageBox.Show(string.Format("Status code == {0}", webResponse.StatusCode));
}
...but in order to use what's returned from reader.ReadToEnd():
...I need to convert it back to json so that I can then query the data with LINQ to JSON using either JSON.NET (http://json.codeplex.com/) or SimpleJson (http://simplejson.codeplex.com/)
Is that realistically possible (converting StreamReader data to JSON)? If so, how?
UPDATE
I'm trying to deserialize the "json" (or string that looks like json) with this code:
string uri = "http://localhost:48614/api/departments";
var webRequest = (HttpWebRequest)WebRequest.Create(uri);
webRequest.Method = "GET";
var webResponse = (HttpWebResponse)webRequest.GetResponse();
if ((webResponse.StatusCode == HttpStatusCode.OK) && (webResponse.ContentLength > 0))
{
StreamReader reader = new StreamReader(webResponse.GetResponseStream());
DataContractJsonSerializer jasonCereal = new DataContractJsonSerializer(typeof(Department));
var dept = (Department)jasonCereal.ReadObject(reader.ReadToEnd());
MessageBox.Show(string.Format("accountId is {0}, deptName is {1}", dept.AccountId, dept.DeptName));
}
...but get two err msgs on the "var dept =" line:
0) The best overloaded method match for 'System.Runtime.Serialization.XmlObjectSerializer.ReadObject(System.IO.Stream)' has some invalid arguments
1) Argument '1': cannot convert from 'string' to 'System.IO.Stream'
So reader.ReadToEnd() returns a string, and DataContractJsonSerializer.ReadObject() expects a stream, apparently. Is there a better approach for this? Or, if I'm on the right track (although currently a section of track has been removed, so to speak), how should I get past this hurdle?
UPDATE 2
I added the System.Web.Extensions reference and then "using System.Web.Script.Serialization;" but this code:
JavaScriptSerializer jss = new JavaScriptSerializer();
var dept = jss.Deserialize<Department>(s);
MessageBox.Show(string.Format("accountId is {0}, deptName is {1}",
dept.AccountId, dept.DeptName));
...but the second line fails with:
"Type 'bla+Department' is not supported for deserialization of an array."
What type should receive the call to jss.Deserialize()? How is it defined?
Well,
the ReadToEnd() method is used to read the stream into a string and output it. If you need a stream out to pass it to a method requiring a stream, you shouldn't use this method.
From what I read on this page , it seems the BaseStream property of your reader would be more appropriate to use then.