Deserialize Json to Object in a handler - c#

I have a simple class:
public class site
{
public string URL { get; set; }
}
That exists within a http handler. Currently I am posting json to this handler and trying to deserialize it to get the URL out of the string. I am however having a problem with the deserialize part of it.
I have a string "jsonString" that has the json formatted like so:
[{"URL":"http://www.google.com/etc/"}]
Here is my code for the deserialize:
JavaScriptSerializer jsonSerializer = new JavaScriptSerializer();
string jsonString = String.Empty;
HttpContext.Current.Request.InputStream.Position = 0;
using (StreamReader inputStream = new StreamReader(HttpContext.Current.Request.InputStream))
{
jsonString = inputStream.ReadToEnd();
}
site currSite = new site();
currSite = jsonSerializer.Deserialize<site>(jsonString);
//set response types
HttpContext.Current.Response.ContentType = "application/json";
HttpContext.Current.Response.ContentEncoding = Encoding.UTF8;
//send response
HttpContext.Current.Response.Write(jsonSerializer.Serialize(currSite.URL));
I am then trying to send a response using currSite.URL however it is failing. What am I missing here? I am reasonably confident it is at the deserialize part because if I send a response of jsonString instead of currSite.URL it will work.

Your json string shows that it's an array, not a single entity. You should deserialize it as so:
var result = jsonSerializer.Deserialize<site[]>(jsonString);
And result[0].Url should contain what you are looking for.
Update
Adding sample code:
string json = #"[{""URL"":""http://www.google.com/etc/""}]";
JavaScriptSerializer js = new JavaScriptSerializer();
var result = js.Deserialize<site[]>(json);
Console.WriteLine(result[0].URL);
Prints:
http://www.google.com/etc/

If you're simply trying to send back the URL as the response (just the string) there's no need to serialize the value. Just pass currSite.URL to the Write method.
Otherwise, I'm guessing you should serialize the whole currSite object for the response rather than just the URL. It all depends on what kind of response the caller is expecting (which you haven't specified).

Related

Dictionary and object to web service content type string

I have Dictionary with values how to convert them to string of format application/json and application/x-www-form-urlencoded simplest standard way:
var values = new Dictionary<string, string>
{
{"id", "1"},
{"amount", "5"}
};
The same question regarding class object with the same fields:
class values
{
public String id { get; set; }
public string amount { get; set; }
}
simple way is using json.NET library in order to post the data. you can convert your object to application/json like this:
var jsonString = JsonConvert.SerializeObject(values);
then post it to your service like this:
private static T Call<T>(string url, string body)
{
var contentBytes = Encoding.UTF8.GetBytes(body);
var request = (HttpWebRequest)WebRequest.Create(url);
request.Timeout = 60 * 1000;
request.ContentLength = contentBytes.Length;
request.Method = "POST";
request.ContentType = #"application/json";
using (var requestWritter = request.GetRequestStream())
requestWritter.Write(contentBytes, 0, (int)request.ContentLength);
var responseString = string.Empty;
var webResponse = (HttpWebResponse)request.GetResponse();
var responseStream = webResponse.GetResponseStream();
using (var reader = new StreamReader(responseStream))
responseString = reader.ReadToEnd();
return JsonConvert.DeserializeObject<T>(responseString);
}
It's not clear from your question if you want to manually serialize your dictionary or object and then send it using a custom way or if you would like to automatically serialize and send them to a web service.
The manual way:
Json
PM > Install-Package Newtonsoft.Json
Json.NET natively supports dictionary to Json object and, of course, object to json object serialization. You simply install it and than serialize using:
var jsonString = JsonConvert.SerializeObject(values); // values can be Dictionary<string, Anything> OR an object
Result:
{
"id": "1",
"amount", "5"
}
Form URL encoded
The cleanest way is to use the .NET built-in utility HttpUtility.ParseQueryString (which also encodes any non-ASCII character):
var nvc = HttpUtility.ParseQueryString("");
foreach(var item in values)
nvc.Add(item.Key, item.Value);
var urlEncodedString = nvc.ToString();
Result:
id=1&amount=5
Please note that there is no direct way to serialize an object into a Form URL encoded string without adding its members manually, e.g.:
nvc.Add(nameof(values.id), values.id);
nvc.Add(nameof(values.amount), values.amount);
The automatic way:
Everything is simpler if you just use HttpClient:
PM > Install-Package Microsoft.AspNet.WebApi.Client
Json
You may need to also use HttpClientExtensions extension methods for automatic Json serialization (without it you need to serialize it manually as shown above):
using (var client = new HttpClient())
{
// set any header here
var response = await client.PostAsJsonAsync("http://myurl", values); // values can be a dictionary or an object
var result = await response.Content.ReadAsAsync<MyResultClass>();
}
Form URL encoded
using (var client = new HttpClient())
{
using (var content = new FormUrlEncodedContent(values)) // this must be a dictionary or a IEnumerable<KeyValuePair<string, string>>
{
content.Headers.Clear();
content.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
var response = await client.PostAsync(url, content);
var result = await response.Content.ReadAsAsync<MyResultClass>();
}
}
This way you may serialize dictionaries directly. Again for objects you need to convert them manually as shown above.

