How do I grab specific strings from a source? - c#

I want to create an app that shows current information, i can get the information using a simple (at least, it looks pretty simple) API.
Now, you can use the API by going to the website, and enter the username. The URL will result in something like this site.web/api/public/user?name=Usename.
on that page is all the information I need, in form of one line of 'code'.
{"uniqueId":"hhus-7723dec98ecb9bc6643f10588e0bb3f4","name":"Username","figureString":"hr-125-40.hd-209-1369.ch-210-64.lg-270-1408.he-3329-1408-1408","selectedBadges":[],"motto":"sample txt","memberSince":"2012-08-25T14:01:04.000+0000","profileVisible":true,"lastWebAccess":null}
I want to extract this information and display it in my program, example:
{"uniqueId":"this is an ID"}
I only want the actual ID to be shown: this is an ID.
Thanks for helping!

The format you're receiving is called JSON. There are lots of libraries to read it easily, the most widely used in C# is JSON.NET.
If you only need to extract one property, you can do something like this:
string json = ...
var obj = JObject.Parse(json);
string uniqueId = obj["uniqueId"].Value<string>();
If you also need the other properties, it's probably easier to use deserialization: create a class with the same properties as the JSON object, and use JsonConvert.DeserializeObject to read the JSON into an instance of the class.

The one line of code you're referring to is JSON data. It's stored in the format "key":"value","key:value","key:value" and so on.
You should take a look at Newtonsoft.Json which helps you do exactly this: parse JSON data :)
https://www.nuget.org/packages/Newtonsoft.Json/

Tying it all together for you...
using System.IO;
using System.Net;
using Newtonsoft.Json.Linq;
...
WebClient client = new WebClient();
Stream stream = client.OpenRead("http://site.web/api/public/user?name=Usename");
StreamReader reader = new StreamReader(stream);
string userJson = reader.ReadLine();
reader.Close();
JObject jObject = JObject.Parse(userJson);
string uniqueId = (string)jObject["uniqueId"];

This is an example of Json. The most type safe way if to deserialize the data to a class you define.
Such a class could look like this:
public class MyClass
{
public string uniqueId { get; set; }
}
If you have the data in a string you can just deserialize it with the Newtonsoft.Json nuget package.
MyClass obj = JsonConvert.Deserialize<MyClass>(myJsonString);
If you get the data from http it is easier to use an client which can do the deserialization for you. Such a client is found in the nuget package Microsoft.AspNet.WebApi.Client
using(var client = new HttpClient())
{
var response = await client.GetAsync(myUrl);
response.EnsureSuccessStatusCode();
MyClass obj = await response.Content.ReadAsAsync<MyClass>();
}
Of course this assumes the server is standards compliant and specifies it's content-type as application/json
Bonus: The classes you deserialize to can be auto generated from example at the site: http://json2csharp.com/ .

Related

POST json to another url

