'identity.api.rackspacecloud.com' randomly throws 'The remote name could not be resolved' exception - dotnet-httpclient

I am accessing Rackspace Cloud APIs.
I have one api call which authenticates me on the rackspace cloud.
The method works perfectly, however, from time to time, i get this exception, randomly :
The remote name could not be resolved: 'identity.api.rackspacecloud.com'
When i am not getting this exception, the method returns the expected result, as it should be.
Is there any specific reason why it does this?
Here is my .net code:
private async Task<XDocument> AuthenticateAsync()
{
XNamespace ns = "http://docs.rackspace.com/identity/api/ext/RAX-KSKEY/v1.0";
XDocument doc =
new XDocument(
new XDeclaration("1.0", "UTF-8", "Yes"),
new XElement("auth",
new XElement(ns + "apiKeyCredentials",
new XAttribute("username", "the userName"),
new XAttribute("apiKey", "the apiKey")
)
)
);
using (HttpClient client = new HttpClient())
{
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml"));
StringContent content = new StringContent(doc.ToString(), Encoding.UTF8, "application/xml");
// i randomly get "The remote name could not be resolved" exception
HttpResponseMessage response = await client.PostAsync("https://identity.api.rackspacecloud.com/v2.0/tokens", content);
response.EnsureSuccessStatusCode();
string stringResponse = await response.Content.ReadAsStringAsync();
return XDocument.Parse(stringResponse);
}
}

This certainly sounds like a DNS failure. Can you configure your machine to use the Google DNS servers and try again?

Related

Google Spreadsheets api: Error o.s.b.w.servlet.support.ErrorPageFilter : Forwarding to error page from request due to exception Address already in us

I have write the code get google could credential by below code for read google spreadsheet data:
public static Credential getCredentials(final NetHttpTransport HTTP_TRANSPORT, String spreadsheetCredentialURL)
throws IOException {
// Load client secrets.
InputStream in = new URL( awsBucketUrl+spreadsheetCredentialURL).openStream();
if (in == null) {
throw new FileNotFoundException("Resource not found: " + awsBucketUrl+spreadsheetCredentialURL);
}
GoogleClientSecrets clientSecrets =
GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in));
in.close();
// Build flow and trigger user authorization request.
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, SCOPES)
.setDataStoreFactory(new FileDataStoreFactory(new java.io.File(TOKENS_DIRECTORY_PATH)))
.setAccessType("offline")
.build();
LocalServerReceiver receiver = new LocalServerReceiver.Builder().setPort(8099).build();
return new AuthorizationCodeInstalledApp(flow, receiver).authorize("user");
}
Now, when i am deploying this code to my develop environment on docker serve it is givin me below error:
2022-09-07 12:52:40.461 ERROR 1 --- [nio-8080-exec-6] o.s.b.w.servlet.support.ErrorPageFilter : Forwarding to error page from request [/google/spreadsheets-tabs/1Klc6IICWEiq-Oi9YEEbRxbqtEylJ4Ti0UtKNkieYo8Q] due to exception [Address already in us].
The same code is working on my local laptop environment.
anyone has any idea?

How to convert Office files to PDF using Microsoft Graph

I'm looking for a way to convert Office files to PDF.
I found out that Microsoft Graph could be used.
I'm trying to download converted PDF using Microsoft Graph from OneDrive.
I'd like to convert .docx to .pdf.
However, when I sent the following request, I did not receive a response even if I waited.
GET https://graph.microsoft.com/v1.0/users/{id}/drive/root:/test.docx:/content?format=pdf
Also, the error code is not returned.
If syntax is wrong, an error code will be returned as expected.
It will not return only when it is correct.
In addition, I can download the file if I do not convert.
GET https://graph.microsoft.com/v1.0/users/{id}/drive/root:/test.docx:/content
Is my method wrong or else I need conditions?
If possible, please give me sample code that you can actually do.
using (HttpClient client = new HttpClient())
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", authResult.AccessToken);
client.BaseAddress = new Uri(graphUrl);
var result = await client.GetAsync("/v1.0/users/xxxxxxxxxxxxxxxxxxxxxxxxx/drive/root:/test.docx:/content?format=pdf");
:
I would like to elaborate a bit Marc's answer by providing a few examples for HttpClient.
Since by default for HttpClient HttpClientHandler.AllowAutoRedirect property is set to True there is no need to explicitly follow HTTP redirection headers and the content could be downloaded like this:
using (HttpClient client = new HttpClient())
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
client.BaseAddress = new Uri("https://graph.microsoft.com");
var response = await client.GetAsync($"/v1.0/drives/{driveId}/root:/{filePath}:/content?format=pdf");
//save content into file
using (var file = System.IO.File.Create(fileName))
{
var stream = await response.Content.ReadAsStreamAsync();
await stream.CopyToAsync(file);
}
}
In case if follow HTTP redirection is disabled, to download the converted file, your app must follow the Location header in the response as demonstrated below:
var handler = new HttpClientHandler()
{
AllowAutoRedirect = false
};
using (HttpClient client = new HttpClient(handler))
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
client.BaseAddress = new Uri("https://graph.microsoft.com");
var response = await client.GetAsync($"/v1.0/drives/{driveId}/root:/{filePath}:/content?format=pdf");
if(response.StatusCode == HttpStatusCode.Redirect)
{
response = await client.GetAsync(response.Headers.Location); //get the actual content
}
//save content into file
using (var file = System.IO.File.Create(fileName))
{
var stream = await response.Content.ReadAsStreamAsync();
await stream.CopyToAsync(file);
}
}
The API doesn't return the converted content directly, it returns a link to the converted file. From the documentation:
Returns a 302 Found response redirecting to a pre-authenticated download URL for the converted file.
To download the converted file, your app must follow the Location header in the response.
Pre-authenticated URLs are only valid for a short period of time (a few minutes) and do not require an Authorization header to access.
You need to capture the 302 and make a 2nd call to the URI in the Location header in order to download the converted file.

Azure notification hub installation c#

Can anyone help me with Azure notification hub, how to set up device installation form c# code. I have problem with the Installation object. How to set it to pass it as parameter to CreateOrUpdateInstallation method of hub client instance. It's not clear to me.
I have a hub on azure that works with device registration like charm in local, but uploaded on azure are not working. Now I wanna try with istalation.
thnx
update: after 4 days, I figured out, that you can't send notification to yourself. Azure somehow knows that you are sending notification to yours phone, and that's why my welcome message never delivered to my phone.
update: this is how now I install the device i my backend code:
[HttpGet]
[Route("api/push/test-installation")]
public async Task<IActionResult> NotificationInstalationTest()
{
string connectionString = "{{my connection string}}";
string hubName = "{{my hub name}}";
string token = "{{tokne}}";
NotificationHubClient hubClient = NotificationHubClient.CreateClientFromConnectionString(connectionString, hubName);
string notificationText = $"Test message for Azure delivery for Atila at: {DateTime.Now.ToShortTimeString()}";
var alert = new JObject
(
new JProperty("aps", new JObject(new JProperty("alert", notificationText))),
new JProperty("inAppMessage", notificationText)
).ToString(Newtonsoft.Json.Formatting.None);
IList<string> tags = new List<string>();
tags.Add("email");
IDictionary<string, string> pushVariables = new Dictionary<string, string>();
pushVariables.Add( "email", "atila#panonicit.com" );
Installation installation = new Installation();
installation.InstallationId = Guid.NewGuid().ToString();
installation.Platform = NotificationPlatform.Apns;
installation.PushChannel = token;
installation.Tags = tags;
installation.PushVariables = pushVariables;
await hubClient.CreateOrUpdateInstallationAsync(installation);
NotificationOutcome result = await hubClient.SendAppleNativeNotificationAsync(alert);
return Ok("Success");
}
Now when I hit this endpoint with Postman it works, if the same endpoint call comes from iOS it not works!
thnx
How to set it to pass it as parameter to CreateOrUpdateInstallation method of hub client instance. It's not clear to me.
Based on my understanding, you are registering the notification hub from your backend using the installation model. For your WebAPI project, assuming your method for create/update an installation as follows:
InstallationController.cs
//PUT api/installation
public async Task<HttpResponseMessage> Put(DeviceInstallation deviceUpdate)
{
Installation installation = new Installation();
installation.InstallationId = deviceUpdate.InstallationId;
//TODO:
await hub.CreateOrUpdateInstallationAsync(installation);
return Request.CreateResponse(HttpStatusCode.OK);
}
For your mobile client, you could refer to the following method:
private async Task<HttpStatusCode> CreateOrUpdateInstallationAsync(DeviceInstallation deviceInstallation)
{
using (var httpClient = new HttpClient())
{
//TODO: set your authorization header
//httpClient.DefaultRequestHeaders.Authorization
var putUri =$"{your-backend-endpoint}/api/installation";
string json = JsonConvert.SerializeObject(deviceInstallation);
var response = await httpClient.PutAsync(putUri, new StringContent(json, Encoding.UTF8, "application/json"));
return response.StatusCode;
}
}
Moreover, for more details you could refer to Registration management and here for building backend with the registration model to build your backend using the installation model.

MVC accessing external Web API using login credentials

In need of some help accessing an external Web API passing along credentials in order to access the methods available. I have included the code below that i use in order to attempt to access the Web API. However, i receive the following error every time i attempt to access it:
"The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel."
What am i missing or what am i doing wrong? I have been circling around this for a couple days and have tried a couple different techniques but continue to get the same error. Here is one technique that i used.
private static async Task<string> GetAPIToken(string userName, string password, string apiBaseUri)
{
try
{
using (var client = new HttpClient())
{
//setup client
client.BaseAddress = new Uri(apiBaseUri);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
//setup login data
var formContent = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string,string>("username",userName),
new KeyValuePair<string,string>("password",password),
});
//send request
HttpResponseMessage responseMessage = await client.PostAsync("Token", formContent);
//get access token from response body
var responseJson = await responseMessage.Content.ReadAsStringAsync();
var jobject = JObject.Parse(responseJson);
return jobject.GetValue("access_token").ToString();
}
}
catch (Exception ex)
{
return null;
}
}
Any help would be greatly appreciated.
Thanks
There is a little bit of a difference when using HTTPS vs HTTP. This question should give you the information you need to fix your problem.
Make Https call using HttpClient

Setting ContentType causing multiple requests in MVC Web API

I have a simple GetFile Method in a Web API that returns a file stored as binary in a database. The file can be either image, video or a recording, so I set the content type based on the extension:
[System.Web.Mvc.HttpGet]
public HttpResponseMessage GetFile(Guid Id)
{
HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
var file = db.Files.Where<NonConformityFile>(item => item.Id == Id).FirstOrDefault<NonConformityFile>();
byte[] imgData = file.FileContents;
MemoryStream ms = new MemoryStream(imgData);
response.Content = new StreamContent(ms);
if (file.FileExtension == "png")
response.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("image/png");
else if (file.FileExtension == "mp4")
response.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("video/mp4");
else if (file.FileExtension == "caf")
response.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("audio/x-caf");
else
throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.UnsupportedMediaType, file.FileExtension + " is not a supported file format"));
return response;
}
This Works fine, but when adding some Security to the Method (by providing a token in the http header) it started crashing. When setting a breakpoint, I discovered that the breakpoint was actually hit twice. And the second time the token was gone from the header, causing authentication failure.
Further debugging made me find out that setting the response.Content.Header.ContentType causes the GetFile Method to be called a second time.
Is this designed behaviour, or some crazy side effects from something in my Development environment?
To reproduce, try this:
[System.Web.Mvc.HttpGet]
public HttpResponseMessage GetFile()
{
HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
response.Content = new StreamContent(new MemoryStream());
response.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("image/png");
return response;
}
And see if the Method is run twice. I cannot see the Logic in this behaviour, and it is causing problems in my authentication.

Resources