System.Net.HttpClient.PostAsync work in UWP, but not working in .Net Standard Library - win-universal-app

a have UWP app, that working correctly. Now i working on .Net Standard Library providing same function and i do not now, what I'm doing wrong.
UWP code (working correctly)
private async void btnRVM_ClickR(object sender, RoutedEventArgs e)
{
using (HttpClient httpClient = new HttpClient())
{
Uri uri = new Uri("http://examplecom/api/Account/Register");
HttpContent content = new StringContent(JsonConvert.SerializeObject(new RegistrationObject(tbxUsername.Text, tbxPassword.Text, tbxConfirm.Text)), Encoding.UTF8, "application/json");
try
{
HttpResponseMessage response = await httpClient.PostAsync(uri, content);
}
catch (Exception e1)
{
string excMessage = e1.ToString();
}
}
But almost same code in .Net standard library do not working
public static async Task<object> RegisterAsync(string username, string password, string confirmPassword)
{
using (HttpClient httpClient = new HttpClient())
{
Uri uri = new Uri("http://example/api/Account/Register");
HttpContent content = new StringContent(JsonConvert.SerializeObject(new RegistrationObject(username, password, confirmPassword)), Encoding.UTF8, "application/json");
try
{
HttpResponseMessage response = await httpClient.PostAsync(uri, content);
}
catch (Exception e1)
{
string excMessage = e1.ToString();
}
return Task.FromResult<object>(null);
}
}

Related

MAUI Http calls to local API freeze on android device, but not on windows

For some reason my http calls to local api freezes on await when running MAUI application on my android device, but works as intended when running it on windows.
The flow:
public ICommand LoginCommand => _loginCommand ??=
new Command(async () =>
{
if (await _userService.Login(Username, Password))
{
Navigate("//chatrooms");
}
});
public async Task<bool> Login(string username, string password)
{
try
{
var response = await _barigaProApiClient.SignIn(
new SignInRequest
{
Username = username,
Password = password
});
}
catch (Exception)
{
return false;
}
return true;
}
public async Task<SignInResponse> SignIn(SignInRequest request)
{
var content = new StringContent(JsonConvert.SerializeObject(request), Encoding.UTF8, "application/json");
var response = await _client.PostAsync("/api/User/SignIn", content); // stuck here
response.EnsureSuccessStatusCode();
return JsonConvert.DeserializeObject<SignInResponse>(await response.Content.ReadAsStringAsync());
}
At first I thought it could be a deadlock and unmanaged synchronization context.
Found an article with similar problem, got a suggestion to use .ConfigureAwait(false) to fix that, but it still did not work.

Disable Azure Function on a particular condition

We have a azure function where we are calling few API's. its an eventhub trigger function. we have a scenario where the api which we are calling goes into schedule maintenance very often. we want to build a re try mechanism where we are re trying for x number of times and on failure we want to disable the function on runtime. is there a way we can do that in the function app itself?
Thank you Melissa and Ian Kemp. Posting your suggestions as answer to help other community members.
Use the below code to disable the Azure Function
public class FunctionsHelper
{
private readonly ClientSecretCredential _tokenCredential;
private readonly HttpClient _httpClient;
public FunctionsHelper(string tenantId, string clientId, string clientSecret, string subscriptionId, string resourceGroup, string functionAppName)
{
var baseUrl =
$"https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroup}/providers/Microsoft.Web/sites/{functionAppName}/";
var httpClient = new HttpClient
{
BaseAddress = new Uri(baseUrl)
};
_httpClient = httpClient;
_tokenCredential = new ClientSecretCredential(tenantId, clientId, clientSecret);
}
private async Task SetAuthHeader()
{
var accessToken = await GetAccessToken();
_httpClient.DefaultRequestHeaders.Authorization = AuthenticationHeaderValue.Parse($"Bearer {accessToken}");
}
private async Task<string> GetAccessToken()
{
return (await _tokenCredential.GetTokenAsync(
new TokenRequestContext(new[] {"https://management.azure.com/.default"}))).Token;
}
public async Task StopFunction(string functionName)
{
await SetFunctionState(functionName, isDisabled: true);
}
public async Task StartFunction(string functionName)
{
await SetFunctionState(functionName, isDisabled: false);
}
private async Task SetFunctionState(string functionName, bool isDisabled)
{
await SetAuthHeader();
var appSettings = await GetAppSettings();
appSettings.properties[$"AzureWebJobs.{functionName}.Disabled"] = isDisabled ? "1" : "0";
var payloadJson = JsonConvert.SerializeObject(new
{
kind = "<class 'str'>", appSettings.properties
});
var stringContent = new StringContent(payloadJson, Encoding.UTF8, "application/json");
await _httpClient.PutAsync("config/appsettings?api-version=2019-08-01", stringContent);
}
private async Task<AppSettings> GetAppSettings()
{
var res = await _httpClient.PostAsync("config/appsettings/list?api-version=2019-08-01", null);
var content = await res.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<AppSettings>(content);
}
}
internal class AppSettings
{
public Dictionary<string, string> properties { get; set; }
}
Check the SO for further information.

Azure AD B2B SSO with a multi-tenant application, I'm getting a response like "Insufficient privileges to complete the operation."

I have used the following permissions:
public void Test()
{
try
{
string tenantId = User.FindFirst("http://schemas.microsoft.com/identity/claims/tenantid").Value;
string authority = "https://login.microsoftonline.com/{0}/common/oauth2/v2.0/token?scope=openid%20profile%20User.ReadWrite%20User.ReadBasic.All%20Sites.ReadWrite.All%20Contacts.ReadWrite%20People.Read%20Notes.ReadWrite.All%20Tasks.ReadWrite%20Mail.ReadWrite%20Files.ReadWrite.All%20Calendars.ReadWrite";
string graphResourceId = "https://graph.microsoft.com";
string clientId = "XXX-XXX-XXX-XXX";
string secret = "XXXXXXXXXXXXXXXXXXXXXXXX";
authority = String.Format(authority, tenantId);
AuthenticationContext authContext = new AuthenticationContext(authority);
var accessToken = authContext.AcquireTokenAsync(graphResourceId, new ClientCredential(clientId, secret)).Result.AccessToken;
var graphserviceClient = new GraphServiceClient(new DelegateAuthenticationProvider(requestMessage =>
{
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", accessToken);
return Task.FromResult(0);
}));
var _users = graphserviceClient.Users.Request().GetAsync().Result;
}
catch (Exception ex)
{
throw ex;
}
}
public async Task<IActionResult> Index()
{
string tenantId = User.FindFirst("http://schemas.microsoft.com/identity/claims/tenantid").Value;
string ClientID = "xxx-xxx-xxx-xxx";
ActiveDirectoryClient adClient = new ActiveDirectoryClient(new Uri("https://graph.windows.net/" + tenantId), async () => await GetAppTokenAsync(tenantId).ConfigureAwait(true));
try
{
var naaaewuser = adClient.Users.ExecuteAsync().Result;
}
catch (Exception ex)
{
throw ex;
}
return View();
}
"code": "Authorization_RequestDenied"
"value": "Insufficient privileges to complete the operation."
Can anyone help me how can I get users list of an organization who has signed in without “Admin Consent”? Also, please let me know if there is any alternative for this.
Thank you
I got solution and get users basic profile of my organization. Solution: Get Access token using AcquireTokenSilentAsync method. More Details
https://stackoverflow.com/a/52734558/4689622
Thanks All

Send JSON to webapi controller

This seems like it should be easy. I need to POST data like this to a webapi controller:
{
"startRace":"2016-08-22T12:00:00.000Z",
"endRace":"2016-08-26T12:00:00.000Z" }
So I created a console app and here is the snippet of code that handles the POST event:
var i = (int)DateTime.Now.DayOfWeek;
var startRace = DateTime.Today.AddDays(i);
var endRace = DateTime.Today.AddDays(i + 4);
var raceDates = new Dictionary<string, string>
{
{"startRace", startRace.ToString("u")},
{"endRace", endRace.ToString("u")}
};
var json = JsonConvert.SerializeObject(raceDates);
using (var http = new HttpClient())
{
try {
HttpResponseMessage response = http.PostAsync("http://localhost:15312/api/race/dates/post",
new StringContent(json, Encoding.UTF8, "application/json")).Result;
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
But everytime I run the app, I always get this error message:
String is not in JSON format
Is there something I'm missing?
Thanks!
This is a working example code.
Console App
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
var i = (int)DateTime.Now.DayOfWeek;
var startRace = DateTime.Today.AddDays(i);
var endRace = DateTime.Today.AddDays(i + 4);
var raceDates = new Dictionary<string, string>
{
{"startRace", startRace.ToString("u")},
{"endRace", endRace.ToString("u")}
};
var json = JsonConvert.SerializeObject(raceDates);
using (var http = new HttpClient())
{
try
{
HttpResponseMessage response = http.PostAsync("http://localhost:15312/api/race/dates/post/?raceDates=" + raceDates,
new StringContent(json, Encoding.UTF8, "application/json")).Result;
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
}
}
}
Web API
using System.Collections.Generic;
using System.Web.Http;
namespace WebApplication1.Controllers
{
public class RaceController : ApiController
{
[Route("api/race/dates/post")]
public void Post(Dictionary<string, string> raceDates)
{
var dates = new Dictionary<string, string>
{
{"startRace", raceDates["startRace"]},
{"endRace", raceDates["endRace"]}
};
}
}
}

Win Phone 8 / Asp .Net Web API Image Upload

The following code responsible for uploading images:
[HttpPost]
public async Task<HttpResponseMessage> Upload()
{
if (!Request.Content.IsMimeMultipartContent())
{
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}
var streamProvider = new MultipartMemoryStreamProvider();
Cloudinary cloudinary = new Cloudinary(ConfigurationManager.AppSettings.Get("CLOUDINARY_URL"));
return await Request.Content.ReadAsMultipartAsync(streamProvider).ContinueWith(t =>
{
if (t.IsFaulted || t.IsCanceled)
throw new HttpResponseException(HttpStatusCode.InternalServerError);
var content = streamProvider.Contents.FirstOrDefault().ReadAsStreamAsync();
ImageUploadParams uploadParams = new ImageUploadParams()
{
File = new CloudinaryDotNet.Actions.FileDescription(Guid.NewGuid().ToString(), content.Result)
};
ImageUploadResult uploadResult = cloudinary.Upload(uploadParams);
string url = cloudinary.Api.UrlImgUp.BuildUrl(String.Format("{0}.{1}", uploadResult.PublicId, uploadResult.Format));
return Request.CreateResponse<MediaModel>(HttpStatusCode.Created, new MediaModel { URL = url });
});
}
It works via jquery post request. However, in win phone 8 application, the following code does not seem to make a request to the api:
public async Task<string> UploadImage(byte[] image)
{
var client = new HttpClient();
var content = new MultipartFormDataContent();
var imageContent = new ByteArrayContent(image);
imageContent.Headers.ContentType = MediaTypeHeaderValue.Parse("image/jpeg");
content.Add(imageContent, "image", string.Format("{0}.jpg", Guid.NewGuid().ToString()));
return await client.PostAsync(baseURL + "image/Upload", content).Result.Content.ReadAsStringAsync().ContinueWith(t =>
{
return t.Result;
});
}
What is the problem here? I hope someone could show me the proper use of httpclient.
It is a classic Turkish İ problem. Changing "image/Upload" to "Image/Upload" solved the problem.

Resources