converting mashape api response to c# class - c#

I am using mashape api for getting the speed post tracking information:-
https://www.mashape.com/blaazetech/indian-post
As this is in .NET c# following code is not getting complied:-
Task<HttpResponse<MyClass>> response = Unirest.get("https://indianpost.p.mashape.com/index.php?itemno=EF990403084IN")
.header("X-Mashape-Key", mykey)
.header("Accept", "application/json")
.asJson();
the complie error is "The type arguments for method 'unirest_net.request.HttpRequest.asJson()' cannot be inferred from the usage. Try specifying the type arguments explicitly."
I am not sure how this api can be consumed. Is it problem with "MyClass" and what?

RSDC - Ok, turns out that your API endpoints for Indian-Post don't work anyways. Tested them on Mashape and it returns error.
>>> I got it working for the metaCritic GET API <<<
https://www.mashape.com/byroredux/metacritic (Game List API, 2nd one down)
re: MyClass
1) On the mashape.com site in the API documentation page, find the 200/JSON response on the right side.
2) Copy the json data
3) go to http://json2csharp.com/ and paste the code
4) click Generate button to get c# class code. Copy the class code.
5) back in VS, go to Models folder and create class called MyClass.cs.
6) paste your code in as such:
public class MyClass
{
public class Result
{
public string name { get; set; }
public string score { get; set; }
public string url { get; set; }
public string rlsdate { get; set; }
public string rating { get; set; }
public string summary { get; set; }
public string platform { get; set; }
}
public class RootObject
{
public List<Result> results { get; set; }
}
}
7) Try this:
HttpResponse<MyClass.RootObject> response = Unirest.get("https://byroredux-metacritic.p.mashape.com/game-list/ps4/coming-soon")
.header("X-Mashape-Key", "KxdVFN6Vlymshd5ezOQwBvS2Svjtp1bq5YOjsnFOkgTOwqwM6y")
.header("Accept", "application/json")
.asJson<MyClass.RootObject>();
If you run the debugger, you can see that response > Body > results now holds 25 items of data.

Related

Get value from Json url with a changing variable

I want to get the price of any crypto coin from BitZ api.
I have the code like this:
string coinName;
string jsonURL = "https://apiv2.bitz.com/Market/coinRate?coins=" + coinName;
I will give the variable coinName the value I want for example coinName = "btc" and I want the price in USDT
The problem here is the Json structure it contains the coin name I will end up with tons of code lines if do this for every coin,
public class Btc
{
public string usdt { get; set; }
}
public class Data
{
public Btc btc { get; set; }
}
public class Root
{
public int status { get; set; }
public string msg { get; set; }
public Data data { get; set; }
public int time { get; set; }
public string microtime { get; set; }
public string source { get; set; }
}
Unlike Bittrex api for example which is easier to read using JsonDotNet asset from unity store and :
BittrexJsonUrl = "https://api.bittrex.com/api/v1.1/public/getticker?market=USDT-" + coinName;
and then I use this code to get the data:
private IEnumerator GetData()
{
/////bittrex
UnityWebRequest request = UnityWebRequest.Get(BittrexJsonUrl);
yield return request.SendWebRequest();
if (request.error == null)
{
Bittrex_proccessJsonData(request.downloadHandler.text);
}
else
{
Debug.Log("Something went wrong!!");
}
}
private void Bittrex_proccessJsonData (string _url) {
var _bittrexJsonData = JsonConvert.DeserializeObject<BittrexJsonData>(_url);
bittrexPrice = _bittrexJsonData.result.Last;
}
this works perfectly with with bittrex's Json structure, since it doesnt contain the coin name all I do is change the Json URL.
Now I want to do like the same thing for BitZ's if you have any idea how to please help :) thank you in advance.
For such thing you could use good old SimpleJson.
Here you don't need to implement the entire c# structure but rather access the data field by field via it's ID. You can imagine it like a nested Dictionary like thing.
Simply create that file with given content from the link somewhere in your project and do e.g.
var json = JSON.Parse(the_JSON_string);
var usdt = json["Data"]["bst"]["usdt"].AsFloat;

POST request with JSON Body Serialization

