Return json without binding it to object using web client - c#

I want to simply return a JsonResult in C# from an online API service (iTunes). What I am wanting to do is just go out get the data in JSON format and return that exact data in the same JSON format so I can play with it in javascript.
Here is what I have:
public JsonResult Index()
{
using (var client = new WebClient())
{
var json = client.DownloadString("https://itunes.apple.com/lookup?id=909253");
return json;
}
}
I am noticing I can't return the json because it is now a string. I don't want to bind this to a model!!! I just want to return a JSON object exactly how I got it.

Change your method signature to return a string instead of a JsonResult object…
public string Index()
{
using (var client = new WebClient())
{
return client.DownloadString("https://itunes.apple.com/lookup?id=909253");
}
}

Already given answer is ok to get json in javascript.. javasript will treat this string same as if your return json object..
However if you have to get a json object from string in c# anyway then check the accepted answer here
Parse JSON String to JSON Object in C#.NET

Related

JsonDeserializer check before try to convert Model

Read simple api call code bellow. Here i am getting call response in- IRestResponse response and its a json response. Then using JsonDeserializer() i am trying to convert it to a C# Model which is WallMartData model. ( i think i dont need to share model code here bcoz it doesn't matter for this question ). Now from this same response sometime i will get a json response which match with my model WallMartData and some time it will return other json response. Now my question is- before i try to convert my json response to WallMartData Model i want to check if this is a valid convertable json. If its not valid convartable for this WallMartData model then it will skip try to convert. Bcoz when its fails to convert i am getting invalid json exception on c#. Thats why i need to check before try to convert. Any solution?
string url = "http://api.example.com/v1/items?apiKey=" + Token + "&upc=" + UPC;
var client = new RestClient(url);
var request = new RestRequest(Method.GET);
IRestResponse response = client.Execute(request);
var deserializer = new JsonDeserializer();
var wmr = deserializer.Deserialize<WallMartData>(response);
You can try to create a method use try .... catch to check the JSON string is or isn't valid.
private static bool IsValidJson<T>(string strInput,out T obj)
{
obj = default(T);
try
{
obj = JsonConvert.DeserializeObject<T>(strInput);
return true;
}
catch (JsonReaderException jex)
{
return false;
}
catch (Exception ex)
{
return false;
}
}
Then you can use bool to check the DeserializeObject whether success.
WallMartData wmr;
if(IsValidJson<WallMartData>(response,out wmr)){
//... your logic with wmr
}
I think you can just use try catch block and it will be enough. But if you really need to validate your JSON, you can use JSON Schema. You can generate schema for your class using JsonSchemaGenerator
I suggest using JsonSchema by Json.Net
more info here
let's say that your WallMartData class looks like this
public class WallMartData
{
[JsonProperty("email", Required = Required.Always)]
public string Email;
[JsonProperty("first_name")]
public string firstName;
[JsonProperty("last_name")]
public string lastName;
}
Then you can easily use the schema checker
JSchemaGenerator generator = new JSchemaGenerator();
JSchema schema = generator.Generate(typeof(WallMartData));
string json = #"...";
JObject wallMartData = JObject.Parse(json);
if(wallMartData.IsValid(schema))
{
//if json matching the schema aka the class account
}
else
{
//the json is invalid
}

Hook OData's $metadata response and convert it from XML to JSON

The answer of Get OData $metadata in JSON format states that OData cannot return the metadata as JSON by default.
But is it possible then to capture or hook its response for the $metadata URL, and then convert it on the fly to JSON before sending it to the client?
I imagine pseudocode like this:
[HttpGet]
[ODataRoute("$metadata")]
public string GetMetadataAsJson()
{
string xml = GetOdataMetadataAsXML();
string json = ConvertToJson(xml);
return json;
}
I don't know how to implement it correctly, though, in particular I'm not sure how to get the standard OData response as a string, and how to hook the $metadata URL.
Newtonsoft supports the Json part checkout https://www.newtonsoft.com/json/help/html/ConvertXmlToJson.htm
So the actual solution for the Json Part would be quite simple, as soon as you have your XML
[HttpGet]
[ODataRoute("$metadata")]
public string GetMetadataAsJson()
{
string xml = GetOdataMetadataAsXML();
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
string json = JsonConvert.SerializeXmlNode(doc);
return json;
}
Also you should probably first check if e.g. a format query is set for example with this code
[HttpGet]
[ODataRoute("$metadata")]
public string GetMetadataAsJson([FromQuery(Name="Format")]string format)
{
string metaResult = GetOdataMetadataAsXML();
if(format.Equals("json",StringComparison.OrdinalIgnoreCase))
{
XmlDocument metaDoc = new XmlDocument();
doc.LoadXml(metaResult);
metaResult = JsonConvert.SerializeXmlNode(doc);
}
return metaResult;
}

Parse JSON response where the object starts with a number in c#

