How to consume restful services from another restful service in asp.net? - asp.net

I have an URL of one restful service, I want to consume this restful service from another restful service.
Suppose URL is first rest service is "http://testapi.com/services/rest/?method=getList&key=123”
Restful service 1 - > Restful service 2 -> asp.net client application
Could you provide any example with code and configuration settings.
Thanks

You can use the HttpClient. The example in the post is using a console application, but you can still use it from a Web Api project (which I have on some of my projects).
Example get async:
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("YOURURIHERE");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
// New code:
HttpResponseMessage response = await client.GetAsync("api/products/1");
if (response.IsSuccessStatusCode)
{
Product product = await response.Content.ReadAsAsync>Product>();
}
}

Related

Access to Sharepoint Online from Client App

Recently I came up with an issue that I have a .NET Web API which needs to connect to SharePoint Online. In the Azure AD, I have provided all permission to the AppId "AllSites.Manage.All", AllSites.Read.All etc. I used CSOM library to pass the token to the sharepoint. But once I am trying to execute query on the clientcontext received, It is throwing 401 UnAuthorized error
private async Task<ClientContext> GetClientContextWithAccessToken1(string targetUrl)
{
var accessToken = await _tokenAcquisition.GetAccessTokenForUserAsync(new string[] {"Files.ReadWrite.All", "Sites.Manage.All", "AllSites.Read"});
HttpClient httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
var response = await httpClient.GetAsync($"https://graph.microsoft.com/beta/me");
if(response.StatusCode == HttpStatusCode.OK)
{
var content = await response.Content.ReadAsStringAsync();
}
using(ClientContext clientContext = new ClientContext(targetUrl))
{
clientContext.ExecutingWebRequest +=
delegate (object oSender, WebRequestEventArgs webRequestEventArgs)
{
webRequestEventArgs.WebRequestExecutor.RequestHeaders["Authorization"] =
"Bearer " + accessToken;
};
return clientContext;
}
}
For the request to query https://graph.microsoft.com/beta/me , one of the below permissions is required to be granted consent from admin. like Directory.Read.All , User.Read.All ...
Also please make sure to add Sites.Read.All or Sites.ReadWrite.All Application permission in your registrated AAD Application and do admin consent for it before you getting token to access sharepoint sites.
If you're using v2 endpoint, please go to below URL in your internet browser to do admin grant:
https://login.microsoftonline.com/{yourtenant}/adminconsent?client_id={ applicationid /clientId }&state=123&redirect_uri={redirect uri of your app}
and sign in with Global administrator account and accept this permission.
Reference:
azure-app-cannot-access-sharepoint-online-sites
If you are calling Microsoft Graph API endpoints you should avoid using csom.
AllSites.Manage.All, AllSites.Read.All etc. permissions are related to SharePoint and CSOM and they will not work for Graph API endpoints.
For Graph API you need to acquire different token or better option is to use Microsoft Graph Client Library for .NET in your case.

Custom Headers with GRPC in .NET Core

I am working on building a service in GRPC using .NET core. The scenario is as follows - there are 2 services - A and B.
Service A exposes a REST API.
Service B exposes GRPC API.
User invokes Service A, and Service A invokes Service B. I need to pass the headers sent by the user to Service B.
How can I do this with GRPC? The Interceptor interface does not seem to expose the Metadata collection.
To forward the headers sent from client, on the rest api you can do something like this:
using var channel = GrpcChannel.ForAddress("http://localhost:5005");
var client = new Greeter.GreeterClient(channel);
Metadata headers = new()
{
{ "myCustomHeader", myCustomHeader }
};
var reply = await client.SayHelloAsync(new HelloRequest { Name = model.Name }, headers);
Using the Metadata you can pass all headers that you need.
On the gRPC service side, you need to use HttpContextAccessor here
This way you can read the http context request headers
string header = _httpContextAccessor.HttpContext.Request.Headers["myCustomHeader"];
take a look at this repo: here

API request for LinkedIn user data always returns 401

I am building back-end(API) of mobile application on asp.net core. Using swagger for visualization of API calls and so on. Currently I am creating external authentications, I have some problems with LinkedIn.
The structure of application is simple, mobile side gets LinkedIn user's Access Token and sends it to me with API request, I have to request user data from LinkedIn by received Access Token, register or login him/her and return response to mobile side.
There is the code below, and commented links where I tried to send requests.
public async Task<IResponse<LinkedInAuthenticationResponse>> LinkedInAuthentication(string accessToken)
{
using (var httpClient = new HttpClient())
{
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
httpClient.DefaultRequestHeaders.Add("x-li-format", "json");
var oauthUrl = "https://api.linkedin.com/v1/people";
// https://api.linkedin.com/v2/me
// https://api.linkedin.com/v1/people/~:(id,formatted-name,email-address,picture-url)
var response = httpClient.GetAsync(oauthUrl).Result;
string responseContent = string.Empty;
try
{
responseContent = await response.Content.ReadAsStringAsync();
response.EnsureSuccessStatusCode();
return Ok(JsonConvert.DeserializeObject<GoogleAuthenticationResponse>(responseContent));
}
catch (Exception ex)
{
}
}
}
The problem is that LinkedIn doesn't provide exact link where API call should be send, I had to try several of them but the response is always 401.
My Access Token is valid, this can not be problem. I have used almost same code for Facebook and Google and they work perfectly.
Any one can provide link which works for API calls ?
This issue has nothing to do with the asp.net framework but with the endpoint, you are using. Since v1 of the LinkedIn API has been deprecated, you need to change your endpoint as for this link here

How can i consume web api in asp.net MVC

I am new to .Net MVC. I am trying to create a sample CRUD application using Web APIs created in NodeJS.
Reading data from DB(MSSQL) is working fine using the below code in .net MVC
List<student> students = new List<student> { };
HttpResponseMessage response = await client.GetAsync(path);
if (response.IsSuccessStatusCode)
{
students = await response.Content.ReadAsAsync<List<student>>();
}
I want to update the record in DB by consuming the node api in .net MVC. I am using the below code, but its not working,
HttpResponseMessage response = await client.PutAsJsonAsync(
"localhost:8082/update", data);
response.EnsureSuccessStatusCode();
student std = await response.Content.ReadAsAsync<student>();
I want to know how can i consume a web api with PUT method.
Any Help would be appreciated!

Fail to connect an ASP.NET Web Client to a Web API 2.0 individual account authentication server

I am trying to connect an ASP.NET Single Page Application to a ASP.NET Web API 2.0 server with individual authentication. I am able to authenticate with the server using Fiddler and raw http requests as shown in the below tutorial:
Individual Accounts in Web API
My question is how do I point the separate single page client sample easily to the Web API service? Is it just a simple change in a configuration file or a connection string somewhere?
Surprisingly I cannot find that much info on how to do this on the web probably because it is deceptively simple and I am just missing something because I am new to ASP.NET
Update:
I basically want this to point to a different Web API 2.0 server:
static Startup()
{
PublicClientId = "self";
UserManagerFactory = () => new UserManager<IdentityUser>(new UserStore<IdentityUser>());
OAuthOptions = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/Token"),
Provider = new ApplicationOAuthProvider(PublicClientId, UserManagerFactory),
AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
AllowInsecureHttp = true
};
}
public void ConfigureAuth(IAppBuilder app)
{
// Enable the application to use a cookie to store information for the signed in user
// and to use a cookie to temporarily store information about a user logging in with a third party login provider
app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
// Enable the application to use bearer tokens to authenticate users
app.UseOAuthBearerTokens(OAuthOptions);
....
}
That currently points to the root of the application but the Web API 2.0 server is actually on another ASP.NET Application running somewhere else.
This is all code you need to send request to Web Api 2.0:
//line below is for supporting self-generated ssl certificates, you can ommit if you're using http
System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
HttpClientHandler handler = new HttpClientHandler();
//this credentials will be in header
handler.Credentials = new NetworkCredential("someLogin", "somepassword");
client = new HttpClient(handler);
client.BaseAddress = new Uri("http://localhost:4567");
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
mediaTypeFormatter = new JsonMediaTypeFormatter();
var content = new ObjectContent<T>(item, mediaTypeFormatter);
var response = await client.PostAsync("api/account/register", content);
if (response.StatusCode != HttpStatusCode.OK && response.StatusCode != HttpStatusCode.BadRequest)
{
throw new ArgumentException("Internal server error");
}
//and here you have successfully sent request and received response from web api.
You can put it into some method then and use method parameters to pass for example host Uri. You can have that saved for example in Web.config as you mentioned.
So after working with the new ASP.NET MVC 5 and the Single Page Application templates in visual studio 2013 I found that the authentication and security is significantly different. This isn't so obvious from any of the documentation.
They both use the "new" ASP.NET Identity which replaces the older membership however when you use the ASP.NET MVC 5 template you get the same old SQL Server type of security setup through the controllers that used to be there, with the SPA (Single Page Application) Template you get API based token authentication.
The only way to wire up the SPA to another API 2.0 located somewhere else is on the client side of things on the JavaScript side, which is slightly confusing because that's not how the ASP.NET MVC 5 template works. The confusion comes from the fact that the SPA gives you both the server side and the client side setup.

Resources