I've a problem as I need to send some json to a url. When I send all my json and token to the page.
Then there will be no content JSON value into the system.
I have checked up on whether there is some content and it is there, but it sends just do not like json values.
string apiKeyToken = model.reepaytoken; // TOKEN HERE.
string URLLink = APIClassPay.HelperPay.CreateCustomerURL;//URL to send it json to.
WebClient client = new WebClient();
//JSON coming here!
var JSONCustomer = APIClassPay.HelperPay.CreateCustomer(model.Brugernavn, model.Adresse, model.Byen, model.Postnr.ToString(), model.Mobil.ToString(), model.Fornavn, model.Efternavn);
client.Headers.Add("text/json", JSONCustomer);
client.Headers.Set("X-Auth-Token", apiKeyToken);
string reply = client.DownloadString(URLLink);
When I blow my json looks like this.
[HttpPost]
public ActionResult information(BuyMedlemskabViewModel model)
{
DataLinqDB db = new DataLinqDB();
var Pric = db.PriceValues.FirstOrDefault(i => i.id == model.HiddenIdMedlemskab);
if (Pric != null)
{
string _OrderValue = DateTime.Now.Year + Helper.Settings.PlanValue();
Session[HelperTextClass.HelperText.SessionName.OrderId] = _OrderValue;
Session[HelperTextClass.HelperText.SessionName.FakturaId] = model.HiddenIdMedlemskab;
Session[HelperTextClass.HelperText.SessionName.fornavn] = model.Fornavn;
Session[HelperTextClass.HelperText.SessionName.efternavn] = model.Efternavn;
Session[HelperTextClass.HelperText.SessionName.Adresse] = model.Adresse;
Session[HelperTextClass.HelperText.SessionName.Post] = model.Postnr;
Session[HelperTextClass.HelperText.SessionName.Byen] = model.Byen;
Session[HelperTextClass.HelperText.SessionName.Mobil] = model.Mobil;
string apiKeyToken = model.reepaytoken;.
string URLLink = APIClassPay.HelperPay.CreateCustomerURL;//URL to send it json to.
WebClient client = new WebClient();
//JSON coming here!
var JSONCustomer = APIClassPay.HelperPay.CreateCustomer(model.Brugernavn, model.Adresse, model.Byen, model.Postnr.ToString(), model.Mobil.ToString(), model.Fornavn, model.Efternavn);
client.Headers.Add("text/json", JSONCustomer);
client.Headers.Set("X-Auth-Token", apiKeyToken);
string reply = client.DownloadString(URLLink);
}
return RedirectToAction("information");
}
EDIT - Update (ERROR HERE):
ReePay API reference: https://docs.reepay.com/api/
I think there are a few things, you'll have to fix:
First of all you're obviously trying to create a ressource (usually a POST or PUT, speaking in REST-words but you're using WebClient's DownloadString-method which performs a GET. So I think you should probably use a POST or PUT instead but which one to chose exactly depends on the web service you're contacting.
Then you seem to have mistaken the Content-Type-header and tried to pack the payload in there. The payload - your customer JSON - will have to be put into the request's body.
Based on your previous questions I assume the service you're trying to contact is either PayPal or QuickPay. To further help you with this question, it'd be helpful if you could specify which one you use.
If it's QuickPay, please notice that there's an official .NET client which you could use instead of using WebClient on you own.
But anyway for making HTTP requests I'd suggest you to use HttpClient in favor of WebClient. You'd generally do it in a way like this:
using (var httpClient = new HttpClient())
{
var request = new HttpRequestMessage(HttpMethod.Post,
APIClassPay.HelperPay.CreateCustomerURL);
request.Headers.Add("X-Auth-Token", apiKeyToken);
request.Headers.Add("Content-Type", "application/json");
request.Content = new StringContent(JSONCustomer);
var response = await httpClient.SendAsync(request);
}
EDIT:
As you clarified in a comment, the service you're using is Reepay. If you take a look at the documentation of the create customer method, you can see, that the necessary HTTP method is POST. So the code snippet above should generally fit.
Regarding the compilation error you faced, I updated the code-snipped above. There was a mistake in the variable names I chose. Please note, that you dropped the keyword await as I can see from your screenshot. Please re-enter it. If the compiler complains about it, it's very likely that the .NET framework version of your project is less than 4.5 which is necessary to use async/await.
So you should update your project's .NET framework version at best to version 4.6.1 as Microsoft recently announced that support for 4.5 and others is discontinued. Have a look here on how to do that.

Retrieve anonymous type from the web in C#

