I take from a website 24images URLs(8images and each image has 3 different sizes this is how the web API works and I cannot change it)
I get those as JSON and I parse them as shown here using newton soft JSON.
Each image URL is stored in property in the same class as its different size images
and different images are stored in other classes
so there are 8classes containing 3 properties which contains image url
I am trying to get 1image url from each class
I am trying to use reflection but since these classes has different names, it is hard to do it (for me at least)
I have came this far
PropertyInfo[] properties = typeof(Photos).GetProperties();
foreach (PropertyInfo property in properties)
{
object a = property.GetValue(mm);
//I cannot use a._1 or a._2 because it is not an instance of the class I want I also cannot convert it since the class names are not the same
}
If you are using Newtonsoft JSON library - then you can use the JObject class, it's an abstraction for any JSON object.
var uri = new Uri("Your API request URL");
using var client = new HttpClient();
var response = await client.GetAsync(uri);
var data = await response.Content.ReadAsStringAsync();
var jObject = JObject.Parse(data);
var img1 = jObject["_1"];
var img2 = jObject["_2"];
//And so on.
Please see the code below, this is how you can read properties.
Helper class to read properties
public static class Helper
{
public static void GetDataByProperty(Type photosType, object photoObject, string propertyNameToRead)
{
foreach (PropertyInfo photoProperty in photosType.GetProperties())
{
if (photoProperty.Name == propertyNameToRead)
{
foreach (var urlProperty in photoProperty.PropertyType.GetProperties())
{
Console.WriteLine(urlProperty.GetValue(photoObject));
}
}
}
}
}
Sample API data
var photos = new Photos
{
_1 = new __1() { _3 = "http://www.google3.com", _2 = "http://www.google2.com", _0 = "http://www.google0.com" },
};
Reading the data
Helper.GetDataByProperty(photos.GetType(), photos._1, "_1");
Related
In my REST Service I have the following:
AssetController:
// GET: <AssetController>
[HttpGet("{companyID}/{machineName}")]
public Asset Get(int companyID, string machineName)
{
Database db = new Database(configuration.ConnectionString);
//DataSet ds = db.executeFunctionSelect("fngetallassets2()");
DataSet ds = db.executeViewSelect("tblasset where LOWER(name) = '" + machineName.ToLower() + "'");
//DataSet ds = db.executeDataSetProc("getallassets", null);
DataTable table = ds.Tables[0];
DataRow row = table.Rows[0];
Asset asset = new Asset
{
ID = int.Parse(row["ID"].ToString()),
CompanyID = int.Parse(row["Company_ID"].ToString()),
Name = row["Name"].ToString(),
IPAddress = row["IP_Address"].ToString(),
CreateDate = DateTime.Parse(row["Create_Date"].ToString()),
IsActive = bool.Parse(row["Is_Active"].ToString())
};
return asset;
}
This works fine... Its the PUT that I need help with
// PUT /<AssetController>/5
// Insert record into the database
[HttpPut("{asset}")]
public void Put([FromBody] string asset)
{
Database db = new Database(configuration.ConnectionString);
db.executeNonQuery("sp_AssetInsert", null);
}
Here I am trying to pass (somehow) the same asset class
In the calling windows forms I use this way to call the PUT Method:
public void InsertAsset(Asset asset)
{
ArrayList parameters = new ArrayList
{
asset.Name,
asset.IPAddress
};
RestClient client = new RestClient("https://localhost:5001/Asset/");
RestRequest request = new RestRequest(Method.PUT);
request.AddJsonBody(asset);
IRestResponse<List<string>> response = client.Execute<List<string>>(request);
if (response.StatusCode == HttpStatusCode.OK)
{
}
I get an error on Response.StatusCode = unsupportedmedia or something like this.
I need to know how to serialize or somehow pass either the class or the JSON string of it or whatever...
Can someone please help me figure out how to call the PUT methods as I have dozens of these to do.
Here is the calling and receiving code used to make this work.
calling:
RestClient client = new RestClient("https://localhost:5001/Asset/");
RestRequest request = new RestRequest(Method.PUT);
request.AddJsonBody(asset); <-- Asset is a class object
RestResponse response = (RestResponse)client.Execute(request);
if (response.StatusCode == HttpStatusCode.OK)
{
}
Receiving Code:
// PUT /<AssetController>/5
// Insert record into the database
[HttpPut]
public void Put([FromBody] Asset asset)
{
Database db = new Database(configuration.ConnectionString);
db.executeNonQuery("sp_AssetInsert", null);
}
I needed to change the [FromBody] string asset to [FromBody] Asset asset
There are several ways to pass parameters:
as url route i.e. https://localhost:5001/Asset/42/MyCompanyName
as url parameter http:// localhost:5001/Asset?companyID=42&machineName=companyname
in body, typically as a json serialized object
when you specify the route in [HttpPut("{paramaters}")] you are specifying option 1. You can use FromBody and FromUrl attributes on the parameter to control this. Simple parameters like numbers and string would typically be part of the URL, while complex objects like Asset will probably be easier to pass in the body.
See also
restsharp parameter posting
asp.net parameter binding
I'm new to the REST API world. I explain my need: at a specific URL I have a raw JSON text, I would like this text to be acquired by my application and inserted later in the DB as a model I created previously through EF. C# NET-CORE 2.2.
if I wasn't clear enough, don't hesitate to ask me for more details.
Thanks in advance!
Edit:
I'm sorry if it' was unclear, I will provide more detail:
Actually, i have a JSON string downloaded from an url. I did it with the following code:
var client = new WebClient();
var jsonFull = client.DownloadString(string.Format("https://url"));
It's working fine. Now, I need to take from this string only a little part of the JSON, so i did:
using var jsonDoc = JsonDocument.Parse(jsonFull);
var jsonParsed = jsonDoc.RootElement;
var myCV = jsonParsed.GetProperty("cv");
CVE is an object of this JSON, and I succesfully take it.
Inside this object, there is another one called CV_data, so I extract this:
var myCVLE = myCV.GetProperty("CV_data_meta");
The result is a var with inside
ValueKind = Object : "{
"ID": "CV-2019",
"ASS": "cv#ms.org"
}"
Now, I have a class like that
public class CV_data_meta
{
[JsonPropertyName ("ID")]
public string ID { get; set; }
[JsonPropertyName("ASS")]
public string ASS { get; set; }
}
The question is: how i can put the value in the var myCVLE in the class CV_data_meta?
I tried with
var myCVClass = JsonSerializer.Deserialize<CV_data_meta>(myCVLE);
But I get an error.
Note: I can't deserialize all the string JSON into an object, because there are a lot of information that I don't need.
Thanks in advance all!
As I understand from your question, it follows:
You first need to create the JSON object mapping (class) that the API URL will return.
Then consume the API url like this:
var client = new WebClient();
var reply =
client.DownloadString(
string.Format("https://www.yourapi.com/yourpath?yourkey={0}", yourkey));
receive and map object with mapped class
var yourvar = JsonConvert.DeserializeObject<yourclass>(reply);
Now you have the API return mapped to a class in your application, you can do whatever you want with it, including saving to a database.
I am using Sql Database rest api via c# code.
I am looking for a way to added the json to the body.
This is the format required.
{
"properties":
{
"startIpAddress": "0.0.0.3",
"endIpAddress": "0.0.0.3"
}
}
link. https://learn.microsoft.com/en-us/rest/api/sql/firewallrules/createorupdate
I'n not so used to doing this type procedure.
So, do I need to add the root 'properties' in the call? If so, how do I nest the json into the code?
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
string json = new JavaScriptSerializer().Serialize(new
{
startIpAddress = ip,
endIpAddress = ip
});
streamWriter.Write(json);
}
I tried this, but got bad format error back.
Many thanks in advance
Scott
For the required output json you should have something link this as your anonymous object:
new
{
properties = new {
startIpAddress = ip,
endIpAddress = ip
}
}
Now it would have the properties as main object and inside it two properties that you need.
The story is: I am building a Node application, but I need data from Google AdWords. Since there is no official Node library and I couldn't get the unofficial ones to work I wanted to create a REST API in ASP.NET. So far this is what I have:
[HttpGet]
public IEnumerable<string> Get()
{
TargetingIdeaSelector selector = new TargetingIdeaSelector
{
requestType = RequestType.IDEAS,
ideaType = IdeaType.KEYWORD,
requestedAttributeTypes = new AttributeType[] {
AttributeType.KEYWORD_TEXT,
AttributeType.SEARCH_VOLUME,
AttributeType.AVERAGE_CPC,
AttributeType.COMPETITION,
AttributeType.CATEGORY_PRODUCTS_AND_SERVICES
}
};
// Set selector paging (required for targeting idea service).
Paging paging = Paging.Default;
// Create related to query search parameter.
RelatedToQuerySearchParameter relatedToQuerySearchParameter =
new RelatedToQuerySearchParameter
{
queries = new String[] {
"bakery", "pastries", "birthday cake"
}
};
var searchParameters = new List<SearchParameter>
{
relatedToQuerySearchParameter
};
TargetingIdeaPage page = new TargetingIdeaPage();
page = targetingIdeaService.get(selector);
return new string[] { "value1", "value2" };
}
I basically grabbed the code from the docs. The problem is that the targetingIdeaService is not defined. If I try to take a look at a code sample it looks like this:
public void Run(AdWordsUser user, long? adGroupId) {
using (TargetingIdeaService targetingIdeaService =
(TargetingIdeaService) user.GetService(AdWordsService.v201802.TargetingIdeaService)) {
// Create selector.
TargetingIdeaSelector selector = new TargetingIdeaSelector();
selector.requestType = RequestType.IDEAS;
selector.ideaType = IdeaType.KEYWORD;
selector.requestedAttributeTypes = new AttributeType[] {
AttributeType.KEYWORD_TEXT,
AttributeType.SEARCH_VOLUME,
AttributeType.AVERAGE_CPC,
AttributeType.COMPETITION,
AttributeType.CATEGORY_PRODUCTS_AND_SERVICES
};
List<SearchParameter> searchParameters = new List<SearchParameter>();
// Create related to query search parameter.
RelatedToQuerySearchParameter relatedToQuerySearchParameter =
new RelatedToQuerySearchParameter();
relatedToQuerySearchParameter.queries = new String[] {
"bakery", "pastries", "birthday cake"
};
searchParameters.Add(relatedToQuerySearchParameter);
And a lot more code. The point is they made it in a function, and are passing a user object into it. Now I will not have said object. Unless it's needed. Then I'm screwed. But I need to get this service up and running. This is the only missing step, other than that it should work.
So my question is: Does anyone see a way around it?
The AdWordsUser object contains the authentication you need to connect to the API. Without it your app will have no idea of which AdWords account and OAuth refresh token to supply to the TargetingIdeaService.
I am currently trying to add pagination to my Instagram App and have managed to replace the List that provides the Data Source with the new data, but I want to add it to the existing List so that when I scroll back up it would show the most recent picture. Here is my approach right now:
var request = new RestRequest { RootElement = "data", Resource = "/users/self/feed" };
request.AddParameter ("access_token", instagramAccessToken);
var client = new RestClient ("https://api.instagram.com/v1");
client.ExecuteAsync (request, response => {
var rootObject = JsonConvert.DeserializeObject<RootObject> (response.Content);
string nextURL = rootObject.pagination.next_url;
//// Create Next Client
var requestBack = new RestRequest ();
var clientBack = new RestClient (nextURL);
// GET Next Response
clientBack.ExecuteAsync(requestBack, responseBack => {
var rootObjectBack = JsonConvert.DeserializeObject<RootObject> (responseBack.Content);
table.InvokeOnMainThread (() => {
// Create list that contains newly attained JSON
List<Datum> instagramData = rootObjectBack.data;
// Create dummy list for other values
List<Datum> sloppy = null;
// Send list that contains data, and the sloppy which doesnt contain anything to the Facebook and Twitter Values.
table.Source = new TableSource<Datum>(instagramData, sloppy, sloppy);
table.ReloadData ();
});
});
});
List<x> A = initial data
List<x> B = new data
A.AddRange(B);
A now has B appended to the end
to access the public List (assuming it's called "Data") inside of your existing source
((TableSource<Datum>)table.Source).Data