I have one specific issue, which I'm not able to handle.
I'm using HTTP Get API request and I'm getting JSON string, which I'm deserializing, this works perfectly. But then, I need to reuse just two pairs of this JSON file, but it needs to be pasted as JSON body for POST request. Let me show you the example:
Output of GET API Request:
{
"message":{
"value":[
{
"Reference":null,
"Key":"abc",
"IssueNumber":123
},
{
"Reference":null,
"Key":"def",
"IssueNumber":345
}
]
}
}
So now Im able to deserialize this JSON string (i.e.: jsonString("value)(0)("Key") and I will get "abc").
But now, I have no idea, how to serialize this deserialized object to use ReviewStatus and Key. This POST request JSON body looks like that:
{
"newStatus":"New"
"queueItems": [
{
"Key":"abc"
"IssueNumber":123
},
{
"Key":"def"
"IssueNumber":456
}
]
}
For loop works for me, but in that case, I will do API call for each item instead of doing just one POST API call. What would be the best solution in your opinion? I was trying to use Newtonsoft.Json.JsonConvert (SerializeObject Method), but it didn't work for me as I expected. I'm pretty sure, that there needs to be something much easier, but I need your help.
Thanks for any advice.
Frantisek
You can try to write two split species models, one for Receive JSON Modle, another for Response JSON Model.
Receive Modle
public class Value
{
public object Reference { get; set; }
public string Key { get; set; }
public int IssueNumber { get; set; }
}
public class Message
{
public List<Value> value { get; set; }
}
public class ReciveModel
{
public Message message { get; set; }
}
Response Model
public class QueueItem
{
public string Key { get; set; }
public int IssueNumber { get; set; }
}
public class ResponseModel
{
public string newStatus { get; set; }
public List<QueueItem> queueItems { get; set; }
}
Receive your JSON data and Deserialize to ReciveModel object, then let the data into another instance ResponseModel
final, you use JsonConvert.SerializeObject to serialize then instance to be JSON data.
var obj = JsonConvert.DeserializeObject<ReciveModel>(JsonData);
var res = new ResponseModel() {
newStatus = "New",
queueItems = obj.message.value.Select(x => new QueueItem() {
IssueNumber = x.IssueNumber,
Key = x.Key
}).ToList()
};
var jsonResult = JsonConvert.SerializeObject(res);
Result
{"newStatus":"New","queueItems":[{"Key":"abc","IssueNumber":123},{"Key":"def","IssueNumber":345}]}
c# online
Note
There are two way can create model easily.
You can use Web Essentials in Visual Studio, use Edit > Paste special > paste JSON as class, you can easier to know the relation between Json and model.
If you can't use Web Essentials you can instead of use http://json2csharp.com/ online JSON to Model class.
You can try to use those models to carry your JSON Format.

Rest exception: Unable to find a constructor to use for type "myclass". A class should either have a default constructor

I know this question has been asked before, but I can't find an answer to solve this problem.
I'm making a request to a web service which returns a json, and then I save that json as an object in a list using json.net.
List<myclass> result;
var request = new RestRequest(url, Method.POST);
//Set the parameters of the request
//[...]
IRestResponse response = client.Execute(request)
Console.WriteLine(response.Content);
//response.Content = [{"nomPrecio":"string","nomPrecioEN":"string","IDrangoPrecio":0,"IDPoblacionMv":0,"NumOfertas":0,"NumOVotaciones":0,"Imagen":"anUrl"}]
//Everything works fine until here, and I can see the json is being received OK, but then...
result = JsonConvert.DeserializeObject<List<myclass>>(response.Content);
Then the console shows this message:
Rest Exception: Unable to find a constructor to use for type mynamespace.myclass. A class should either have a default constructor, one constructor with arguments or a constructor marked with the JsonConstructor attribute. Path '[0].nomPrecio', line 1, position 14.
namespace mynamespace
{
public class myclass
{
public myclass()
{
}
public myclass(string nomPrecio, string nomPrecioEN, int IDrangoPrecio, int IDPoblacionMv, int NumOfertas, int NumOVotaciones, string Imagen)
{
this.nomPrecio = nomPrecio;
this.nomPrecioEN = nomPrecioEN;
this.IDrangoPrecio = IDrangoPrecio;
this.IDPoblacionMv = IDPoblacionMv;
this.NumOfertas = NumOfertas;
this.NumOVotaciones = NumOVotaciones;
this.Imagen = Imagen;
}
public string nomPrecio { get; set; }
public string nomPrecioEN { get; set; }
public int IDrangoPrecio { get; set; }
public int IDPoblacionMv { get; set; }
public int NumOfertas { get; set; }
public int NumOVotaciones { get; set; }
public string Imagen { get; set; }
}
}
What's more weird is that I make the same for other classes in the app and no one returns this error, all of them works.
I tried a lot of things like "json2csharp" but nothing works.
Any tip about what could I be doing wrong? Thanks
Some linker problem mb? Try to add for your class
[Preserve(AllMembers = true)]
That can happen when linker is set to "Sdk and user assemblies"

Restier getting stored procedure function to work HTTP request

I have a RESTier Website using the latest version. All my entities and views I created from the database with EF 6 work fine, but I cannot seem to get the stored procedures I brought in to work. As the documentation is a little sparse I'm not sure if I need to implement anything beyond to basic startup of the service.
When sending this URI via Postman I get a 404 error not found:
http://192.168.1.20:60666/api/MIC_REST/up_BomAssemParts_s_ByJobID_FmNumber_WorkArea_TEST(jobID=252, fmNumber= 98, workAreas='A13,D12,A3,A9,A7,A10')
I basically have stock setup of service below. Any help in whether it might be the URI or the setup would be greatly appreciated.
WebApiConfig:
public static class WebApiConfig
{
public async static void Register(HttpConfiguration config)
{
config.EnableSystemDiagnosticsTracing();
config.Filter().Expand().Select().OrderBy().MaxTop(1000).Count();
await config.MapRestierRoute<EntityFrameworkApi<MICdB>>(
"MIC_REST", "api/MIC_REST", new Microsoft.Restier.Publishers.OData.Batch.RestierBatchHandler(GlobalConfiguration.DefaultServer));
}
}
public virtual ObjectResult<up_BomAssemParts_s_ByJobID_FmNumber_WorkArea_Result_TEST> up_BomAssemParts_s_ByJobID_FmNumber_WorkArea_TEST( Nullable<int> jobID, Nullable<int> fmNumber, string workAreas)
{
var jobIDParameter = jobID.HasValue ?
new ObjectParameter("JobID", jobID) :
new ObjectParameter("JobID", typeof(int));
var fmNumberParameter = fmNumber.HasValue ?
new ObjectParameter("FmNumber", fmNumber) :
new ObjectParameter("FmNumber", typeof(int));
var workAreasParameter = workAreas != null ?
new ObjectParameter("WorkAreas", workAreas) :
new ObjectParameter("WorkAreas", typeof(string));
return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction<up_BomAssemParts_s_ByJobID_FmNumber_WorkArea_Result_TEST>("up_BomAssemParts_s_ByJobID_FmNumber_WorkArea_TEST", jobIDParameter, fmNumberParameter, workAreasParameter);
}
public partial class up_BomAssemParts_s_ByJobID_FmNumber_WorkArea_Result_TEST
{
public string BomAssemShipMark { get; set; }
public string CurrentLocation { get; set; }
public int Quantity { get; set; }
public string PlPiecemark { get; set; }
public string MatSizeText { get; set; }
public string LengthText { get; set; }
public string GradeDescription { get; set; }
public string PlPiecemarkPrefix { get; set; }
public int PlPiecemarkSuffix { get; set; }
public string PlCodes { get; set; }
public string PlPremark { get; set; }
public Nullable<int> FmNumber { get; set; }
}
After banging my head on trying to get an ODataController to work, I have giving up and resorted to using an Apicontroller, which ended up being very simple to implement. With an ODataController, I could never get a URL to work or if I tried to add an oDataRoute, an error always resulted. It seems absurd that with all the fairly useless examples posted using ResTier the one real world example that one would expect (a stored procedure that returns a list of non-entity data for UI view purposes) seems non-existent. ResTier seems to work great for EntitySets but this mess I found myself in makes me question it (or Odata not sure where the fault is). Oh well, below gets the data...now to find a compress to fix the welt on my forehead....
[System.Web.Http.RoutePrefix("spapi/MIC_REST")]
public class SPController :ApiController
{
private MICdB db = new MICdB();
[System.Web.Http.Route("part/{jobID:int}/{fmNumber:int}/{workAreas}")]
// [EnableQuery]
public List<up_BomAssemParts_s_ByJobID_FmNumber_WorkArea_Result> GetPartsLists([FromODataUri]int jobID, [FromODataUri]int fmNumber, [FromODataUri]string workAreas)
{
return db.up_BomAssemParts_s_ByJobID_FmNumber_WorkArea_TEST(jobID, fmNumber, workAreas).ToList();
}
}

Removing properties of an object in List<>

I'm listening to "push" notifications coming into my server. I've set up SubscriptionModel with all possible properties, and I can correctly iterate through the JSON body coming through, parse each Subscription, and modify the output before returning the list I created. However, I'd like to know how I might go about removing properties of SubscriptionModel when I don't need to return them at all; or removing them if they're null before responding back with List<SubscriptionModel> subscriptions.
namespace TextMessagingListener.Controllers
{
public class SubscriptionModel
{
public long push_id { get; set; }
public string request_id { get; set; }
public string subscription_id { get; set; }
public string message { get; set; }
public string status_code { get; set; }
public string error_message { get; set; }
}
[Route("api/[controller]")]
public class SubscriptionController : Controller
{
// PUT api/subscription
[HttpPut]
public List<SubscriptionModel> Put([FromBody] List<SubscriptionModel> model)
{
// Receive a report of whether your subscription(s) was successfully added or not.
List<SubscriptionModel> subscriptions = new List<SubscriptionModel>();
foreach (SubscriptionModel m in model)
{
m.message = "Push notification successfully received.";
subscriptions.Add(m);
}
return subscriptions;
}
}
}
The only solution I can think of is to create another object which will just be for returning information; and applying each subscriptions item I want to send on to that.
You can't. You'd need another class. A "light" version that contains just the properties. Or you could do an anonymous type, but that is difficult to work with. I agree with the other guy on your naming conventions though :).

Categories