I'm trying to retrieve some data from the web. The data is served either as JSON object or XML: in both cases I'd like not to build a model based on the structure of this XML/JSON but to just retrieve the data I need.
HttpResponseMessage response = await client.PostAsync(
"http://www.someAPI.com/api.xml",
requestContent);
response.EnsureSuccessStatusCode();
HttpContent content = response.Content;
If I have to build a model based on the data structure I'll receive back I'll do it: I just want to know if there is any alternative. Can I parse content as an anonymous type and, say, retrieve the data as arbitrary fields or properties or array indexes?
Let's say: response.Countries[5].CountryId. Is it possible in any of these 2 types (JSON and XML)? How can I do it?
EDIT #2:
I've added a note below about using the excellent Json.NET library to deserialize to a dynamic object.
EDIT #1:
Thanks to Hoghweed's answer, my answer below is now more complete. Specifically, we need to cast the HttpContent we get from HttpResponseMessage.Content to ExpandoObject in order for the dynamic-ness to work as expected:
dynamic content = response.Content.ReadAsAsync<ExpandoObject>().Result;
var myPropertyValue = content.MyProperty;
To get the ReadAsync<T>() extension method though, you'd need to use NuGet to download and install System.Net.Http.Formatting.dll from the Microsoft.AspNet.WebApi.Client package (here's the "old" Nuget page, which mentions that it is now included in the above package).
Original Answer:
So, you don't want to have to create a POCO and have to manage its properties as the XML/JSON structure you get back changes. dynamic seems perfect for your use case:
HttpResponseMessage response = await client.PostAsync(
"http://www.someAPI.com/api.xml", requestContent);
response.EnsureSuccessStatusCode();
dynamic content = response.Content.ReadAsAsync<ExpandoObject>().Result; // Notice the use of the dynamic keyword
var myPropertyValue = content.MyProperty; // Compiles just fine, retrieves the value of this at runtime (as long as it exists, of course)
Specifically regarding XML: you could try Anoop Madhusudanan's ElasticObject which might be very helpful when converting between dynamic and XML, and back.
Specifically regarding JSON: you could use Json.NET do something like this:
dynamic content = JsonConvert.DeserializeObject(response.Content.ReadAsStringAsync().Result);
var myPropertyValue = content.MyProperty;
The up-side is that you won't take a dependency on the Microsoft.AspNet.WebApi.Client package (which, as of v4.0.30506.0, depends on Json.NET). The downside is that you won't be able to use this for XML.
Hope this helps.
Reading the HttpResponseMessage.Content as a dynamic it's possible but not accessing it directly as dynamic, but using the proper extension method to read it's content as ExpandoObject.
I wrote a behavior test for that, it's clear is a test, but the context is similar to what your question is:
a response object with a json content (I used json in my test)
a dynamic resolution without a model object
The test is structured as:
Given an anonymous object
When creating an HttpResponseMessage with a content of this object using a JsonMedia Formatter
Then it's possible to access it as dynamic using an ExpandoObject
The test prerequisite is to install the Microsoft.AspNet.WebApi.Client
So, this is the code of the test
public class RetrieveAnonymousTypeFromTheWebInCSharp
: BehaviorTest
{
private object _testModel;
private HttpResponseMessage _message;
protected override void Given()
{
_testModel = new
{
Id = 14,
MyProperty = "Test property value"
};
}
protected override void When()
{
_message = new HttpResponseMessage(HttpStatusCode.Accepted)
{
Content =
new ObjectContent(_testModel.GetType(),
_testModel,
new JsonMediaTypeFormatter
())
};
}
[Test]
public void Then()
{
//then properties could be retrieved back by dynamics
dynamic content = _message.Content.ReadAsAsync<ExpandoObject>().Result;
var propertyvalue = content.MyProperty;
Assert.That(propertyvalue, Is.Not.Null.And.EqualTo("Test property value"));
}
}
This could be done sure for xml too.

Consuming web services in C#

