How to access REST API endpoints in a C# code - c#

I have set up a backend server with multiple endpoints using NodeJS with the ExpressJS framework. These REST Api Endpoints are connected to a Mongodb Database.
Due to project requirements, I had to write some code on C# that will also be calling and posting data into the database. However, I am now having trouble accessing the collections created by the ExpressJS Api Endpoint on my C# code.
May I know how is it normally done? Eg. how do I create a GET request from C# to access a collection created by ExpressJS Any help is greatly appreciated! Thank you!

restful request is just a format of HTTP request. so you should send the request first.
then when you get restful response, you should deserialize it in JSON format.
show the example code
using System;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
namespace HttpClientSample
{
public class Product
{
public string Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
public string Category { get; set; }
}
class Program
{
static HttpClient client = new HttpClient();
static void ShowProduct(Product product)
{
Console.WriteLine($"Name: {product.Name}\tPrice: " +
$"{product.Price}\tCategory: {product.Category}");
}
static async Task<Uri> CreateProductAsync(Product product)
{
HttpResponseMessage response = await client.PostAsJsonAsync(
"api/products", product);
response.EnsureSuccessStatusCode();
// return URI of the created resource.
return response.Headers.Location;
}
static async Task<Product> GetProductAsync(string path)
{
Product product = null;
HttpResponseMessage response = await client.GetAsync(path);
if (response.IsSuccessStatusCode)
{
product = await response.Content.ReadAsAsync<Product>();
}
return product;
}
static async Task<Product> UpdateProductAsync(Product product)
{
HttpResponseMessage response = await client.PutAsJsonAsync(
$"api/products/{product.Id}", product);
response.EnsureSuccessStatusCode();
// Deserialize the updated product from the response body.
product = await response.Content.ReadAsAsync<Product>();
return product;
}
static async Task<HttpStatusCode> DeleteProductAsync(string id)
{
HttpResponseMessage response = await client.DeleteAsync(
$"api/products/{id}");
return response.StatusCode;
}
static void Main()
{
RunAsync().GetAwaiter().GetResult();
}
static async Task RunAsync()
{
// Update port # in the following line.
client.BaseAddress = new Uri("http://localhost:64195/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
try
{
// Create a new product
Product product = new Product
{
Name = "Gizmo",
Price = 100,
Category = "Widgets"
};
var url = await CreateProductAsync(product);
Console.WriteLine($"Created at {url}");
// Get the product
product = await GetProductAsync(url.PathAndQuery);
ShowProduct(product);
// Update the product
Console.WriteLine("Updating price...");
product.Price = 80;
await UpdateProductAsync(product);
// Get the updated product
product = await GetProductAsync(url.PathAndQuery);
ShowProduct(product);
// Delete the product
var statusCode = await DeleteProductAsync(product.Id);
Console.WriteLine($"Deleted (HTTP Status = {(int)statusCode})");
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
Console.ReadLine();
}
}
}
reference call web api

Related

C#- http client response help request

I have the following code:
static async Task checkIMEI( double IMEI)
{
var client = new HttpClient();
var request = new HttpRequestMessage
{
Method = HttpMethod.Get,
RequestUri = new Uri("https://kelpom-imei-checker1.p.rapidapi.com/api?service=model&imei=" + IMEI.ToString() ),
Headers =
{
{ "X-RapidAPI-Host", "kelpom-imei-checker1.p.rapidapi.com" },
{ "X-RapidAPI-Key", "key" },
}
};
using (var response = await client.SendAsync(request))
{
response.EnsureSuccessStatusCode();
object result = await response.Content.ReadAsStringAsync();
MessageBox.Show("\n" + result);
}
}
Running this code I get the following
response
I would like to further break up this response and the individual data and assign it to a variable such as
string ModelNum= model_nb >> should show "SM-G891A"
String Brand = brand >> should show "Samsung Korea"
Your help would be appriciated.
first your Client is bad practice use this link HttpClientFactory Microsoft docs to refactor your client.
Then Create Class for your needed model for ex:
public class Mobile
{
public string ModelNum { get; set; }
public string Brand { get; set; }
}
then you should deserialize your result to your model:
var result = await response.Content.ReadAsStringAsync();
var model = JsonSerializer.Deserialize<Mobile>(result);

404 error on using graph API from c# console app

I am currently trying to authenticate Graph API using my C#. I am able to query this API and receive the token successfully from Postman.But when I call same API, I get 404 error.
My code is as below:
using System;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using Newtonsoft.Json;
namespace GraphTest
{
public class AuthenticationModel
{
public string grantType { get; set; } = "client_credentials";
public string clientId { get; set; } = "my_ad_app_id";
public string clientSecret { get; set; } = "client_secret";
public string scope { get; set; } = "https://graph.microsoft.com/.default";
}
public class Authentication
{
private static string tenantId = "tenant_id";
private static readonly HttpClient Client = new HttpClient();
public Authentication()
{
var authenticationModel = new AuthenticationModel();
RunAsync().GetAwaiter().GetResult();
}
private static async Task RunAsync()
{
Client.BaseAddress = new Uri("https://login.microsoftonline.com/");
Client.DefaultRequestHeaders.Accept.Clear();
Client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("*/*"));
Client.DefaultRequestHeaders.Add("Host", "login.microsoftonline.com");
Client.DefaultRequestHeaders.Add("Cache-Control", "no-cache");
try
{
var authenticationModel = new AuthenticationModel();
var url = await GetTokenAsync(authenticationModel);
Console.WriteLine($"Created at {url}");
}
catch (Exception exception)
{
Console.WriteLine(exception.Message);
}
}
private static async Task<Uri> GetTokenAsync(AuthenticationModel authenticationModel)
{
var keyValues = authenticationModel.GetType().GetProperties()
.ToList()
.Select(p => $"{p.Name} = {p.GetValue(authenticationModel)}")
.ToArray();
var xUrlEncodedBody = string.Join('&', keyValues);
var response = await Client.PostAsJsonAsync(
$"{tenantId}/oauth2/v2.0/token", xUrlEncodedBody);
response.EnsureSuccessStatusCode();
return response;
}
}
}
So, I recieve this in response: StatusCode:404, ReasonPhrase:Not Found
Please help me in knowing that where I am doing it wrong.
Note: API with same data works fine with Postman. Though, I have replaced some values here for security reasons.
You should not post form URL encoded content as JSON (PostAsJsonAsync). The body needs to have a content type of application/x-www-form-urlencoded.
But backing up a second, you don't need to implement the protocol yourself when there are libraries out there that do it for you :). We provide and support the Microsoft Authentication Library (MSAL) which makes this easy.
var app = ConfidentialClientApplicationBuilder.Create(config.ClientId)
.WithTenantId("{tenantID}")
.WithClientSecret(config.ClientSecret)
.Build();
string[] scopes = new string[] { "https://graph.microsoft.com/.default" };
AuthenticationResult result = null;
try
{
result = await app.AcquireTokenForClient(scopes).ExecuteAsync();
}
catch (MsalServiceException ex)
{
Console.WriteLine($"Error getting token: {ex.Message}");
}
Console.WriteLine($"Token: {result.AccessToken}");
I ran your code and it is wrongly generating query string as below with spaces.
xUrlEncodedBody => grantType = client_credentials&clientId = my_ad_app_id&clientSecret = client_secret&scope = https://graph.microsoft.com/.default
There is space between query parameter name and value, see below line.
.Select(p => $"{p.Name} = {p.GetValue(authenticationModel)}")
Remove the space and try again
.Select(p => $"{p.Name}={p.GetValue(authenticationModel)}")

Call REST API from C#

I have a REST based API developed in JAVA. Now I am trying to call that API from a console based C# application i.e. from it's main function. I want to know is it possible to do that.
I have tried something but its not working
//I have written the below code in my class file. But the I can't find the RestClient class. What do I need to include this
static void Main(string[] args)
{
{
string endPoint = #"http:\\myRestService.com\api\";
var client = new RestClient(endPoint);
var json = client.MakeRequest();
}
}
From the documentation on asp.net site. this shows how it is done in C# , RestClient you tried to use is a lib, that encapsulate something like this sample. RestClient can be added as a nugget package.
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
namespace ProductStoreClient
{
class Product
{
public string Name { get; set; }
public double Price { get; set; }
public string Category { get; set; }
}
class Program
{
static void Main()
{
RunAsync().Wait();
}
static async Task RunAsync()
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://localhost:9000/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
// HTTP GET
HttpResponseMessage response = await client.GetAsync("api/products/1");
if (response.IsSuccessStatusCode)
{
Product product = await response.Content.ReadAsAsync<Product>();
Console.WriteLine("{0}\t${1}\t{2}", product.Name, product.Price, product.Category);
}
// HTTP POST
var gizmo = new Product() { Name = "Gizmo", Price = 100, Category = "Widget" };
response = await client.PostAsJsonAsync("api/products", gizmo);
if (response.IsSuccessStatusCode)
{
Uri gizmoUrl = response.Headers.Location;
// HTTP PUT
gizmo.Price = 80; // Update price
response = await client.PutAsJsonAsync(gizmoUrl, gizmo);
// HTTP DELETE
response = await client.DeleteAsync(gizmoUrl);
}
}
}
}
}

