creating webjob to get status of webjobs of same app service - azure

I am creating one webjob which needs to send mail of status of webjobs. I am using webjob API aka "https://xyz.scm.ase-03.com/api/triggeredwebjobs" to get the webjobs details. I am getting the response from my local httpclient call but while deploying it as a webjob on azure then I am getting null response. Here is my code:
var result = string.Empty;
var url = "https://domain.dev.xyz.com/api/";
var baseURL = "triggeredwebjobs";
string userPswd = "username " + ":" + "password"; // getting username and password from publish profile.
userPswd = Convert.ToBase64String(Encoding.Default.GetBytes(userPswd));
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(url);
client.Timeout = TimeSpan.FromMinutes(30);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic",userPswd );
var response = new HttpResponseMessage();
response = client.GetAsync(baseURL).Result; // Here I am getting null value.
result = response.IsSuccessStatusCode ? (response.Content.ReadAsStringAsync().Result) : response.IsSuccessStatusCode.ToString();
}
I am in doubt that calling self webjobs api url maybe not working so I deployed it to another app service but no luck.
Can anyone let me know where is the issue may be?
Thanks in advance.

Related

.net 6 Blazor WebAssembly Deployed to Azure 400 Error when trying to send email via SendGrid

I have a basic Blazor WebAssembly project that is using SendGrid to send form data via email. Locally it works fine. I have deployed to Azure App Service and setup API Management as well.
Locally I set an EnvironmentVariable to hold my SendGrid Api key.
This is the EmailService code.
public async Task<ServiceResponse<Contact>> SendEmail(Contact info)
{
var apiKey = Environment.GetEnvironmentVariable("SENDGRID_API_KEY");
var toEmail = _config.GetSection("SendGrid:EmailTo").Value;
var toName = _config.GetSection("SendGrid:EmailName").Value;
var _subject = _config.GetSection("SendGrid:EmailSubject").Value;
var client = new SendGridClient(apiKey);
var from = new EmailAddress($"{info.Email}", $"{info.Name}");
var subject = _subject;
var to = new EmailAddress(toEmail, toName);
var plainTextContent = info.Message;
var htmlContent = info.Message;
var msg = MailHelper.CreateSingleEmail(from, to, subject, plainTextContent, htmlContent);
var response = await client.SendEmailAsync(msg);
if (response.IsSuccessStatusCode)
{
return new ServiceResponse<Contact>
{
Data = info,
Success = true,
Message = "Message has been sent."
};
}
else
{
return new ServiceResponse<Contact> { Success = false };
}
}
In Azure App Service I created an Application setting named "SENDGRID_API_KEY" and it holds the SendGrid API key. I also tried modifying the request before it is sent and added the Authorization header there as well.
When the form submits, it returns a 400 (Bad Request) error.
I do not have a secure certificate on this site yet.
Any ideas? Please let me know if you need more info.

Access Azure Data Explorer with Kusto.Data in Azure Function -- Kusto failed to send request -- local debugging works

I am having the following problem and an extensive search online didn't provide any good results.
When trying to access my Azure Data Explorer Database and querying using the Kusto.Data SDK in an Azure Function, it yields the following error:
Kusto client failed to send a request to the service: 'An unknown, invalid, or unsupported option or level was specified in a getsockopt or setsockopt call.'
However, running the Function on my local machine, everything works fine.
Edit: The function excepts at using (var reader = await queryProvider.ExecuteQueryAsync(Database, query, clientRequestProperties))
EDIT2 - SOLUTION:
You can downgrade the NuGet Kusto.Data Package to Version 9.4.1, this solves the problem and doesn't throw any error anymore. If you still encounter difficulties, you can try to directly access the ADX database via http requests:
const string tenantId = "<tenantId>";
const string client_id = "<clientId>";
const string client_secret = "<client_secret>";
const string Cluster = "<cluster_adress";
const string Database = "<database_name>";
var authUrl = "https://login.microsoftonline.com/<tenantId>/oauth2/token";
var param = new Dictionary<string, string>
{
{"client_id",client_id},
{"grant_type","client_credentials"},
{"client_secret",client_secret},
{"resource","https://help.kusto.windows.net"}
};
var data = new FormUrlEncodedContent(param);
using var authClient = new HttpClient();
var response = await authClient.PostAsync(authUrl, data);
string result = response.Content.ReadAsStringAsync().Result;
//parse result
var resultJson = System.Text.Json.JsonDocument.Parse(result);
//retrieve access token
var accessToken = resultJson.RootElement.GetProperty("access_token");
//-----------------------------------------------------------------------------------------------
var dataXUrl = Cluster + "/v1/rest/query";
var database = Database;
var dataXQuery = "sample_table| where Time > ago(2min)";
var body = new Dictionary<string, string>
{
{"db",database},
{"csl",dataXQuery}
};
using var dataXClient = new HttpClient();
dataXClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken.ToString());
dataXClient.DefaultRequestHeaders.Add("Accept", "application/json");
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, dataXUrl);
request.Content = new StringContent(JsonConvert.SerializeObject(body), Encoding.UTF8, "application/json");
var table = await dataXClient.SendAsync(request);
//pretty print
var obj = JsonConvert.DeserializeObject(table.Content.ReadAsStringAsync());
var tableJSON = JsonConvert.SerializeObject(obj, Formatting.Indented);
log.LogInformation("\n\n" + tableJSON);
I am having the same issue on a continuous webjob on an Azure App Service. The Kusto nuget version I am using is 10.1.0
Downgrading to nuget 9.4.1 solved the problem immediately.
FYI - This only seems to affect 10.1.0. The earlier 10.x.x versions should work.
The ADX team believes they will have this fixed in the next nuget version.