I just started playing around with some API's in C#. In my form I had added a service reference http://wsf.cdyne.com/WeatherWS/Weather.asmx. Everything works great and I am able to utilize its library. Now I am trying to use for example http://free.worldweatheronline.com/feed/apiusage.ashx?key=(key goes in here)&format=xml. [I have a key] Now when I try to use it as service reference I am not able to use.
Do I have to call it in my form instead of referencing it? or do some sort of conversion? Also does it matter if its xml or json type?
ASMX is old technology and uses SOAP under the hood. SOAP doesn't tend to work with query string parameters, it takes parameters as part of the message.
ASHX is something different (it could be anything, it's one way to write a raw HTML/XML page in .NET), so you can't transfer the method for calling one to the other. It also won't have a service reference, it's likely you request it via a raw HTTP request. You'll need to consuly the service documentation to discover how to use it.
worldweatheronline doesn't return a SOAP-XML that is consumable by a WebService client. Therefore you should download the response and parse it as done with many REST services.
string url = "http://free.worldweatheronline.com/feed/apiusage.ashx?key=" + apikey;
using (WebClient wc = new WebClient())
{
string xml = wc.DownloadString(url);
var xDoc = XDocument.Parse(xml);
var result = xDoc.Descendants("usage")
.Select(u => new
{
Date = u.Element("date").Value,
DailyRequest = u.Element("daily_request").Value,
RequestPerHour = u.Element("request_per_hour").Value,
})
.ToList();
}
Also does it matter if its xml or json type?
No, at the end you have to parse the response by yourself.
string url = "http://free.worldweatheronline.com/feed/apiusage.ashx?format=json&key=" + apikey;
using (WebClient wc = new WebClient())
{
string json = wc.DownloadString(url);
dynamic dynObj = JsonConvert.DeserializeObject(json);
var jArr = (JArray)dynObj.data.api_usage[0].usage;
var result = jArr.Select(u => new
{
Date = (string)u["date"],
DailyRequest = (string)u["daily_request"],
RequestPerHour = (string)u["request_per_hour"]
})
.ToList();
}
PS: I used Json.Net to parse the json string

Using A Web API for Business Logic?

My web application needs to be able to go and get all my projects from Paymo http://api.paymo.biz/
I am familiar with JSON and XML, but what I'm wondering is, how does one interact with the api (make calls to it).
I would ideally like to make a class in ASP .Net such as PaymoManager(int apikey....)
From there I can wrap the functionality I need. I just need to understand, how do I call functions of the API and how do I get the response. I am not familar with web apis.
Edit: Could you give me an example of this, even with some abstract url. I need this done server side in a CS file.
Basically a simple example that calls someurl.com/somerequest and then how do you receive the JSON or XML... how does this work in terms of a class. I want this in a class.
http://api.paymo.biz/docs/misc.overview.html
To perform an action using the Paymo API, you need to send a request
to the Paymo webservice specifying a method and some arguments, and
will receive a formatted response.
This means that you can use WebClient to download a string from a url:
WebClient client = new WebClient();
string reply = client.DownloadString (address);
Depending on the format you specify, you can parse the reply as XML or JSON.
XDocument xml = XDocument.Parse(reply);
// where ReplyType is a class that defines public
// properties matching the format of the json string
JavaScriptSerializer serializer = new JavaScriptSerializer();
ReplyType abc = serializer.Deserialize<ReplyType>(reply);
If you are using .NET 4.5, you might consider using HttpClient like so:
static async void Main()
{
try
{
// Create a New HttpClient object.
HttpClient client = new HttpClient();
// fill in the details in the following string with your own KEY & TOKEN:
string requestUrl = "https://api.paymo.biz/service/paymo.auth.logout?api_key=API_KEY&format=JSON&auth_token=AUTH_TOKEN"
HttpResponseMessage response = await client.GetAsync(requestUrl );
response.EnsureSuccessStatusCode();
string responseBodyJSON = await response.Content.ReadAsStringAsync();
// Above three lines can be replaced with new helper method in following line
// string body = await client.GetStringAsync(uri);
Console.WriteLine(responseBodyJSON );
// Now you can start parsing your JSON....
}
catch(HttpRequestException e)
{
Console.WriteLine("\nException Caught!");
Console.WriteLine("Message :{0} ",e.Message);
}
}

Json Hijacking Restsharp. modify response content before deserialization.

Ok. So I'm trying to use Restsharp as a Http Client.
Basicaly I need to modify a response content before deserialization.
Is there a point of extension where I could do this?
You know what I mean?
Form API I, get valid json answer but with ")]}',"( hijacking prevention) as a prefix.
Now I need to remove it.
Is there a way to do that?
Weel I think I figure it out.
I have to execute result first and then Deserializer class that i have derived from JsonDeserializer;
var reult = client.Execute(request);
var u = new MyDeserializer().Deserialize<UserGuamInformations>(reult);
and part of the class:
public new T Deserialize<T>(IRestResponse response){
string str = response.Content;
response.Content = str.Remove(0, 6);//remove )]}',\n
return base.Deserialize<T>(response);
}

Categories

Resources