Unable to Parse JSON Response

I have a service that sends JSON response. The controller method looks as follows:
string varStr = "{proper JSON here}";
public string GetListofResourcesInSubscription(string subscriptionId)
{
// Uncomment any option below to test. The error persists either way.
//return varStr; --- Option 1
return JsonConvert.SerializeObject(JObject.Parse(varStr)); // Option 2
}
The method that gets the response is like the following:
response = outgoingRequest.GetResponse() as HttpWebResponse;
if (response.StatusCode == HttpStatusCode.OK)
{
responseStream = response.GetResponseStream();
using (var reader = new StreamReader(responseStream))
{
string strResp = reader.ReadToEnd();
JObject joResponse = JObject.Parse(strResp); // throws error
JArray objArray = (JArray)joResponse["value"];
// other processing
}
}
Irrespective of the return statement selected in the controller method above, the response parser is always throwing an error while it is trying to parse the response.
Changing the parsing line to the following resolves the issue but it is not clear to me why it is so.
JObject joResponse = JObject.Parse(JsonConvert.DeserializeObject<string>(strResp));
Also, I want to know what is the correct way of sending a JSON response from an ASP.NET web api2 controller. I don't want to use models for creating the response because I have JSON strings that I want to return directly instead of creating models out of them.
Update 1:
The error is the following:
"Error reading JObject from JsonReader. Current JsonReader item is not an object: String. Path '', line 1, position 6546."} System.Exception {Newtonsoft.Json.JsonReaderException}
You can't deserialize a complex JSON object back to a string. Your example won't work, because you are assuming the JSON evaluates to a string:
JObject joResponse = JObject.Parse(JsonConvert.DeserializeObject<string>(strResp))
You might have more success either using a JObject, or the alternative is to deserialize into a Dictionary, or into a known type.
var dictionary = JsonConvert.DeserializeObject<<Dictionary<string,object>>(strResp);
The problem here was the return type of the controller function. As it was returning string, the serialization to string was required to get correct result. The correct way of returning JSON is to return a JToken as explained here. So the controller needs to be changed to the following:
public JToken GetListofResourcesInSubscription(string subscriptionId)
{
return JObject.Parse(varStr);
}

RestSharp get serialized output