Unable to post to an external API endpoint from an App Service website in Azure

I am doing an HttpPost to the FedEx tracking API endpoint from the backend of a web app that I am hosting in Azure.
The app works fine on my development machine and can post to the endpoint just fine. But after deploying it to my App service it is no longer able to call the FedEx api to get the required oauth token.
AccessTokenInfo responseObj = new();
using (var client = new HttpClient()) {
client.BaseAddress = new Uri(_fedexConfig.BaseUri);
client.DefaultRequestHeaders.Accept.Add(new
MediaTypeWithQualityHeaderValue("application/json"));
var response = new HttpResponseMessage();
var allIputParams = new List<KeyValuePair<string, string>>() {
new KeyValuePair<string, string>("grant_type","client_credentials"),
new KeyValuePair<string, string>("client_id",_fedexConfig.ClientId),
new KeyValuePair<string, string>("client_secret", _fedexConfig.ClientSecret)
};
HttpContent requestParams = new FormUrlEncodedContent(allIputParams);
response = await client.PostAsync(_fedexConfig.TokenUri,requestParams).ConfigureAwait(false);
}
When the call is made the response only returns a 403 error "forbidden".
Is there some additional settings that the AppService needs to have to communicate with an api endpoint outside the Azure environment?

Update Application Settings: Azure Functions

I am trying to update only one application setting using below request. My setting is getting updated properly, but my all other application settings are vanished. I see only one settings there with the correct updated value which I tried to update. I do not want to loose or change all other application settings.
What am I missing here or what is wrong I am doing?
I am following the below given article:
https://learn.microsoft.com/en-us/rest/api/appservice/webapps/updateapplicationsettings
PUT https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/config/appsettings
I am using their online tool to send the request:
https://learn.microsoft.com/en-us/rest/api/appservice/webapps/updateapplicationsettings
Since I am using the online tool it is generating the authorization token. But I want to do programmatically. It would be great if I can get the sample code to generate the token and to update application settings.
Authorization: Bearer
eyJ0eXAiOixxxxxxxeyE_rd3Cw
Content-type: application/json
I reproduce your problem and if you want to update application setting, you need to write down all the application settings, otherwise it will be overridden by the one application setting.
Preparation:
1.Register an App registration in Azure Active Directory and get appid and appsecret. Please refer to this article.
2.Add the registered app into Role assignments under Access control.
Here is C# code sample you could refer to.
var appId = "xxxxxxxxxxxxxxxxxxxx";
var secretKey = "xxxxxxxxxxxxxxxxxxxx";
var tenantId = "xxxxxxxxxxxxxxxxxxx";
var context = new AuthenticationContext("https://login.windows.net/" + tenantId);
ClientCredential clientCredential = new ClientCredential(appId, secretKey);
var tokenResponse = context.AcquireTokenAsync("https://management.azure.com/", clientCredential).Result;
var accessToken = tokenResponse.AccessToken;
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + accessToken);
var baseUrl = new Uri($"https://management.azure.com/");
var requestURl = baseUrl +
#"subscriptions/xxxxxxxxxxxxxxxxxxx/resourceGroups/xxxxxx/providers/Microsoft.Web/sites/xxxxxx/config/appsettings?api-version=2016-08-01";
string body = "{\"kind\": \"webapp\",\"properties\": {\"WEBSITE_NODE_DEFAULT_VERSION\": \"6.9.1\",\"aaa\": \"bbb\"}}";
var stringContent = new StringContent(body, Encoding.UTF8, "application/json");
var response = client.PutAsync(requestURl, stringContent).Result;
}
The result is as below:

400-BadRequest while call rest api of azure Web App

var client = new HttpClient();
client.DefaultRequestHeaders.Add("x-ms-version", "2016-05-31");
var content = new FormUrlEncodedContent(new KeyValuePair<string, string>[]
{
new KeyValuePair<string, string>("api-version", "2016-08-01")
});
content.Headers.ContentType = new MediaTypeHeaderValue("application/xml");
var response = client.PostAsync("https://management.azure.com/subscriptions/SuscriptionID/resourceGroups/Default-Web-SoutheastAsia/providers/Microsoft.Web/sites/MyAppName/stop?", content);
This is how I make a call to Azure WebApp rest api but I am getting statuscode : BadRequest
There are some issues with your code:
You're mixing Azure Service Management API with Azure Resource Manager (ARM) API. API to stop a web app is a Resource Manager API thus you don't need to provide x-ms-version.
You're missing the Authorization header in your request. ARM API requests require an authorization header. Please see this link on how to perform ARM API requests: https://learn.microsoft.com/en-us/rest/api/gettingstarted/.
Based on these, I modified your code:
static async void StopWebApp()
{
var subscriptionId = "<your subscription id>";
var resourceGroupName = "<your resource group name>";
var webAppName = "<your web app name>";
var token = "<bearer token>";
var url = string.Format("https://management.azure.com/subscriptions/{0}/resourceGroups/{1}/providers/Microsoft.Web/sites/{2}/stop?api-version=2016-08-01", subscriptionId, resourceGroupName, webAppName);
var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token);
var t = await client.PostAsync(url, null);
var response = t.StatusCode;
Console.WriteLine(t.StatusCode);
}
Please try using this code. Assuming you have acquired proper token, the code should work.

Resources