Example of Firebase REST API for C# - c#

I have been trying to find examples of CRUD Firebase database for C#. I have researched some websites and tried doing on my own, but not all are complete nor updated examples.
May I know if there is a complete example of such?
I have tried using HttpWebResponse to query from Firebase.
So this is my sample code
public void getUser()
{
var request = (HttpWebRequest)WebRequest.Create(apiUrl + "user.json?orderBy=\"email\"&equalTo=" + "\"" + userId + "\"");
request.Method = "GET";
request.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip;
using (var response = (HttpWebResponse)request.GetResponse())
{
using (var reader = new StreamReader(response.GetResponseStream()))
{
var js = new JavaScriptSerializer();
var objText = reader.ReadToEnd();
var result = JsonConvert.DeserializeObject<List<User>>(objText);
}
}
}
My User class
public string email { get; set; }
public string firstName { get; set; }
public string #group { get; set; }
public string lastName { get; set; }
However, when I call getUser, it returns me null. But inside the objText, there is text in it.
E.g.
{"12345678":{"email":"user#hotmail.com","firstName":"Alan","group":"N","lastName":"Paul"}}

You are trying to get the User data from the Firebase database and you are able to get the data successfully too.
The issue is with the JSON deserialization. The JSON you are getting from Firebase can not be deserialized to List<User>. Also it can not be deserialized to a single object of User.
The reason for this is the format of the JSON. As per the JSON the target class should have a property with name 12345678 and the type of the property should be User. And your User class not like that. I assume that the value "12345678" is the userId.
What you can do is to convert the JSON to a dictionary with string as Key and User as value holding type and then get the User object from the dictionary.
Consider following code. (I am writing only necessary code here)
var objText = reader.ReadToEnd();
var usersDictionary = JsonConvert.DeserializeObject<Dictionary<string, User>>(objText);
// I assume that the value `12345678` represents the UserId.
// If my assumption is right, following code gives you the user object from the dictionary.
var result = usersDictionary[userId];
//this line of code may throw an exception coz the dictionary does not have the userId in it
// this could be due to Firebase did not return any data in "objText".
This way you can get the user object out or the response text from the Firebase.

Related

How can I add json data to a label in C#? ( windows forms )

so i want to get bitcoin price from a URL and see it in a label in my form.
URL
i tried to make a class for it with the code
public string price { get; set; }
but i don't know what to do after that, i searched a lot in google but they all show the result in list and etc
To deserialize, first you need to make a class with the attributes the JSON has. This page will help you a lot in that.
Once you have a class, you need to deserialize your JSON into that class. In C# I like to use JsonConvert from the library Newtonsoft.Json, you need to import it.
The method that deserializes it is JsonConvert.DeserializeObject.
One little example, let's say your class is called Bitcoin, then you would have to do it that way :
var myBitcoin = JsonConvert.DeserializeObject<Bitcoin>(yourJson);
EDIT: To pull your json from an URL you can use Webclient DownloadString method.
var myjson = new WebClient().DownloadString("url");
This post may also help you.
This should be your class.
public class APIResponse
{
public string symbol { get; set; }
public string price { get; set; }
}
Then in your function add these lines.
APIResponse response = new APIResponse();
response = JsonConvert.DeserializeObject<APIResponse>();
myPriceLabel.Text = response.price;
What did we do? We created a C# model same as the Json Data model and we took JSON data and converted it to APIResponse type so we can access it and use it as we like.
It can be achieved simply by converting the Json with generic object
var myBitcoin = JsonConvert.DeserializeObject<object>(yourJson);
thank you all for answering but i found the solution!
the code should be like this
string url = "https://api.binance.com/api/v3/ticker/price?symbol=BTCUSDT";
using (WebClient wc = new WebClient())
{
var json = wc.DownloadString(url);
JavaScriptSerializer oJS = new JavaScriptSerializer();
PriceClass obj = new PriceClass();
obj = oJS.Deserialize<PriceClass>(json);
BTCPrice_Label.Text = obj.price;
}
and the class should be like this
using System;
public class PriceClass
{
public string symbol { get; set; }
public string price { get; set; }
}

The best way to insert odata type to json payload when use rest api insert data to azure table storage