I'm trying to deserialise a response from a REST service into C# Strongly typed classes - however I've ran into the same issue has in this post:
How do I output this JSON value where the key starts with a number?
However I have the issue that you cannot start a variable name in c# with a number - meaning that the class at that level just deserialises into null.
I need to know how to get into the objects and deserialise them into the c# classes.
My Current code is below:
public static async Task<T> MakeAPIGetRequest<T>(string uri)
{
Uri requestURI = new Uri(uri);
using (HttpClient client = new HttpClient())
{
HttpResponseMessage responseGet = await client.GetAsync(requestURI);
if (responseGet.StatusCode != HttpStatusCode.OK)
{
throw new Exception(String.Format(
"Server error (HTTP {0}: {1}).",
responseGet.StatusCode,
responseGet.Content));
}
else
{
string response = await responseGet.Content.ReadAsStringAsync();
T objects = (JsonConvert.DeserializeObject<T>(response));
return objects;
}
}
}
EDIT: I cannot change the way the service is pushing the data back
The correct way to deal with this was to use the JsonProperty tag on the target classes to define what Json property to listen for, as shown below (referenced from https://stackoverflow.com/questions/24218536/deserialize-json-that-has-some-property-name-starting-with-a-number
public class MyClass
{
[JsonProperty(PropertyName = "24hhigh")]
public string Highest { get; set; }
...
Thanks to #HebeleHododo for the comment answer
While there is no direct way to construct a strongly typed C# object in this case, You could still have the capabilities to parse the json string manually and extract values -
var json = "{'1':{'name':'test','age':'test'}}";
var t = JObject.Parse(json)["1"];
Console.WriteLine(t["name"]); //test
Console.WriteLine(t["age"]); //test

Consuming json input from url ,deserialize into c# & retrieve values from web API

I have been stuck in trying figure out the syntax for a particular scenario.
Scenario: When I give a JSON string as argument in the URL, I want the url to consume an API and retrieve the details from that API, as per the given input.
My project needs deserialization into c# so, I used JSON.NET for the same.
Say: input is - Profile-id : 123456789
The output should consume details pertaining to that Pid and display.
The i/p given in url:
https://www.docscores.com/widget/api/org-profile/demo-health/npi/123456789
The expected o/p:
json string
What i have been doing is :
string url = "https://www.docscores.com/widget/api/org-profile/demo-health/npi/?profile-id=ShowProfile";
string data = GET(url);
dynamic jsonDe = JsonConvert.DeserializeObject(data);
var phyRatings = Convert.ToString(jsonDe.profile.averageRating);
Console.WriteLine(phyRatings);
public string ShowProfile(string pid)
{
}
public static string GET(string url)
{
try
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream stream = response.GetResponseStream();
StreamReader reader = new StreamReader(stream);
string data = reader.ReadToEnd();
reader.Close();
stream.Close();
return data;
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
return null;
}
So, when I pass profile-id as 123456789 in the url, I want the syntax to extract other info with this Profile-id
I AM totally confused with the syntax in C#. How can I pass the argument and write inside the ShowProfile function? I searched everywhere but not able to find the correct syntax.
Can someone please tell me if this is the right way to do it?
EDIT: Sounds like you have two questions here. First is how to pass your Profile-Id in the URL, and the second is how to deserialize the JSON result into a C# object. But let me know if I'm misunderstanding.
For passing 123456789 as your profile ID, you just need to concatenate it into the URL string. So you might have
public string ShowProfile(string pid)
{
ProfileInfo info = GET(pid);
// Do what you want with the info here.
}
public static ProfileInfo GET(int profileId)
{
try
// Note this ends in "=" now.
string basePath = "/widget/api/org-profile/demo-health/npi/?profile-id=";
string path = basePath + profileId.ToString();
//...
ProfileInfo would be your custom class to match the JSON structure.
Then to deserialize the result, in your GET() method, you might instead try calling the service using HttpClient from the Microsoft.AspNet.WebApi.Client NuGet package, and then read that directly into a C# object whose structure maps to the JSON response you get (see example below). Your GET() method could then return that object, and then it'd be trivial for the ShowProfile() method to read the properties you want from that C# object.
public static ProfileInfo GET(int profileId)
{
try
{
// Note this ends in "=" now.
string basePath = "/widget/api/org-profile/demo-health/npi/?profile-id=";
string path = basePath + profileId.ToString();
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("https://www.docscores.com");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = await client.GetAsync(path);
if (response.IsSuccessStatusCode)
{
ProfileInfo info = await response.Content.ReadAsAsync<ProfileInfo>();
return info;
}
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
return null;
}
More code and info at MSDN: Calling a Web API From a .NET Client in ASP.NET Web API 2 (C#)

Deserializing the object inside an http post

Hi I am trying to deserialize an Object from a HttpPost method call inside an authorize attribute.I am using ASP.NET Web Api Framework.
Here is my code:
public override void OnAuthorization(HttpActionContext actionContext)
{
var rezult = DeserializeStream<EvaluationFormDataContract>(actionContext.Request.Content.ReadAsStreamAsync().Result);
}
private T DeserializeStream<T>(Stream stream)
{
var binaryFormatter = new BinaryFormatter();
var rez = binaryFormatter.Deserialize(stream);
var t = (T)binaryFormatter.Deserialize(stream);
return t;
}
When this code gets executed I get this exception when the binaryFormatter tryes to deserialize it:
The input stream is not a valid binary format. The starting contents (in bytes) are: 73-74-75-64-65-6E-74-41-73-73-69-67-6E-6D-65-6E-74 ...
What am I doing wrong?
You are trying to use BinaryFormatter to binary deserialize data which was not binary serialized. From data you sent I see that hex code represents a string.
73-74-75-64-65-6E-74-41-73-73-69-67-6E-6D-65-6E-74 decoded is studentAssignment
This leads me to believe you are doing a simple AJAX call and sending JSON data to WebAPI service.
You need to deserialize the stream using JSON.
Read request content as string
If content is JSON, deserialize it using JSON.NET
var json = actionContext.Request.Content.ReadAsStringAsync().Result;
var m = JsonConvert.DeserializeObject<EvaluationFormDataContract>(json);
If response is not JSON, but form data you can parse it like a query string.
var stringData = actionContext.Request.Content.ReadAsStringAsync().Result;
NameValueCollection data = HttpUtility.ParseQueryString(stringData);
string personId = data["personId"];

Categories

Resources