ASP.Net Web API Returning Array Values

Pretty new with ASP.Net WEB API. Having some issues with the proper API configuration (and return type) for my API call which calls another ASHX service.
I have the following codes (tested in HomeController just to verify that the service call would work):
public async Task<ActionResult> Index()
{
WebRequest request = WebRequest.CreateHttp("http://callme/address.ashx");
var response = await request.GetResponseAsync();
string content;
using (var stream = response.GetResponseStream())
using(var reader = new StreamReader(stream))
{
content = await reader.ReadToEndAsync();
}
var result = JsonConvert.DeserializeObject<MyResult[]>(content);
return this.View();
}
public class MyResult
{
public string ClientAddress { get; set; }
}
Now, trying to port it over to an ASP.Net WEB API call:
ClientAddressController.cs
public class ClientAddressController: ApiController
{
public async IQueryable<MyResult> GetClientAddress()
{
WebRequest request = WebRequest.CreateHttp("http://callme/address.ashx");
var response = await request.GetResponseAsync();
string content;
using (var stream = response.GetResponseStream())
using(var reader = new StreamReader(stream))
{
content = await reader.ReadToEndAsync();
}
var result = JsonConvert.DeserializeObject<MyResult[]>(content);
// How to return the result object??
}
}
public class MyResult
{
public string ClientAddress { get; set; }
}
I need some help to properly define the correct parameters for the WEB Api call so that I could return the result object.
The result object would just be an array of strings:
[{"Address": "Address 100"}, {"Address": "Address 200"}, {"Address": "300"}]
Hoping to get some insights on resolving this. I have some idea with regards to returning database queries in Web API, but the service calls (and the async method) kind of threw me off the groove.
Thanks.
**UPDATE*****
Was able to find some resolution on this and I am posting the solution I have.
public class ClientAddressController: ApiController
{
public async Task<IHttpActionResult> GetClientAddress()
{
WebRequest request = WebRequest.CreateHttp("http://callme/address.ashx");
var response = await request.GetResponseAsync();
string content;
using (var stream = response.GetResponseStream())
using(var reader = new StreamReader(stream))
{
content = await reader.ReadToEndAsync();
}
var result = JsonConvert.DeserializeObject<MyResult[]>(content);
return Ok(result);
// How to return the result object??
}
}
public class MyResult
{
public string ClientAddress { get; set; }
}
P.S.: I am going to accept #Stripling's answer as his provided me some direction.
You'll need to create a class with an Address property, and map the results to objects of that class:
public async IQueryable<ClientAddressResult> GetClientAddress()
{
WebRequest request = WebRequest.CreateHttp("http://callme/address.ashx");
var response = await request.GetResponseAsync();
string content;
using (var stream = response.GetResponseStream())
using(var reader = new StreamReader(stream))
{
content = await reader.ReadToEndAsync();
}
IEnumerable<MyResult> result = JsonConvert.DeserializeObject<MyResult[]>(content);
return result.Select(r => new ClientAddressResult{Address = r.ClientAddress})
.AsQueryable();
}
DTO Classes:
public class MyResult
{
public string ClientAddress { get; set; }
}
public class ClientAddressResult
{
public string Address { get; set; }
}
You can return array values as dynamic List to be able to do that set method return with dynamic List.
var resultList = new List<dynamic>();
resultList.Add(new {Address="Address 100"});
resultList.Add(new {Address="Address 200"});
resultList.Add(new {Address="Address 300"});
return resultList;
Hope this is what you are loooking for.