When I use azure table storage Insert Entity api to insert data.
There are some types like dateTime,int in my entity class. And as per this doc: By default a property is created as type String, unless you specify a different type.
So I wonder which is the best way to add the odata type to the json payload? The generated json payload with odata type added should like below:
And my current solution is that after the json string is generated, I treat it as string, and add the odata type directly into the json. But I think there should be more better way for this.
My code like below:
Entity class:
public class MyClass
{
public string PartitionKey { get; set; }
public string RowKey { get; set; }
public string Name { get; set; }
public Guid TestId { get; set; }
}
The main method:
static void Main(string[] args)
{
string url_with_sasToken = "https://xxx.table.core.windows.net/ttt?sasToken";
MyClass entity = new MyClass
{
PartitionKey = "ivan2",
RowKey = "y1",
Name = "jack60",
TestId = Guid.NewGuid()
};
//here, I add the odata type for Guid type
string s = JsonConvert.SerializeObject(entity).Replace("}","");
s += ",\"TestId#odata.type\"" + ":" + "\"Edm.Guid\"}";
Console.WriteLine(s);
var content = new StringContent(s, Encoding.UTF8, "application/json");
using (HttpClient client = new HttpClient())
{
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new
MediaTypeWithQualityHeaderValue("application/json"));
var t2 = client.PostAsync(url_with_sasToken , content).GetAwaiter().GetResult();
Console.WriteLine(t2.StatusCode);
}
}
IMHO, a better way to do this is to make use of Reflection and dynamically create JSON by iterating over public properties of a class. You can pick only those properties types of which are supported by Table service (e.g. Guid, DateTime etc.)
That way you're not constantly changing the serialization code to reflect changes in your class definition. In any case using + sign for string concatenation is a bad idea :).
For reference, you can take a look at the code for TableEntity class in Storage SDK. I downloaded the code for release 9.3.2 from Github (https://github.com/Azure/azure-storage-net/releases/tag/v9.3.2) as this was the last version that supported Table in the SDK.

c# POST api fuss

I'm building a web Api to catalog my firms bug report onto a server, and I'm having trouble with the post request that I'm doing.
As I've coded the clients they should be either sending bug reports that are formatted like this
public partial class JitCollect {
public DateTime? Timestamp { get; set; }
public string Jit { get; set; }
public int? ProjectId{ get; set; }
}
or they could be sending strings with status reports like "OK" or whatever. My main problem is that if I send the bug reports as "application/x-www-form-urlencoded" and prepending a '=' to my body like I saw online, I lose the DateTime format that NewtonSoft is expecting on the other side:
before "2018-08-14T08:50:17.5608444+02:00"
after "2018-08-14T08:50:17.5608444 02:00"
I could hardcode something to put the '+' back but that's beside the point, I'm interested in how to properly accomplish what I'm trying to do.
if I instead try to send the data as "application/json", I always get empty data on the other side even specifying the from body attribute and the object type (which is not ideal for me because I want to be able to send plain strings as well)
[HttpPost]
public string Post([FromBody] List < JitCollect > jsonPost)
any idea what is the best way to do this? here's one of the many post functions I tried to use
public static void postRequest(string data, string address) {
using (var client = new HttpClient()) {
client.BaseAddress = new Uri(address);
data = $"={data}";
//client.DefaultRequestHeaders.Add("token", token);
var buffer = System.Text.Encoding.UTF8.GetBytes(data);
var byteContent = new ByteArrayContent(buffer);
byteContent.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");
//byteContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
var result = client.PostAsync("", byteContent).Result;
string resultContent = result.Content.ReadAsStringAsync().Result;
}
}
I made a test with asp.net core web api, it passes the datetime correctly.
Controller
[HttpPost]
public object Post([FromBody]List<JitCollect> jsonPost)
{
var resul = jsonPost.FirstOrDefault().Timestamp.Value.ToString("yyyy’-‘MM’-‘dd’T’HH’:’mm’:’ss.fffffffK");
return new List<JitCollect>() {
new JitCollect{ ProjectId = 1, Jit = "J1", Timestamp = DateTime.Now }
};
}
Request from postman
Result From Controller

WebService JSON query exception

async private void webServiceGetPoints()
{
var client = new HttpClient();
var response = await client.GetAsync(new Uri("//private//"));
var result = await response.Content.ReadAsStringAsync();
JArray jsonVal = JArray.Parse(result) as JArray;
dynamic taglist = jsonVal;
foreach (dynamic tag in taglist)
{
Collection.Add(new Tag(tag.name, tag.description, tag.longitude, tag.latitude));
}
}
I've got a problem with that code. When I set this GET query to serwer it returns me a json. I tried to parse it to class using JSON.NET but when I do that it thorws me an exception. I don't know with one becouse it's open App.h.cs file an highlight the line:
if (global::System.Diagnostics.Debugger.IsAttached) global::System.Diagnostics.Debugger.Break();
You are passing dynamic values into your Tag class constructor. Some values in there are probably not convertible into whatever your class expects (maybe they are null, or not even exist).
You can use a typed converter like Json.Net:
class TagData
{
public string name { get; set; }
public int longitude { get; set; }
//...
}
var item JsonConvert.DeserializeObject<List<TagData>>(result);
Especially with data from web services you should never rely on dynamic and always use something that checks correct conversion.

RestSharp Deserialize returns empty properties but xml.deserialize test works

EDIT : the moment I asked the question I thougt of trying something..
I've set XmlNamespace property on the request and that did the trick..
request.XmlNamespace = "http://musicbrainz.org/ns/mmd-2.0#";
But I don't really understand as to why...
Next problem is getting RestSharp to recognize xml atributes as object properties
I've been going over this for the most of the weekend and I just don't get it to work.
I'm trying to write a wrapper round a RestFul webservice (MusicBrainz). I'm testing with a simple example : get details of one artist and put it in a custom Artist object.
When I do a Execute on the RestClient it ends ok but my object properties are null..
But when I test the deserialization with the XmlDeserializer the objectproperties are filled (But not for properties that correspond to an attribute, but I'll tackle that later)
What happens between deserialization of the response and putting the object in response.data ?
Quite possible it is a "newbie" error I'm making as this are my first steps with RestSharp..
Help would be much appreciated..
Returnded xml :
<metadata>
<artist type="Group" id="f1548c5b-329e-4036-921c-02213a04b525">
<name>Uriah Heep</name>
<sort-name>Uriah Heep</sort-name>
<country>GB</country>
<life-span>
<begin>1970</begin>
</life-span>
</artist>
</metadata>
My class :
public class Artist
{
public int Id { get; set; }
public string Type { get; set; }
public string Name { get; set; }
public string SortName { get; set; }
public string Country { get; set; }
}
In the following code output properties are filled
var output = xml.Deserialize<Artist>(response);
But the same response does not fill properties when calling
var response = client.Execute<T>(request);
Complete code (I've put the test code in the generic method for sake of simplicity) :
public T Execute<T>(RestRequest request) where T : new()
{
var client = new RestClient();
client.BaseUrl = BaseUrl;
client.Authenticator = null;
//does not fill properties
var response = client.Execute<T>(request);
if (response.ErrorException != null)
{
throw response.ErrorException;
}
var xml = new XmlDeserializer();
//fills properties
var output = xml.Deserialize<Artist>(response);
return response.Data;
}
This happens because Execute method, after receiving response, tries to negotiate it based on the request's RootElement and XmlNamespace properties and copies them to the XmlDeserializer.
Here's a code from RestClient:
handler.RootElement = request.RootElement;
handler.DateFormat = request.DateFormat;
handler.Namespace = request.XmlNamespace;
response.Data = handler.Deserialize<T>(raw);
If you pass a RestRequest with a mismatching XmlNamespace, RestSharp's XmlDeserializer (that uses XDocument behind the scenes) won't be able to map response XML to an object properties and you will get default/null values instead.
Now for default implementation (when you create XmlDeserializer manually), if you don't set a XmlNamespace, deserializer will do an auto-detection that basically ignores all namespaces in the response and maps all properties only by their names.
See source code from XmlDeserializer:
// autodetect xml namespace
if (!Namespace.HasValue())
{
RemoveNamespace(doc);
}
Taking all above into account, it's clear why it started working after you explicitly set XmlNamespace property to a matching namespace in your request object with this line:
request.XmlNamespace = "http://musicbrainz.org/ns/mmd-2.0#";
Execute method copied namespace into deserializer and it mapped XML to object appropriately.

Categories

Resources