Skip to content

Instantly share code, notes, and snippets.

@SteveSandersonMS
Created February 20, 2018 10:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save SteveSandersonMS/ba34011dd4ee8bb3021c8837ff68ef28 to your computer and use it in GitHub Desktop.
Save SteveSandersonMS/ba34011dd4ee8bb3021c8837ff68ef28 to your computer and use it in GitHub Desktop.
Manually implemented HTTP client
@using StandaloneApp.Util
@(Layout<StandaloneApp.Shared.MainLayout>())
<h1>Hello, world!</h1>
Welcome to your new app.
<button @onclick(DoRequest)>Do request</button>
<div><strong>Response: </strong>@responseText</div>
@functions {
string responseText;
private async void DoRequest()
{
responseText = await new MyHttpClient().GetStringAsync("/index.html");
StateHasChanged();
}
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Blazor standalone</title>
<link href="/css/bootstrap/bootstrap.min.css" rel="stylesheet" />
<link href="/css/site.css" rel="stylesheet" />
</head>
<body>
<app>Loading...</app>
<script src="/css/bootstrap/bootstrap-native.min.js"></script>
<script type="blazor-boot"></script>
<script src="myhttpclient.js"></script>
</body>
</html>
using Microsoft.AspNetCore.Blazor.Browser.Interop;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
namespace StandaloneApp.Util
{
public class MyHttpClient
{
static object _idLock = new object();
static int _nextRequestId = 0;
static IDictionary<int, TaskCompletionSource<HttpResponseMessage>> _pendingRequests
= new Dictionary<int, TaskCompletionSource<HttpResponseMessage>>();
public async Task<string> GetStringAsync(string requestUri)
{
var response = await GetAsync(requestUri);
if (!response.IsSuccessStatusCode)
{
throw new HttpRequestException($"The response status code was {response.StatusCode}");
}
return await response.Content.ReadAsStringAsync();
}
public Task<HttpResponseMessage> GetAsync(string requestUri)
{
var tcs = new TaskCompletionSource<HttpResponseMessage>();
int id;
lock (_idLock)
{
id = _nextRequestId++;
_pendingRequests.Add(id, tcs);
}
RegisteredFunction.Invoke<object>("HttpClientSend", id, requestUri);
return tcs.Task;
}
private static void ReceiveResponse(string id, string statusCode, string responseText, string errorText)
{
TaskCompletionSource<HttpResponseMessage> tcs;
var idVal = int.Parse(id);
lock (_idLock)
{
tcs = _pendingRequests[idVal];
_pendingRequests.Remove(idVal);
}
if (errorText == null)
{
tcs.SetResult(new HttpResponseMessage
{
StatusCode = (HttpStatusCode)int.Parse(statusCode),
Content = new StringContent(responseText)
});
}
else
{
tcs.SetException(new HttpRequestException(errorText));
}
}
}
}
(function () {
function dispatchResponse(id, statusCode, responseText, errorInfo) {
var method = Blazor.platform.findMethod('StandaloneApp', 'StandaloneApp.Util', 'MyHttpClient', 'ReceiveResponse');
Blazor.platform.callMethod(method, null, [
Blazor.platform.toDotNetString(id.toString()),
Blazor.platform.toDotNetString(statusCode.toString()),
responseText === null ? null : Blazor.platform.toDotNetString(responseText),
errorInfo === null ? null : Blazor.platform.toDotNetString(errorInfo.toString())
]);
}
Blazor.registerFunction('HttpClientSend', function (id, requestUri) {
fetch(requestUri).then(function (response) {
return response.text().then(function (responseText) {
dispatchResponse(id, response.status, responseText, null);
});
}).catch(function (errorInfo) { dispatchResponse(id, 0, null, errorInfo); });
});
})();
@TylerBrinkley
Copy link

👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment