unexpected http get request using JsonServiceClient - c#

I am trying to make a json request on an external service, that would look like this :
GET request :
https://remotehost/path/mycount?foo=C&bar=21
response :
{"count":1000}
for this I use ServiceStack JsonServiceClient, which I like because you can pass a object as parameter. this makes it easy to use/read.
Here is my code :
var client = new JsonServiceClient(classifiedSearchBaseURL);
var response = client.Get<CountResponse>(
new MyRequest
{
foo = "C",
bar = 21
});
class MyRequest
{
public string foo { get; set; }
public int bar { get; set; }
}
class CountResponse
{
public string count;
}
But when debugging, instead of getting this http request to the server
GET /path/mycount?foo=C&bar=21
I am getting this
GET /path/json/reply/MyRequest?foo=C&bar=21
Any of you guys has an idea?
Thanks for your help!

The answer is that I should use the Route attribute to the Request object
Following is the modified code
[ServiceStack.Route("/mycount")]
class MyRequest
{
public string foo { get; set; }
public int bar { get; set; }
}

Related

C# JSON URL get data

Im new to System.Net with C#
I want a way to get info from this website api: https://fn-api.glitch.me/api/aes
from its json to a C# string
I have this so far
I don't know how to get each item and where to put the url (im really new to this).
I want the url in a string:
public class Data
{
public string build { get; set; }
public string netCL { get; set; }
public string manifestID { get; set; }
public string aes { get; set; }
}
public class RootObject
{
public Data data { get; set; }
}
Okay, this is how you get about it. I am showing you an example using HttpClient to first read the content from the API and then de-serialize it using Newtonsoft package.
HttpClient class:
public class HttpClientFactory
{
private string webServiceUrl = "https://fn-api.glitch.me/";
public HttpClient CreateClient()
{
var client = new HttpClient();
SetupClientDefaults(client);
return client;
}
protected virtual void SetupClientDefaults(HttpClient client)
{
//This is global for all REST web service calls
client.Timeout = TimeSpan.FromSeconds(60);
client.BaseAddress = new Uri(webServiceUrl);
}
}
Your Model class:
public class Data
{
public string build { get; set; }
public string netCL { get; set; }
public string manifestID { get; set; }
public string aes { get; set; }
}
public class RootObject
{
public Data data { get; set; }
}
Now, you can call this class and create an instance of the HttpClient like this:
public RootObject InvokeAPI()
{
RootObject apiresponse = new RootObject();
string result = string.Empty;
HttpClientFactory clientFactory = new HttpClientFactory();
var client = clientFactory.CreateClient();
HttpResponseMessage response = client.GetAsync("api/aes").Result;
if (response.IsSuccessStatusCode)
{
result = response.Content.ReadAsStringAsync().Result;
apiresponse = JsonConvert.DeserializeObject<RootObject>(result);
}
return apiresponse;
}
Hope this helps you out.
EDIT:
As per your code, you need to call the API on your Button click:
private void metroButton2_Click_1(object sender, EventArgs e)
{
//You need to invoke the API method !!!!
var apiresponse=InvokeAPI();
metroTextBox1.Text = apiresponse.data.aes;
}
Be sure to put try-catch blocks on your code for error handling.
I'd recommend using a 3rd party library like RestSharp. It'll give you a client that's easy to work with and does the converting into objects automatically.
Alternatively you could use the WebClient and download the JSON. Using something like Json.NET allows you to deserialize the JSON into an object.
Easiest way to read from a URL into a string in .NET
I use JSON.Net.

Unable to deserialize list in a XML Response using ReadAsAsync<T>

