How do I call API from server side using ASP.NET MVC? - c#

I am trying to pull REST data from an API but I need to handle the calls to the API with some server side solution. I have tried using the following code
try
{
HttpClient client = new HttpClient();
client.Timeout = TimeSpan.FromSeconds(60);
var request = new HttpRequestMessage()
{
RequestUri = new Uri(string.Format("https://jsonodds.com/{0}{1}{2}", "api/odds/", "?source=", "3")),
Method = HttpMethod.Get,
};
request.Headers.Add("JsonOdds-API-Key", "your key");
HttpResponseMessage response = client.SendAsync(request).Result;
if (response.IsSuccessStatusCode)
{
String.Format("Success");
}
}
catch (Exception ex)
{ //log error }
I receive a 407() error. Any ideas or tips how to do this?

If you are going through a proxy server then you need to use a different constructor for HttpClient.
_httpClient = new HttpClient(new HttpClientHandler
{
UseProxy = true,
Proxy = new WebProxy
{
Address = new Uri(proxyUrl),
BypassProxyOnLocal = false,
UseDefaultCredentials = true
}
})
{
BaseAddress = url
};
Replace proxyUrl with your proxy address then replacing the credential with those that are valid for your proxy. This example uses the default credentials, but you can pass a NetworkCredential to the WebProxy.

Related

Is there a way to use an HTTPS proxy in .NET 6?

I need to check if certain HTTPS proxies are working. To do so, I originally thought of using the following code:
var proxy = new WebProxy($"https://proxy-server:port");
var handler = new HttpClientHandler { Proxy = proxy };
using (var client = new HttpClient(handler))
{
client.BaseAddress = new Uri("https://base-address");
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", credentials);
try
{
var content = client.GetStringAsync(filepath).Result;
Console.WriteLine(content);
}
catch (Exception e)
{
Console.WriteLine("Failed. Reason: " + e);
}
}
If I try to access the base-address without the proxy, it works fine. Using the proxy I get an error saying I can only use HTTP or SOCKS proxies. The problem is, I wasn't able to find an alternate solution that supports HTTPS proxies.
You're getting the error because the WebProxy class in .NET does not support HTTPS proxies. However, you can use the HttpClientHandler's SslOptions property to configure the SSL/TLS settings.
var proxy = new WebProxy($"http://proxy-server:port");
var handler = new HttpClientHandler
{
Proxy = proxy,
SslOptions = new SslClientAuthenticationOptions
{
RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true
}
};
using (var client = new HttpClient(handler))
{
client.BaseAddress = new Uri("https://base-address");
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", credentials);
try
{
var content = client.GetStringAsync(filepath).Result;
Console.WriteLine(content);
}
catch (Exception e)
{
Console.WriteLine("Failed. Reason: " + e);
}
}
Create a new instance of HttpClientHandler and set its Proxy property to a new WebProxy that represents the HTTP proxy server.
Set the SslOptions property to a new instance of SslClientAuthenticationOptions and configure the RemoteCertificateValidationCallback to return true, indicating that you want to accept any server certificate.
Create a new instance of HttpClient and pass the handler to its constructor.
Finally, use the client to send an HTTPS GET request to the base-address website.

Teams webhook post (proxy authentication) failed

I'm trying to post a new Teams message. If I don't use proxy, pogram fails half start count with fail: Proxy auth required. If i try to use proxy, build fail by timeout (post timeout).
Maybe some fail in proxy settings?
using (var httpClientHandler = new HttpClientHandler
{
UseDefaultCredentials = true,
UseProxy = true,
Proxy = new WebProxy { UseDefaultCredentials = true }
})
{
using (var httpClient = new HttpClient())
{
var httpResponse = await httpClient.PostAsync(HookUri, StringContent);
}
}

Proxy authentication with Twilio voice api in C#

I want make outbound calls from my console application using C# With Twilio voice api. But most of the time i am getting the connection error message. My system is using the proxy server. So i want to add proxy authentication with the code. Please suggest.
My code is as below :
const string accountSid = "*****************";
const string authToken = "*****************";
var client = new TwilioRestClient(accountSid, authToken); TwilioClient.Init(accountSid, authToken);
var to = new PhoneNumber("*****************");
var from = new PhoneNumber("*****************"); `enter code here`
var call = CallResource.Create(to, from, url: new Uri(tempURL));
Twilio Evangelist here.
If you're trying to use the proxy here, I think using our Rest API is going to be helpful. Try this code below to hook your proxy server up to the HttpClient object:
public static HttpClient GetProxy()
{
// First create a proxy object
var proxyUri = $"{proxyServerSettings.Address}:{proxyServerSettings.Port}";
var proxyCreds = new NetworkCredential("proxyuser", "proxypassword");
var proxy = new WebProxy(proxyUri, false)
{
UseDefaultCredentials = false,
Credentials = proxyCreds,
};
// Now create a client handler which uses that proxy
var httpClientHandler = new HttpClientHandler()
{
Proxy = proxy,
PreAuthenticate = true,
UseDefaultCredentials = false,
};
return new HttpClient(httpClientHandler);
}
To make the telephone call with the proxy, you can use the sample code here:
const string accountSid = "*****************";
const string authToken = "*****************";
string to = "+1xxxxxxxxxx";
string from = "+1xxxxxxxxxx";
string callUrl = $"https://api.twilio.com/2010-04-01/Accounts/{AccountSid}/Calls";
var httpClient = GetProxy();
var authorizationValue = Convert.ToBase64String(Encoding.ASCII.GetBytes($"{accountSid}:{authToken}"));
httpClient.DefaultRequestHeaders.Clear();
httpClient.DefaultRequestHeaders.Add("Authorization", $"Basic {authorizationValue}");
var result= httpClient.PostAsync(callUrl, new FormUrlEncodedContent(new Dictionary<string,string>
{
{"To", to},
{"From", from},
{"Url", "http://demo.twilio.com/docs/voice.xml"}
}));
Let me know if this helps or if you run into additional problems. Happy to help here

Set 'per request' cookie with .Net HttpClient

Hi I'm trying to implement simple http proxy service using Owin infrastructure. This proxy must authenticate user with windows authentication, pull user's properties from the enterprise AD, add this info as a cookie value into original request and then redirect request to the application on the Internet (lets call it External Application).
I'm using HttpClient to send request to the External Application.
However HttpClient does not fit well for this scenario. It seems that the only allowed way to send cookie using it is to put them into CookieContainer and set this CookieContainer as a property of HttpClientHandler. It's ok when you have single user but in case of a proxy service cookie values from different users will mix and overwrite each other.
Is there any way to set cookie or CookieContainer per request? Or maybe there is a better way to redirect requests?
P.S. Here is some code:
Initialization of http handlers:
private void RegisterRoutes(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "Proxy",
routeTemplate: "{*path}",
handler: HttpClientFactory.CreatePipeline
(
innerHandler: new HttpClientHandler(),
handlers: new DelegatingHandler[]
{
new ProxyHandler()
}
),
defaults: new { path = RouteParameter.Optional },
constraints: null);
}
ProxyHandler
internal class ProxyHandler : DelegatingHandler
{
private readonly HttpClient _client;
public ProxyHandler()
{
var handler = new HttpClientHandler { ClientCertificateOptions = ClientCertificateOption.Automatic};
_client = new HttpClient(handler);
}
protected async override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var forwardUri = new UriBuilder(request.RequestUri);
forwardUri.Host = "localhost";
forwardUri.Port = 23016;
forwardUri.Scheme = Uri.UriSchemeHttp;
request.RequestUri = forwardUri.Uri;
request.Headers.Host = forwardUri.Host;
//Explicitly null it to avoid protocol violation
if (request.Method == HttpMethod.Get || request.Method == HttpMethod.Trace)
request.Content = null;
try
{
var response = await _client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cancellationToken);
//Explicitly null it to avoid protocol violation
if (request.Method == HttpMethod.Head)
response.Content = null;
return response;
}
catch (Exception ex)
{
var response = request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex);
string message = ex.Message;
if (ex.InnerException != null)
message += ':' + ex.InnerException.Message;
response.Content = new StringContent(message);
Trace.TraceError("Error:{0}", message);
return response;
}
}
private void SetCookies(HttpRequestMessage request)
{
var container = new CookieContainer();
var authCookieValue = "2EF91D8FD9EDC594F2DB82";
var authCookie = new Cookie("cookieByProxy", authCookieValue);
var targetUri = new Uri("http://localhost:23016/");
container.Add(targetUri, authCookie);
var cookieHeader = container.GetCookieHeader(targetUri);
if (!string.IsNullOrEmpty(cookieHeader))
request.Headers.TryAddWithoutValidation("Cookie", cookieHeader);//Overwriting cookie header with custom values. However cookie values are ignored by HttpClient (both old and new)
}
}
Found solution here: enter link description here
The trick is in explicitly setting UseCookie flag of the HttpClientHandler to false.
var handler = new HttpClientHandler { ClientCertificateOptions = ClientCertificateOption.Automatic, UseCookie = false };

HttpClient adds hostname twice when using proxy server

I am using the HttpClient class to make GET requests, it works perfectly without proxy, but when I try to make a request thought a proxy server, it adds hostname in the path and there is also hostname in headers, so the full url is like http://google.comhttp://google.com/
The code:
static void GetSmth()
{
var baseAddr = new Uri("http://google.com");
var handler = new HttpClientHandler
{
AllowAutoRedirect = false,
UseCookies = true,
UseProxy = true,
Proxy = new WebProxy("111.56.13.168:80", true),
};
HttpClient client = new HttpClient(handler);
client.BaseAddress = baseAddr;
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "/");
var resp = client.SendAsync(request).Result;
}
Wireshark screenshot:
What is wrong with it?

Categories