Xamarin.Forms make Http POST request using a webview - webview

I am new to Xamarin and currently implementing a Xamarin.Forms application which has a XAML based Login page with Username/Password fields and a Submit button.
Once the user enters the credentials and hit Submit, I need to make a request to the server to generate a JWT token(which I'm getting using an HttpClient) for the validated user.
And then This token should be sent via form-data to a web page and the response page should be loaded in a WebView.
Is this possible in Xamarin.forms? If yes how can it be done?

Is this possible in Xamarin.forms?
Yes, you can use HttpClient
HttpClient client = new HttpClient() { Timeout = TimeSpan.FromSeconds(30) };
HttpContent content = new StringContent(JsonConvert.SerializeObject(objectToPost), Encoding.UTF8, "application/x-www-form-urlencoded");
var response = await client.PostAsync(new Uri("http://your.url"), content);
if (response.IsSuccessStatusCode) {
var responseFromServer = await response.Content.ReadAsStringAsync();
}
else {
// handle errors
}

Related

Twitch API OAuth

Please let me know if this is not possible...but in an effort to refactor my personal API I decided to start calling the Twitch endpoints through my API so data can be combined. To do this I direct the user to the auth page and get a bearer token back. I then pass that token to my API in the header. For some reason I get a 401 if I try to use that token at all from my API. I have no idea why as I can't view a reason in the response. The token works from postman.
Here is an example of a request I make in my API:
public async Task<bool> ValidateToken()
{
var response = await client.GetAsync("https://id.twitch.tv/oauth2/validate");
return response.StatusCode == HttpStatusCode.OK;
}
The HttpClient is created as follows before the validation method is called:
public TwitchService(IHeaderDictionary headers)
{
StringValues token;
StringValues clientId;
var hasToken = headers.TryGetValue("Authorization", out token);
var hasClientId = headers.TryGetValue("Client-id", out clientId);
client = new HttpClient();
client.DefaultRequestHeaders.Add("Accept", "application/json");
if (hasToken)
{
var authToken = token.ToString().Replace("Bearer", "");
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", authToken);
}
if (hasClientId)
{
client.DefaultRequestHeaders.Add("Client-ID", clientId.ToString());
}
}
It turns out that the auth header is removed by the HttpClient and this is by design. The following link gives a good explanation about it: Authorization header is lost on redirect

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.

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

Microsoft Bot Framework project to add a chatbot to my website. I cannot use the Web Chat client. What other methods can I use ?

I am working on a Microsoft Bot Framework project to add a chatbot to my website.
I need to pass data continuously from the chat UI to the Bot to get user details and current page details. Therefore I cannot use the Web Chat client.
What other methods can I use apart from creating my own chat interface ?
What other methods can I use apart from creating my own chat interface ? According to this statement, WebChat is the easiest way. Because only with an embeded Iframe you are done creating your chatbot. Apart from that,
There is a REST Api to access the botframework. It is called as Direct Line API. You can find documentation from,
HERE
Below is a code sample about how you can use it. I tried with the ASP.NET MVC application.
private async Task<bool> PostMessage(string message)
{
bool IsReplyReceived = false;
client = new HttpClient();
client.BaseAddress = new Uri("https://directline.botframework.com/api/conversations/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("BotConnector", "[YourAccessToken]");
response = await client.GetAsync("/api/tokens/");
if (response.IsSuccessStatusCode)
{
var conversation = new Conversation();
response = await client.PostAsJsonAsync("/api/conversations/", conversation);
if (response.IsSuccessStatusCode)
{
Conversation ConversationInfo = response.Content.ReadAsAsync(typeof(Conversation)).Result as Conversation;
string conversationUrl = ConversationInfo.conversationId+"/messages/";
BotDirectLineApproch.Models.Message msg = new BotDirectLineApproch.Models.Message() { text = message };
response = await client.PostAsJsonAsync(conversationUrl,msg);
if (response.IsSuccessStatusCode)
{
response = await client.GetAsync(conversationUrl);
if (response.IsSuccessStatusCode)
{
MessageSet BotMessage = response.Content.ReadAsAsync(typeof(MessageSet)).Result as MessageSet;
ViewBag.Messages = BotMessage;
IsReplyReceived = true;
}
}
}
}
return IsReplyReceived;
}
In here Message, MessageSet and Conversation are classes created by looking at the Json response in the documentation. If you need, I can add that also.
Cheers!

Communication Between Asp.net MVC and window Store app

Please let me know the procedure for communication between window store app and MVC such that data can be passed from MVC to Store app and vice versa.
Did you mean call to a web API?
You can use System.Net.Http.HttpClient to send http requests & receive responses.
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://localhost:9000/");
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>();
Console.WriteLine("{0}\t${1}\t{2}", product.Name, product.Price, product.Category);
}
}
A detailed guide available Here. It shows how you can use WebApi with Windows store app.
The recommended way to connect to a web service is to use the Windows.Web.Http.HttpClient (which supersedes System.Net.Http.HttpClient). This can be used to send any normal HTTP request (PUT, POST, GET, etc.)
using Windows.Web.Http;
using (HttpClient hc = new HttpClient())
{
Uri uri = new Uri("https://api.stackexchange.com/2.2/questions/27796508?order=desc&sort=activity&site=stackoverflow");
try
{
string json = await hc.GetStringAsync(uri);
}
catch (Exception ex)
{
// Handle network exceptions
}
}
See How to connect to an HTTP server using Windows.Web.Http on MSDN and the HttpClient sample for more details.

Resources