[Update: This question is different from the suggested duplicate because this one is about deserialization of XML and the explanation of the problem and solution on this one is clearer as I've included the full source code.]
I'm trying to read and subsequently manipulate a response from a Web API. Its response looks like this:
<MYAPI xsi:noNamespaceSchemaLocation="MYAPI.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<MySite Resource="some resource name">
<Name>some name</Name>
<URL>some url</URL>
<SecondName>Describes something</SecondName>
</MySite>
... A lot of these <MySite>...</MySite> are there
<SomeOtherSite Resource="some resource name">
<Name>some name</Name>
<URL>some url</URL>
</SomeOtherSite>
</MYAPI>
SomeOtherSite is not repeating and only one of it appears at the end of the response. But the MySite is the one that is repeating.
I've modeled the class for this XML response as:
public class MYAPI
{
public List<MySite> MySite { get; set; }
public SomeOtherSite SomeOtherSite { get; set; }
}
public class MySite
{
public string Name { get; set; }
public string URL { get; set; }
public string SecondName { get; set; }
}
public class SomeOtherSite
{
public string Name { get; set; }
public string URL { get; set; }
}
And this is my code:
static void Main()
{
var handler = new HttpClientHandler();
handler.Credentials = new NetworkCredential("MyUsername", "MyPassword");
var client = new HttpClient(handler);
client.BaseAddress = new Uri("https://sitename.com:PortNumber/");
var formatters = new List<MediaTypeFormatter>()
{
new XmlMediaTypeFormatter(){ UseXmlSerializer = true }
};
var myApi = new MYAPI();
HttpResponseMessage response = client.GetAsync("/api/mysites").Result;
if (response.IsSuccessStatusCode)
{
myApi = response.Content.ReadAsAsync<MYAPI>(formatters).Result;
}
}
Now the myApi only has object for SomeOtherSite but the list for the MySite is empty.
Would someone please tell me how I should deserialize this response correctly?
Should I be creating custom media formatter? I have no idea of it by the way.
Also would you please tell me how to model that Resource attribute coming in the response?
And I can't change anything in the WebAPI server. I just need to consume the data from it and use it elsewhere.
Thank You so much!
I solved this after some really good direction from: https://stackoverflow.com/users/1124565/amura-cxg Much Thanks!
The solution was to annotate all the properties with XMLAttributes. And it correctly deserialized the response. And as for the Resource attribute, all I needed was [XmlAttribute(AttributeName="Resource")]
The rest of the source code works as is.
[XmlRoot(ElementName="MYAPI")]
public class MYAPI
{
[XmlElement(ElementName="MySite")]
public List<MySite> MySite { get; set; }
[XmlElement(ElementName="SomeOtherSite")]
public SomeOtherSite SomeOtherSite { get; set; }
}
public class MySite
{
[XmlElement(ElementName="Name")]
public string Name { get; set; }
[XmlElement(ElementName="URL")]
public string URL { get; set; }
[XmlElement(ElementName="SecondName")]
public string SecondName { get; set; }
[XmlAttribute(AttributeName="Resource")]
public string Resource { get; set; }
}
Plus, I didn't need any custom media formatter. And from one of the posts by https://stackoverflow.com/users/1855967/elisabeth , I learned that we should not touch the generated file from xsd.exe tool. So I explicitly set to use the XmlSerializer instead of the DataContractSerializer used by default:
var formatters = new List<MediaTypeFormatter>()
{
new XmlMediaTypeFormatter(){ UseXmlSerializer = true }
};

JsonServiceClient returns reponse with correct attribute but empty value

I am trying to make a JSON request on an external service, that would look like this :
GET request :
https://remotehost/path/mycount?foo=C&bar=21
response :
{"count":1000}
for this, I use ServiceStack JsonServiceClient, here is my code below
var client = new JsonServiceClient(classifiedSearchBaseURL);
var response = client.Get<CountResponse>(new MyRequest {
foo = "C",
bar = 21
});
class MyRequest
{
public string foo { get; set; }
public int bar { get; set; }
}
class CountResponse
{
public string count;
}
The problem is that I get a response object with an attribute "count" that is null, even though the server answers a 200 with a correct value/response (using Fiddler)
I tried changing the type of count from string to int but then I get 0 instead of null.
Any of you guys have an idea?
Thanks for your help!
ServiceStack only serializes public properties by default so you need to change your Response DTO to:
class CountResponse
{
public string count { get; set; }
}
I'd also recommend adding the IReturn<T> marker interfaces like:
class MyRequest : IReturn<CountResponse>
{
public string foo { get; set; }
public int bar { get; set; }
}
So the Response Type can be automatically inferred by the client so your call sites can be reduced to:
var response = client.Get(new MyRequest { foo = "C", bar = 21 });

Deserializing rest client response from wordpress.org

I have a wordpress.org locally hosted on my pc.
I've installed a wordpress plugin called json-api which let you retrieve posts from your wordpress site.
I'm running the following code:
var client = new RestClient(BlogArticlesUrl);
var request = new RestRequest();
request.Timeout = 5000;
request.RequestFormat = DataFormat.Json;
request.Method = Method.GET;
request.AddParameter("json", "get_tag_posts");
request.AddParameter("slug", "featured");
request.AddParameter("count", "3");
var articles = client.Execute<List<BlogArticleModel>>(request);
After executing the code, in the variable articles I have the following:
Inside the Content there are few keys but I would only like to convert 'posts' to a model in c#
How do I acheive that?
EDIT:
I have found a solution using newtonsoft for dot net
Newtonsoft.Json.JsonConvert.DeserializeObject<BlogArticleResponse>(articles.Content);
In RestSharp, the Content is what gets deserialized. So, the type you pass into the .Execute<T> method must be the same structure as the response.
In your case, it will look something like this:
public class BlogArticleResponse
{
public string status { get; set; }
public int count { get; set; }
public int pages { get; set; }
public BlogTag tag { get; set; }
...
}
public class BlogTag
{
public int id { get; set; }
public string slug { get; set; }
public string title { get; set; }
public string description { get; set; }
...
}
You can then execute the request like this:
var result = client.Execute<BlogArticleResponse>(request);
For more information, have a look at the documentation.

RESTSharp: Access values from deserialized class

I am using RESTSharp to receive and deserialize result from an API call. Response is JSON. I've created a class for the repsonse that looks like this:
public class JsonResponseClass
{
public class Selector
{
public static string verb { get; set; }
}
public class Points
{
public int definition { get; set; }
}
}
I do following to get the response:
var response = client.Execute<JsonResponseClass>(request);
var resData = response.Data;
How do I read/print values received from above? For example how do I print values verb and definition from the above deserialized response?
You're not supposed to nest the classes. Instead, add a property of each type to the root object's class.
public class JsonResponseClass
{
public Selector selector { get; set; }
public Points points { get; set; }
}
public class Selector
{
public static string verb { get; set; }
}
public class Points
{
public int definition { get; set; }
}
With that in place, the code works as expected:
var response = client.Execute<JsonResponseClass>(request);
var resData = response.Data;
var verb = resData.selector.verb;
var definition = resData.points.definition;
It's not clear what are you asking.
resData variable contains data from request stored in JsonResponseClass so you need to access it's fields like:
string verb = resData.verb;
Console.WriteLine(verb);

Categories

Resources