How to Deserialize JSON - c#

I'm working on project in which I'm Posting data from asp.net webform to WCF service. I'm posting data through params and the service respond me back a JSON string. Now I have an issue in deserialize. I read many threads but didn't find any solution. Hope someone can sort out my problem. Thanks in Advance
Response from WCF
{"LoginResult":false}
I just want "false" value.
How I tried:
string URL = "http://localhost:32319/ServiceEmployeeLogin.svc";
WebRequest wrGETURL;
wrGETURL = WebRequest.Create(URL+"/"+emp_username+"/"+emp_password+"/"+emp_type);
wrGETURL.Method = "POST";
wrGETURL.ContentType = #"application/json; charset=utf-8";
HttpWebResponse webresponse = wrGETURL.GetResponse() as HttpWebResponse;
Encoding enc = System.Text.Encoding.GetEncoding("utf-8");
// read response stream from response object
StreamReader loResponseStream = new StreamReader(webresponse.GetResponseStream(), enc);
// read string from stream data
strResult = loResponseStream.ReadToEnd();
var jObj = JObject.Parse(strResult);
var dict = jObj["LoginResult"].Children().Cast<JProperty>();

You could use json.net to do it like this:
public class AuthResponse {
public bool LoginResult { get; set; }
}
var deserializedResponse = JsonConvert.DeserializeObject<AuthResponse>(strResult);
http://james.newtonking.com/json

.Net 4.5 has a JavaScriptSerializer, which should work as well:
public class AuthResponse {
public bool LoginResult { get; set; }
}
System.Web.Script.Serialization.JavaScriptSerializer sr = new System.Web.Script.Serialization.JavaScriptSerializer();
AuthResponse response = sr.Deserialize<AuthResponse>(responseText);
http://msdn.microsoft.com/en-us/library/system.web.script.serialization.javascriptserializer%28v=vs.110%29.aspx

Related

HTTP request with C#

