Displaying result in console instead of web page - c#

The project I have created, is an ASP.NET Web API which communicates with a Java Web Service through HttpClient. When I run the Java Web Service, I get the result {"id":2,"content":"Hello, World!"}. When I run the ASP.NET Web API, The ASP.NET Web API gets result from the Java Web Service and displays result as "{\"id\":2,\"content\":\"Hello, World!\"}" in a web page.
How do I display the result in console, which means I create a console application and put in these codes and I want the result to come out in a console and not web page. How do I do that? What are the codes that has to be modified? Someone please kindly do help me thank you so much.
Here are my ASP.NET Codes that I have done so far:
ClientController.cs
public class ClientController : ApiController
{
private ServerClient serverClient = new ServerClient();
public async Task<IHttpActionResult> GET()
{
try
{
var result = await serverClient.content();
return Ok(result);
}
catch (Exception e)
{
var result = "Server is not running";
return Ok(new { ErrorMessage = result });
}
}
}
ServerClient.cs
public class ServerClient
{
private static HttpClient client;
private static string BASE_URL = "http://localhost:8080/";
static ServerClient()
{
client = new HttpClient();
client.BaseAddress = new Uri(BASE_URL);
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
}
public async Task<string> content()
{
var endpoint = string.Format("greeting");
var response = await client.GetAsync(endpoint);
return await response.Content.ReadAsStringAsync();
}
}
WebApiConfig.cs
config.Routes.MapHttpRoute(
name: "TestClient",
routeTemplate: "api/testclient",
defaults: new { actcion = "Get", controller = "Client" }
);

static void Main(string[] args)
{
var result = serverClient.content().Result;
Console.WriteLine(result);
}
Please note that using Result or Wait() in async programming might cause deadlock

Related

Azure DevOps API creating work item returns 404 error

I am attempting to add a work task using Azure Apis but I keep getting a 404 error. I attempted to do a get all projects and this works (so my authentication token is working fine). I even granted all Azure Permissions to the token and it still returns a 404 error.
public class Main
{
public static void Main(string[] args)
{
AzureClient ac = new AzureClient();
var task = ac.AddTask();
}
}
public class AzureClient
{
private readonly HttpClient _client;
public AzureClient()
{
_client = new HttpClient()
{
Timeout = TimeSpan.FromSeconds(30)
};
_client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
// ADDED PAT HERE TO CLIENT
}
public async Task AddTask()
{
List<object> task = new List<object>
{
new { op = "add", path = "/fields/System.Title", value = "Test"}
};
string jsonTask = JsonConvert.SerializeObject(task);
string baseUri = "some base uri";
string uri = $"{baseUri}/_apis/wit/workitems/$Task?api-version=5.0";
// RESPONSE HERE RETURNS 404
var response = _client.PostAsync(uri, new StringContent(jsonTask, Encoding.UTF8, "application/json-patch+json")).Result;
}
}
Please use the 'application/json-patch+json' instead of the 'application/json' in your code:
_client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
If you use the Postman to test the Api, you will find the error:
Valid content types for this method are: application/json-patch+json.
That's way we need to use the application/json-patch+json
Hope this will help.

Http Get Request not getting any data

I have my Web Api on a production server online and working well in postman and in Xamarin forms so far until I needed to do a Get Request and does not return any data. Infact it stops at the GetAsStringAsync line and does not continue. Instead, it jumps out of the method and then nothing more.
Does any one know what the problem could be? I have checked and made sure my Internet is working and the Uri too.
This is where I am doing my Get in Xamarin forms:
public async Task<List<OfferModel>> AllOffers()
{
var httpclient = new HttpClient();
httpclient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", Settings.AccessToken);
//it does not continue after this line, it jumps out of the method instead
var response = await httpclient.GetStringAsync(UrlConstants.offerurl);
var data =JsonConvert.DeserializeObject<List<OfferModel(response);
return data;
}
Solution 1
Can you try access task via awaiter it may be wait until result when responded
public class HttpHelperService
{
public async Task<List<OfferModel>> AllOffers()
{
List<OfferModel> result;
string responseBody;
using (HttpClient client = new HttpClient())
{
try
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", Settings.AccessToken);
HttpResponseMessage response = client.GetStringAsync(new Uri(UrlConstants.offerurl)).GetAwaiter().GetResult();
result = JsonConvert.DeserializeObject<List<OfferModel>>(response);
}
catch (Exception ex)
{
result = null;
}
return result;
}
}
}
Solution 2
public class MyPage : ContentPage
{
//Here is your page constructor
public MyPage()
{
GetServices(); //--> call here without awaiter
}
}
//Here is your awaiter method
private async void GetServices()
{
LoadingPopupService.Show();
var result = await HttpService.AllOffers();
LoadingPopupService.Hide();
}
//Here is your service.
public async Task<List<OfferModel>> AllOffers()
{
var httpclient = new HttpClient();
httpclient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", Settings.AccessToken);
var response = await httpclient.GetStringAsync(UrlConstants.offerurl);
var data =JsonConvert.DeserializeObject<List<OfferModel(response);
return data;
}