I am looking for a way to access the serialized result of the AddBody call.
I am using the built in RestSharp Serializer.
Example:
class Foo
{
public string FooField;
}
void SendRecord()
{
var f = new Foo();
f.FooField = "My Value";
request.AddBody(f);
// How do I get the serialized json result of the add body call without
// data? I would like to log the serialized output of the add body call to
// the database.
//Expected {"FooField":"My Value"}
var response = client.Execute(request);
}
I figured it out by finding this post.
request.Parameters.Where(p => p.Type == ParameterType.RequestBody).FirstOrDefault();
I also struggled with this (using v107 preview) and couldn't find any examples of logging the actual string sent to the server. The issue I was trying to debug was getting the right serialisation settings so the object was no use to me.
The only way I could find to get the serialized body as a string was to hook into the OnBeforeRequest event on the RestRequest:
var request = new RestRequest("/", Method.Post)
.AddHeader(KnownHeaders.ContentType, "application/json", false)
.AddJsonBody(myObj);
request.OnBeforeRequest = async (httpRequest) =>
{
var requestBodyStr = await httpRequest.Content.ReadAsStringAsync();
Trace.WriteLine($"Request body: {requestBodyStr}");
};
RestSharp itself doesn't expose the serialized request body when you pass an object to it.
There is a way to get at it though, I just posted over here:
https://stackoverflow.com/a/75537611/2509281
Right off the RestSharp homepage (http://restsharp.org/):
// execute the request
RestResponse response = client.Execute(request);
var content = response.Content; // raw content as string <~~~~~~~~~~

Moving from standard .NET rest to RestSharp

For the most part, I have managed quite quickly to move my code from standard .NET code to using RestSharp. This has been simple enough for GET processes, but I'm stumped for POST processes
Consider the following
var request = System.Net.WebRequest.Create("https://mytestserver.com/api/usr") as System.Net.HttpWebRequest;
request.Method = "POST";
request.ContentType = "application/json;version=1";
request.Headers.Add("Content-Type", "application/json;version=1");
request.Headers.Add("Accepts", "application/json;version=1");
request.Headers.Add("Authorize", "key {key}");
using (var writer = new System.IO.StreamWriter(request.GetRequestStream())) {
byte[] byteArray = System.Text.Encoding.UTF8.GetBytes("{\n \"firstName\": \"Dan\",\n \"lastName\": \"Eccles\",\n \"preferredNumber\": 1,\n \"email\" : \"testuser#example.com\",\n \"password\": \"you cant get the wood\"\n}");
request.ContentLength = byteArray.Length;
writer.Write(byteArray);
writer.Close();
}
string responseContent;
using (var response = request.GetResponse() as System.Net.HttpWebResponse) {
using (var reader = new System.IO.StreamReader(response.GetResponseStream())) {
responseContent = reader.ReadToEnd();
}
This is fairly straight forward to move across, except for the serialisation code. Is there a particular way this has to be done for RestSharp? I've tried creating an object and using
var json = JsonConvert.SerializeObject(user);
restRequest.RequestFormat = DataFormat.Json;
restRequest.AddBody(json);
but the server still comes back with an error.
I'm also currently using JSON.NET for deserialization to an error object when the user passes in bad data. Is there a way I can deserialize to error object based on a single string using RestSharp?
You're close, but you don't need to worry about serialization with RestSharp.
var request = new RestRequest(...);
request.RequestFormat = DataFormat.Json;
request.AddBody(user); // user is of type User (NOT string)
By telling it that the format is JSON, then passing your already-serialized-as-JSON string, RestSharp is actually encoding it again as a string.
So you pass the string: {"firstName":"foo"} and it actually gets sent to the server as a JSON string object: "{\"firstName\":\"foo\"}" (note how your JSON is escaped as a string literal), which is why it's failing.
Note you can also use an anonymous object for the request:
var request = new RestRequest(...);
request.RequestFormat = DataFormat.Json;
request.AddBody(new{
firstName = "Dan",
lastName = "Eccles",
preferredNumber = 1,
// etc..
});
You use the same typed objects with the response (eg, RestSharp deserializes for you):
var response = client.Execute<UserResponse>(request);
// if successful, response.Data is of type UserResponse

Using the contents of a JsonObject on aspx web page

I am trying to use a HTTP request to return the contents of a json string from google shopping api. What I have so far seems to be working but I would like to know how I can use the contents of the object to display the data on a page.
public string HttpGet(string url)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
try
{
using (Stream stream = response.GetResponseStream())
{
StreamReader reader = new StreamReader(stream);
return reader.ReadToEnd();
}
}
finally
{
response.Close();
}
}
protected void submit_Click(object sender, EventArgs e)
{
string json = HttpGet("https://www.googleapis.com/shopping/search/v1/public/products?key={KEY}4&country=UK&q=BX80637153570K&rankBy=price:ascending&maxResults=1&alt=json");
dynamic obj = JsonObject.Parse(json);
}
Ok looking at the responses it looks as though I need a C# class for the data returned in json. I have created a classes using json2csharp.com. This is the data I need to return from the Json and display on the page. Maybe it will help explain my problem better.
https://www.googleapis.com/shopping/search/v1/public/products?key=AIzaSyCC0j59RBeGNtf2W2ft6avhfoTdJ1FQ2c4&country=UK&q=BX80637153570K&rankBy=price:ascending&maxResults=1&alt=json
Can anyone advise how I can use this information on my website. I am a little lost now as I'm new to all this and have tried several different methods.I don't need all of the returned data if that makes a difference? Just price and link.
Supposing dynamic obj is rightly filled you can use it's content in web page
For examples, if json is:
{
"error" : {
"code": 400,
"message": "Bad Request"
}
}
You can access object properties with code like this:
Response.Write("Error code is" + obj.error.code);
Of course Response.Write is only a sample on how you can send retrieved data to the page.
Edit 1:
It seems json converter used in question is not working or not working right.
In many cases, it's overkill to create a concrete class only to parse a json, expecially since C# 4 that can use ExpandoObject
This is a sample on how you can deserialize in a dynamic object without the need to create a concrete object
var url = "http://www.google.com/ig/calculator?hl=en&q=100USD=?EUR";
string json = HttpGet(url);
//this is json string:
//{lhs: "100 U.S. dollars",rhs: "78.1799703 Euros",error: "",icc: true}
//now convert in a dynamic object
var jss = new DynamicJsonConverter();
var serializer = new JavaScriptSerializer();
serializer.RegisterConverters(new[] { new DynamicJsonConverter() });
dynamic obj = serializer.Deserialize(json, typeof(object));
//now you have access to json content
string text1 = obj.lhs;
string text2 = obj.rhs;
DynamicJsonConverter class can be created using code you can find here:
Deserialize JSON into C# dynamic object?
I think you need to deserialize the response
JavaScriptSerializer json_serializer = new JavaScriptSerializer();
You will need to create a class with the property resulted by the response.
Say test class
class Test
{
//define a similar property here
// which you suppose it will be return in the response
}
Then
Test routes_list = (Test)json_serializer.DeserializeObject(yourjson);
Edit 1
Or you can go through this link
How to Convert JSON object to Custom C# object?

Categories