Call web API from client app

I used to use ASMX web services, however have since read (and been told) that a better way to request data from a client etc is to use web API's with MVC.
I have created an MVC 4 web api application and getting to grips with how it works.
Currently I have a single public string in my valuesControllers -
public class ValuesController : ApiController
{
// GET api/values/5
public string Get(int id)
{
return "value";
}
}
And I am currently trying to call this in my client like this -
class Product
{
public string value { get; set; }
}
protected void Button2_Click(object sender, EventArgs e)
{
RunAsync().Wait();
}
static async Task RunAsync()
{
using (var client = new HttpClient())
{
try
{
client.BaseAddress = new Uri("http://localhost:12345/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
// HTTP GET
HttpResponseMessage response = await client.GetAsync("api/values/5");
if (response.IsSuccessStatusCode)
{
Product product = await response.Content.ReadAsAsync<Product>();
Console.WriteLine("{0}", product.value);
}
}
catch(Exception ex)
{
Console.WriteLine(ex.Message.ToString());
}
}
}
On debugging I can step through the request and enter the web API code successfully however on the line -
Product product = await response.Content.ReadAsAsync<Product>();
This fails and enters my catch with the exception -
Error converting value "value" to type 'myDemo.Home+Product'. Path '', line 1, position 7.
Why is this?
Why is this?
Because from your controller action you are returning a string, not a Product which are 2 quite different types:
public string Get(int id)
{
return "value";
}
so make sure that you are consistently reading the value on the client:
if (response.IsSuccessStatusCode)
{
string result = await response.Content.ReadAsAsync<string>();
Console.WriteLine("{0}", result);
}
Of course if you modified your API controller action to return a Product:
public Product Get(int id)
{
Product product = ... go fetch the product from the identifier
return product;
}
your client code would work as expected.

Categories

Resources