OWIN Self-Host + Web Api connection cant make requests through Postman

I am trying to self-host Web API. It works fine when I call requests through my program, where is API controller. But i can't make request through Postman Client. What could be the problem?
Api Controller
public class MyApiController : ApiController
{
public string Get()
{
return "Get";
}
}
Startup.cs
public class Startup
{
public void Configuration(IAppBuilder appBuilder)
{
var config = new HttpConfiguration();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
appBuilder.UseWebApi(config);
}
}
Program.cs
class Program
{
static void Main(string[] args)
{
string url = "http://localhost:44300/";
using (WebApp.Start<Startup>(url))
{
var client = new HttpClient();
var response = client.GetAsync(url + "api/myapi").Result;
Console.WriteLine(response.Content.ReadAsStringAsync().Result);
}
Console.ReadLine();
}
}
It looks like your issues are in your main method. In C#, the using statement (link) creates a resource, executes the code in the block, and then disposes of the resource.
In your posted example, your WebApp is disposed right after it prints the response to the console (and before you're able to make requests with your browser).
These edits should allow you to keep the WebApp in-scope in order to play around with the framework.
class Program
{
static void Main(string[] args)
{
string url = "http://localhost:44300/";
using (WebApp.Start<Startup>(url))
{
var client = new HttpClient();
var response = client.GetAsync(url + "api/myapi").Result;
Console.WriteLine(response.Content.ReadAsStringAsync().Result);
Console.WriteLine("WebApp Ready");
Console.ReadLine();
}
Console.WriteLine("WebApp disposed.");
Console.ReadLine();
}
}

Calling remote web api from mvc controller

What is the preferred way for handling web api endpoints for each controller?
For example, my MVC controller will be calling different endpoints.
These are the only ones for now, but it could change.
Also, I will be developing this locally and and deploying to development server.
http://localhost:42769/api/categories/1/products
http://localhost:42769/api/products/
public class ProductsController : Controller
{
HttpClient client;
string url = "http://localhost:42769/api/categories/1/products"; //api/categories/{categoryId}/products
public ProductsController()
{
client = new HttpClient();
client.BaseAddress = new Uri(url);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
}
// GET: Products
public async Task<ActionResult> ProductsByCategory()
{
HttpResponseMessage responseMessage = await client.GetAsync(url);
if (responseMessage.IsSuccessStatusCode)
{
var responseData = responseMessage.Content.ReadAsStringAsync().Result;
var products = JsonConvert.DeserializeObject<List<GetProductsByCategoryID>>(responseData);
return PartialView(products);
}
return View("Error");
}
}
Not sure I understand you question or problem, but I would create a wrapper class for the service and then have different methods for each resource that you need to call. Always think SOLID.
Example (written by hand)
public class Client
{
private Uri baseAddress;
public Client(Uri baseAddress)
{
this.baseAddress = baseAddress;
}
public IEnumerable<Products> GetProductsFromCategory(int categoryId)
{
return Get<IEnumerable<Product>>($"api/categories/{categoryId}/products");
}
public IEnumerable<Products> GetAllProducts()
{
return Get<IEnumerable<Product>>($"api/products");
}
private T Get<T>(string query)
{
using(var httpClient = new HttpClient())
{
httpClient.BaseAddress = baseAddress;
var response= httpClient.Get(query).Result;
return response.Content.ReadAsAsync<T>().Result;
}
}
}

Posting data to Web API using custom Authentication

This is a follow-up on an earlier question regarding using HttpClient with Web API performing authentication using a custom Message Handler.
I can request data from the server using the provided solution, but now I am having trouble posting JSON data to the server. Whenever I try posting data to the Web API I am returned an Internal Server Error response code.
Here is the code on the client side:
using (var httpClient = new HttpClient())
{
var request = new HttpRequestMessage();
request.Headers.Add("X-Token", UserSession.GlobalInstance.SecurityToken);
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
request.Method = HttpMethod.Post;
request.RequestUri = new Uri(_apiBaseAddress + "api/User");
request.Content = new ObjectContent<UserDTO>(userDTO, new JsonMediaTypeFormatter());
var response = httpClient.SendAsync(request).Result;
if (response.IsSuccessStatusCode)
{
// handle result code
}
throw new Exception(String.Format("Server generated error response: {0}", response.StatusCode));
}
The declaration for the controller method:
public class UserController : ApiController
{
public long Post(UserDTO userDTO)
{
// create user and return custom result
// code (e.g. success, duplicate email, etc...)
}
}
(I've also added [FromBody] to the method parameter, but end up with the same result).
A snapshot of the code for my message handler and routing configuration can be found here.
Your code works as expected...
The server side.
Create a console application and run NuGet
Install-Package Microsoft.AspNet.WebApi.OwinSelfHost
Program.cs
internal class Program
{
private static IDisposable _server;
private static void Main(string[] args)
{
_server = WebApp.Start<Startup>("http://localhost:12345");
Console.ReadLine();
_server.Dispose();
}
}
Startup.cs
public class Startup
{
public void Configuration(IAppBuilder app)
{
var config = new HttpConfiguration();
WebApiConfig.Register(config);
app.UseWebApi(config);
}
}
WebApiConfig.cs
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
var userTokenInspector = new UserTokenInspector {InnerHandler = new HttpControllerDispatcher(config)};
config.Routes.MapHttpRoute(
"UserAuthenticationApi",
"api/{controller}/Authenticate",
new {controller = "User", action = "Authenticate"},
null
);
config.Routes.MapHttpRoute(
"DefaultApi",
"api/{controller}/{id}",
new {id = RouteParameter.Optional},
null,
userTokenInspector
);
}
}
UserTokenInspector.cs
public class UserTokenInspector : DelegatingHandler {
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
CancellationToken cancellationToken) {
const string TOKEN_NAME = "X-Token";
if (!request.Headers.Contains(TOKEN_NAME)) {
return Task.FromResult(request.CreateErrorResponse(HttpStatusCode.Unauthorized,
"Request is missing authorization token."));
}
try {
//var token = UserToken.Decrypt(request.Headers.GetValues(TOKEN_NAME).First());
// validate token
// ...
// ...
Thread.CurrentPrincipal = new GenericPrincipal(new GenericIdentity("alex"), new string[] { });
}
catch {
return Task.FromResult(request.CreateErrorResponse(HttpStatusCode.Unauthorized, "Invalid token."));
}
return base.SendAsync(request, cancellationToken);
}
}
UserController.cs
public class UserController : ApiController
{
public long Post(UserDTO userDTO)
{
// create user and return custom result
// code (e.g. success, duplicate email, etc...)
return 1;
}
}
UserDto.cs
public class UserDTO
{
public string Username { get; set; }
}
ValuesController.cs
public class ValuesController : ApiController
{
public HttpResponseMessage Get()
{
return Request.CreateResponse(HttpStatusCode.OK, "yay");
}
}
The Client... create a Console application and run NuGet:
Install-Package Microsoft.AspNet.WebApi.Client
Program.cs
internal class Program
{
private static void Main(string[] args)
{
var request = new HttpRequestMessage();
request.Headers.Add("X-Token", "token");
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
request.Method = HttpMethod.Post;
var baseAddress = "http://localhost:12345/";
request.RequestUri = new Uri(baseAddress + "api/User");
var userDto = new UserDTO() {Username = "Alex"};
request.Content = new ObjectContent<UserDTO>(userDto, new JsonMediaTypeFormatter());
var httpClient = new HttpClient();
var response = httpClient.SendAsync(request).Result;
if (response.IsSuccessStatusCode)
{
// handle result code
Console.WriteLine(response.StatusCode);
Console.ReadLine();
}
}
}

Categories

Resources