I want to convert the Object received in the function and do as needed to convert it to an object ({"some_key": "some_value"}).
Here is my code:
public HttpRequests(string url, string method, Object data)
{
//The following prepares data, according to received parameter
if (data is Array)
{
data = (Array)data;
}
else if (data is Dictionary<Object, Object>)
{
data = ((Dictionary<string, string>)data)["something"] = platform_secret;
data = ((Dictionary<string, string>)data)["something2"] = "1";
}
method = method.ToUpper(); //POST or GET
this.url = just_url + url;
this.data = Newtonsoft.Json.JsonConvert.SerializeObject(data);
this.method = method;
}
public Object performRequest()
{
if (this.data != null && url != null)
{
WebRequest request = HttpWebRequest.Create(url);
byte[] data_bytes = Encoding.ASCII.GetBytes(Convert.ToChar(data)[]);
//^ this does not work. Am I supposed to do this?
// as I said, what I want is to get an object {key: something} that can be read
// by $_POST["key"] in the server
request.Method = method;
request.ContentType = "application/x-www-form-urlencoded"; //TODO: check
//request.ContentLength = ((Dictionary<string, string>) data);
request.ContentLength = data_bytes.Length;
Stream dataStream = request.GetRequestStream(); //TODO: not async at the moment
//{BEGIN DOUBT
dataStream.Write(data_bytes, 0, data_bytes.Length);
dataStream.Close();
//DOUBT: DO THIS ^ or THIS:_ ???
StreamWriter writer = new StreamWriter(dataStream);
writer.Write(this.data);
//End DOUBT}
WebResponse response = request.GetResponse();
Stream dataResponse = response.GetResponseStream();
writer.Close();
response.Close();
dataStream.Close();
return dataResponse.
}
What exactly am I missing here?
As you initially assign this.data = Newtonsoft.Json.JsonConvert.SerializeObject(data);, suppose his.data has type string (you can change if it is otherwise).
Then instead of byte[] data_bytes = Encoding.ASCII.GetBytes(Convert.ToChar(data)[]); you need to write just byte[] data_bytes = Encoding.ASCII.GetBytes(data);
After use this
//{BEGIN DOUBT
dataStream.Write(data_bytes, 0, data_bytes.Length);
dataStream.Close();
It will help to do the call with some data but it does not help to solve your problem. request.ContentType = "application/x-www-form-urlencoded"; does not expect that the data is Newtonsoft.Json.JsonConvert.SerializeObject serialized. It expects a string containing & separated pairs that are urlencoded.
name1=value1&name2=value2&name3=value3
So, you need to use this format instead of JSON.
You need to use the first piece of code. Here is and exmaple.
But the second piece could work too, I guess. You have missed nothing on C# side. A problem could be in the data you are going to transfer, however. If it is not correctly encoded, for example.
You should be doing something closer to the lines of this...
void Main()
{
var formSerializer = new FormEncodedSerializer();
formSerializer.Add("key", "value");
formSerializer.Add("foo", "rnd");
formSerializer.Add("bar", "random");
var uri = #"http://example.com";
var contentType = #"application/x-www-form-urlencoded";
var postData = formSerializer.Serialize();
var http = new Http();
Console.WriteLine (http.Post(uri, postData, contentType));
}
public class Http
{
public string Post(string url, string data, string format)
{
var content = Encoding.UTF8.GetBytes(data);
var contentLength = content.Length;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.ServicePoint.Expect100Continue = false;
request.Method = "POST";
request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
request.ContentType = format;
request.ContentLength = contentLength;
using (Stream requestStream = request.GetRequestStream())
{
requestStream.Write(content, 0, content.Length);
}
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
using (Stream responseStream = response.GetResponseStream())
using (StreamReader reader = new StreamReader(responseStream))
{
return reader.ReadToEnd();
}
}
}`
public class FormEncodedSerializer
{
private Dictionary<string, string> formKeysPairs;
public FormEncodedSerializer(): this(new Dictionary<string, string>())
{
}
public FormEncodedSerializer(Dictionary<string, string> kvp)
{
this.formKeysPairs = kvp;
}
public void Add(string key, string value)
{
formKeysPairs.Add(key, value);
}
public string Serialize()
{
return string.Join("", this.formKeysPairs.Select(f => string.Format("&{0}={1}", f.Key,f.Value))).Substring(1);
}
public void Clear()
{
this.formKeysPairs.Clear();
}
}
I did not really understand what your service expects, in which format you have to send the data.
Anyway, if you set ContentType like "application/x-www-form-urlencoded", you must encode your data with this format. You can simply do it with this code;
var values = ((Dictionary<string, string>)data).Aggregate(
new NameValueCollection(),
(seed, current) =>
{
seed.Add(current.Key, current.Value);
return seed;
});
So, your data is sent like "something=platform_secret&something2=1"
Now, you can send form data simply:
WebClient client = new WebClient();
var result = client.UploadValues(url, values);
I think your first function with signature public HttpRequests(string url, string method, Object data) dosn't seem have any logical error but in your second function with signature public Object performRequest() you have some issue:
if your HTTP method is GET you don't need to write content stream.
if your method is POST and your data are JSON you need setting up HTTP requester like this:
request.ContentType = "application/json";
and finally, flush your stream before you close it, like this request.Flush();

WebDAV get free space info

I'm working with Yandex Disk API (http://api.yandex.com/disk/doc/dg/reference/propfind_space-request.xml).
Having trouble with adding property in the request body (quota-available-bytes and quota-used-bytes)
public static string SpaceInfo(string path)
{
// Authorization.
HttpWebRequest webReq = (HttpWebRequest)WebRequest.Create("https://webdav.yandex.ru/");
webReq.Accept = "*/*";
webReq.Headers.Add("Depth: 0");
webReq.Headers.Add("Authorization: OAuth " + token);
webReq.Method = "PROPFIND";
// Adding data in body request.
string inputData = #"<D:propfind xmlns:D=""DAV:""><D:prop><quota-available-bytes/></D:prop></D:propfind>";
byte[] buffer = new ASCIIEncoding().GetBytes(inputData);
webReq.ContentType = "text/xml; encoding='utf-8";
webReq.ContentLength = buffer.Length;
try
{
HttpWebResponse resp = (HttpWebResponse)webReq.GetResponse();
StreamReader sr = new StreamReader(resp.GetResponseStream());
string dinfo = sr.ReadToEnd();
return dinfo;
}
}
I don't get any response, maybe i can use another method? What should i do?
Thanks!
quota-available-bytes should use same namespace "D"

Poor performance when parsing JSON - JsonTextWriter as an alternative?

I'm using the code below to parse a JSON response back from the server. It's a little slow. I'm wanting to know if I should be using the JsonTextWriter as an alternative?
How would I implement this using the JsonTextWriter?
string responseString = string.Empty;
Uri uri = new Uri ("http://localhost/complex-json.json");
HttpWebRequest request = new HttpWebRequest (uri);
request.Method = "GET";
HttpWebResponse response = request.GetResponse () as HttpWebResponse;
using (StreamReader sr = new StreamReader(response.GetResponseStream())) {
responseString = sr.ReadToEnd ();
}
response.Close ();
JObject obj = JObject.Parse (responseString);
JArray a = (JArray)obj["questions"];
IList<question> questions = a.ToObject<IList<question>>();
for (int i = 0; i < a.Count; i++) {
Console.WriteLine(questions[0].answer_count);
}
System.Web.Extensions.dll has a JavaScriptSerializer. I use the following 2 extension methods to serialize and deserialize:
public static T JsonDeserialize<T>(this string json)
{
return new JavaScriptSerializer().Deserialize<T>(json);
}
public static string ToJson<T>(this T item)
{
return new JavaScriptSerializer().Serialize(item);
}
Hope this helps.

How do I get a JSON response after put/post from MVC

I have a jquery routine that calls an MVC action which will do a PUT/POST to an API url. The call from jQuery is fine and works as well as the call to the API using C#. A response is received from the API in JSON format when checked via Firebug/Fiddler.
How do i get that response to be sent back to the calling jQuery?
My C# code is:
public string callAPIPut(string ApiUrl, string JsonString)
{
WebRequest request = WebRequest.Create(ApiUrl);
ASCIIEncoding encoding = new ASCIIEncoding();
byte[] data = encoding.GetBytes(JsonString);
request.ContentType = "application/json; charset=utf-8";
request.Method = WebRequestMethods.Http.Put;
request.ContentLength = JsonString.Length;
Stream newStream = request.GetRequestStream();
newStream.Write(data, 0, JsonString.Length);
newStream.Close();
return ""; // How do I return the JSON response from the API?
}
When doing a GET i could use something like the following to get the response back to the calling jQuery:
response = (HttpWebResponse)request.GetResponse();
using (StreamReader sr = new StreamReader(response.GetResponseStream()))
{
serviceResponse = sr.ReadToEnd();
}
return serviceResponse;
I dont know how to return the response when doing a Put/Post?
public ActionResult CallAPIPut(string ApiUrl, string JsonString)
{
using (var client = new WebClient())
{
client.Headers[HttpRequestHeader.ContentType] = "application/json";
byte[] data = Encoding.Default.GetBytes(JsonString);
byte[] result = client.UploadData(ApiUrl, "PUT", data);
return Content(Encoding.Default.GetString(result), "application/json");
}
}
or make it more intelligently, by wrapping in a custom and reusable action result to avoid cluttering your controller with infrastructure plumbing:
public class ApiResult : ActionResult
{
public ApiResult(string apiUrl, string jsonData)
: this(apiUrl, jsonData, "PUT")
{
}
public ApiResult(string apiUrl, string jsonData, string method)
{
ApiUrl = apiUrl;
JsonData = jsonData;
Method = method;
}
public string ApiUrl { get; private set; }
public string JsonData { get; private set; }
public string Method { get; set; }
public override void ExecuteResult(ControllerContext context)
{
var response = context.HttpContext.Response;
var contentType = "application/json";
response.ContentType = contentType;
using (var client = new WebClient())
{
client.Headers[HttpRequestHeader.ContentType] = contentType;
byte[] data = Encoding.Default.GetBytes(JsonData);
byte[] result = client.UploadData(ApiUrl, Method, data);
response.Write(Encoding.Default.GetString(result));
}
}
}
and now your controller action simply becomes:
public ActionResult CallAPIPut(string apiUrl, string jsonString)
{
return new ApiResult(apiUrl, jsonString);
}
Stream newStream = request.GetRequestStream();
newStream.Write(data, 0, JsonString.Length);
newStream.Close();
You're posting JSON to the server. To get JSON you need to post/put and use the ResponseStream to read the data the server returned.
A sample:
using System;
using System.IO;
using System.Net;
using System.Text;
namespace Examples.System.Net
{
public class WebRequestGetExample
{
public static void Main ()
{
// Create a request for the URL.
WebRequest request = WebRequest.Create (
"http://www.contoso.com/default.html");
// If required by the server, set the credentials.
request.Credentials = CredentialCache.DefaultCredentials;
// Get the response.
WebResponse response = request.GetResponse ();
// Display the status.
Console.WriteLine (((HttpWebResponse)response).StatusDescription);
// Get the stream containing content returned by the server.
Stream dataStream = response.GetResponseStream ();
// Open the stream using a StreamReader for easy access.
StreamReader reader = new StreamReader (dataStream);
// Read the content.
string responseFromServer = reader.ReadToEnd ();
// Display the content.
Console.WriteLine (responseFromServer);
// Clean up the streams and the response.
reader.Close ();
response.Close ();
}
}
}
Sample from http://msdn.microsoft.com/en-us/library/456dfw4f.aspx
Edit: You would return the responseFromServer and consume that in you're Javascript callback.

Parsing json objects

I'm having trouble understanding how to parse JSON string into c# objects with Visual .NET. The task is very easy, but I'm still lost...
I get this string:
{"single_token":"842269070","username":"example123","version":1.1}
And this is the code where I try to desterilize:
namespace _SampleProject
{
public partial class Downloader : Form
{
public Downloader(string url, bool showTags = false)
{
InitializeComponent();
WebClient client = new WebClient();
string jsonURL = "http://localhost/jev";
source = client.DownloadString(jsonURL);
richTextBox1.Text = source;
JavaScriptSerializer parser = new JavaScriptSerializer();
parser.Deserialize<???>(source);
}
I don't know what to put between the '<' and '>', and from what I've read online I have to create a new class for it..? Also, how do I get the output?
An example would be helpful!
Create a new class that your JSON can be deserialized into such as:
public class UserInfo
{
public string single_token { get; set; }
public string username { get; set; }
public string version { get; set; }
}
public partial class Downloader : Form
{
public Downloader(string url, bool showTags = false)
{
InitializeComponent();
WebClient client = new WebClient();
string jsonURL = "http://localhost/jev";
source = client.DownloadString(jsonURL);
richTextBox1.Text = source;
JavaScriptSerializer parser = new JavaScriptSerializer();
var info = parser.Deserialize<UserInfo>(source);
// use deserialized info object
}
}
If you're using .NET 4 - use the dynamic datatype.
http://msdn.microsoft.com/en-us/library/dd264736.aspx
string json = "{ single_token:'842269070', username: 'example123', version:1.1}";
JavaScriptSerializer jss = new JavaScriptSerializer();
dynamic obj = jss.Deserialize<dynamic>(json);
Response.Write(obj["single_token"]);
Response.Write(obj["username"]);
Response.Write(obj["version"]);
Yes, you need a new class with properties that will match your JSON.
MyNewClass result = parser.Deserialize<MyNewClass>(source);
The usual way would be create a class (or a set of classes, for more complex JSON strings) that describes the object you want to deserialize and use that as the generic parameter.
Another option is to deserialize the JSON into a Dictionary<string, object>:
parser.Deserialize<Dictionary<string, object>>(source);
This way, you can access the data, but I wouldn't suggest you to do this unless you have to.
You need a Class that match with the JSON you are getting and it will return a new object of that class with the values populated.
Following is the code..
ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(AcceptAllCertifications);
request = WebRequest.Create("https://myipaddress/api/admin/configuration/v1/conference/1/");
request.Credentials = new NetworkCredential("admin", "admin123");
// Create POST data and convert it to a byte array.
request.Method = "GET";
// Set the ContentType property of the WebRequest.
request.ContentType = "application/json; charset=utf-8";
WebResponse response = request.GetResponse();
// Display the status.
Console.WriteLine(((HttpWebResponse)response).StatusDescription);
// Get the stream containing content returned by the server.
dataStream = response.GetResponseStream();
// Open the stream using a StreamReader for easy access.
StreamReader reader = new StreamReader(dataStream);
// Read the content.
string responseFromServer = reader.ReadToEnd();
JavaScriptSerializer js = new JavaScriptSerializer();
var obj = js.Deserialize<dynamic>(responseFromServer);
Label1.Text = obj["name"];
// Display the content.
Console.WriteLine(responseFromServer);
// Clean up the streams.
reader.Close();
dataStream.Close();
response.Close();
dynamic data = JObject.Parse(jsString);
var value= data["value"];

Categories