forked from Azure-Samples/azure-search-openai-demo-csharp
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
321 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
@page "/call-web-api" | ||
@using System.Text.Json | ||
@using System.Text.Json.Serialization | ||
@inject IHttpClientFactory ClientFactory | ||
|
||
<h1>Call web API from a Blazor Server Razor component</h1> | ||
|
||
@if (getBranchesError || branches is null) | ||
{ | ||
<p>Unable to get branches from GitHub. Please try again later.</p> | ||
} | ||
else | ||
{ | ||
<ul> | ||
@foreach (var branch in branches) | ||
{ | ||
<li>@branch.Name</li> | ||
} | ||
</ul> | ||
} | ||
|
||
@code { | ||
private IEnumerable<GitHubBranch>? branches = []; | ||
private bool getBranchesError; | ||
private bool shouldRender; | ||
|
||
protected override bool ShouldRender() => shouldRender; | ||
|
||
protected override async Task OnInitializedAsync() | ||
{ | ||
var request = new HttpRequestMessage(HttpMethod.Get, | ||
"https://api.github.com/repos/dotnet/AspNetCore.Docs/branches"); | ||
request.Headers.Add("Accept", "application/vnd.github.v3+json"); | ||
request.Headers.Add("User-Agent", "HttpClientFactory-Sample"); | ||
|
||
var client = ClientFactory.CreateClient(); | ||
|
||
var response = await client.SendAsync(request); | ||
|
||
if (response.IsSuccessStatusCode) | ||
{ | ||
using var responseStream = await response.Content.ReadAsStreamAsync(); | ||
branches = await JsonSerializer.DeserializeAsync | ||
<IEnumerable<GitHubBranch>>(responseStream); | ||
} | ||
else | ||
{ | ||
getBranchesError = true; | ||
} | ||
|
||
shouldRender = true; | ||
} | ||
|
||
public class GitHubBranch | ||
{ | ||
[JsonPropertyName("name")] | ||
public string? Name { get; set; } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,182 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.IO; | ||
using System.Threading.Tasks; | ||
using System.Net; | ||
using System.Text; | ||
using System.Net.Http; | ||
using Newtonsoft.Json; | ||
using Newtonsoft.Json.Linq; | ||
using Microsoft.AspNetCore.SignalR; | ||
using Microsoft.AspNetCore.Mvc; | ||
using MinimalApi.Hubs; | ||
using MinimalApi.Models; | ||
|
||
namespace MinimalApi.Controllers; | ||
|
||
[Route("api/[controller]")] | ||
public class UpdatesController : Controller | ||
{ | ||
#region Data Members | ||
|
||
private bool EventTypeSubcriptionValidation | ||
=> HttpContext.Request.Headers["aeg-event-type"].FirstOrDefault() == | ||
"SubscriptionValidation"; | ||
|
||
private bool EventTypeNotification | ||
=> HttpContext.Request.Headers["aeg-event-type"].FirstOrDefault() == | ||
"Notification"; | ||
|
||
private readonly IHubContext<GridEventsHub> _hubContext; | ||
|
||
#endregion | ||
|
||
#region Constructors | ||
|
||
public UpdatesController(IHubContext<GridEventsHub> gridEventsHubContext) | ||
{ | ||
this._hubContext = gridEventsHubContext; | ||
} | ||
|
||
#endregion | ||
|
||
#region Public Methods | ||
|
||
[HttpOptions] | ||
public Task<IActionResult> OptionsAsync() | ||
{ | ||
using (var reader = new StreamReader(Request.Body, Encoding.UTF8)) | ||
{ | ||
var webhookRequestOrigin = HttpContext.Request.Headers["WebHook-Request-Origin"].FirstOrDefault(); | ||
var webhookRequestCallback = HttpContext.Request.Headers["WebHook-Request-Callback"]; | ||
var webhookRequestRate = HttpContext.Request.Headers["WebHook-Request-Rate"]; | ||
HttpContext.Response.Headers.Append("WebHook-Allowed-Rate", "*"); | ||
HttpContext.Response.Headers.Append("WebHook-Allowed-Origin", webhookRequestOrigin); | ||
} | ||
|
||
return Task.FromResult<IActionResult>(Ok()); | ||
} | ||
|
||
[HttpPost] | ||
public async Task<IActionResult> PostAsync() | ||
{ | ||
using (var reader = new StreamReader(Request.Body, Encoding.UTF8)) | ||
{ | ||
var jsonContent = await reader.ReadToEndAsync(); | ||
|
||
// Check the event type. | ||
// Return the validation code if it's | ||
// a subscription validation request. | ||
if (EventTypeSubcriptionValidation) | ||
{ | ||
return await HandleValidationAsync(jsonContent); | ||
} | ||
else if (EventTypeNotification) | ||
{ | ||
// Check to see if this is passed in using | ||
// the CloudEvents schema | ||
if (IsCloudEvent(jsonContent)) | ||
{ | ||
return await HandleCloudEventAsync(jsonContent); | ||
} | ||
|
||
return await HandleGridEventsAsync(jsonContent); | ||
} | ||
|
||
return new JsonResult(BadRequest()); | ||
} | ||
} | ||
|
||
#endregion | ||
|
||
#region Private Methods | ||
|
||
private async Task<JsonResult> HandleValidationAsync(string jsonContent) | ||
{ | ||
var gridEvent = | ||
JsonConvert.DeserializeObject<List<GridEvent<Dictionary<string, string>>>>(jsonContent) | ||
?.FirstOrDefault(); | ||
if (gridEvent == null) | ||
{ | ||
// Handle the case when the list is empty or null. | ||
return Json(BadRequest()); | ||
} | ||
|
||
await this._hubContext.Clients.All.SendAsync( | ||
"gridupdate", | ||
gridEvent.Id, | ||
gridEvent.EventType, | ||
gridEvent.Subject, | ||
gridEvent.EventTime.ToLongTimeString(), | ||
jsonContent.ToString()); | ||
|
||
// Retrieve the validation code and echo back. | ||
var validationCode = gridEvent.Data?["validationCode"]; | ||
return new JsonResult(new | ||
{ | ||
validationResponse = validationCode | ||
}); | ||
} | ||
|
||
private async Task<IActionResult> HandleGridEventsAsync(string jsonContent) | ||
{ | ||
var events = JArray.Parse(jsonContent); | ||
foreach (var e in events) | ||
{ | ||
// Invoke a method on the clients for | ||
// an event grid notiification. | ||
var details = JsonConvert.DeserializeObject<GridEvent<dynamic>>(e.ToString()); | ||
await this._hubContext.Clients.All.SendAsync( | ||
"gridupdate", | ||
details?.Id, | ||
details?.EventType, | ||
details?.Subject, | ||
details?.EventTime.ToString("T"), | ||
e.ToString()); | ||
} | ||
|
||
return Ok(); | ||
} | ||
|
||
private async Task<IActionResult> HandleCloudEventAsync(string jsonContent) | ||
{ | ||
var details = JsonConvert.DeserializeObject<CloudEvent<dynamic>>(jsonContent); | ||
var eventData = JObject.Parse(jsonContent); | ||
|
||
await this._hubContext.Clients.All.SendAsync( | ||
"gridupdate", | ||
details?.Id, | ||
details?.Type, | ||
details?.Subject, | ||
details?.Time, | ||
eventData.ToString() | ||
); | ||
|
||
return Ok(); | ||
} | ||
|
||
private static bool IsCloudEvent(string jsonContent) | ||
{ | ||
// Cloud events are sent one at a time, while Grid events | ||
// are sent in an array. As a result, the JObject.Parse will | ||
// fail for Grid events. | ||
try | ||
{ | ||
// Attempt to read one JSON object. | ||
var eventData = JObject.Parse(jsonContent); | ||
|
||
// Check for the spec version property. | ||
var version = eventData["specversion"]?.Value<string>(); | ||
if (!string.IsNullOrEmpty(version)) return true; | ||
} | ||
catch (Exception e) | ||
{ | ||
Console.WriteLine(e); | ||
} | ||
|
||
return false; | ||
} | ||
|
||
#endregion | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
|
||
using Newtonsoft.Json; | ||
|
||
namespace MinimalApi.Models; | ||
|
||
// Reference: https://github.com/cloudevents/spec/tree/v1.0-rc1 | ||
|
||
public class CloudEvent<T> where T : class | ||
{ | ||
[JsonProperty("specversion")] | ||
public string? SpecVersion { get; set; } | ||
|
||
[JsonProperty("type")] | ||
public string? Type { get; set; } | ||
|
||
[JsonProperty("source")] | ||
public string? Source { get; set; } | ||
|
||
[JsonProperty("subject")] | ||
public string? Subject { get; set; } | ||
|
||
[JsonProperty("id")] | ||
public string? Id { get; set; } | ||
|
||
[JsonProperty("time")] | ||
public string? Time { get; set; } | ||
|
||
[JsonProperty("data")] | ||
public T? Data { get; set; } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
using System; | ||
|
||
namespace MinimalApi.Models; | ||
|
||
public class ErrorViewModel | ||
{ | ||
public string? RequestId { get; set; } | ||
|
||
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
using System; | ||
|
||
namespace MinimalApi.Models; | ||
|
||
public class GridEvent<T> where T : class | ||
{ | ||
public string? Id { get; set; } | ||
public string? EventType { get; set; } | ||
public string? Subject { get; set; } | ||
public DateTime EventTime { get; set; } | ||
public T? Data { get; set; } | ||
public string? Topic { get; set; } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
using Microsoft.AspNetCore.SignalR; | ||
|
||
namespace MinimalApi.Hubs; | ||
|
||
public class GridEventsHub : Hub | ||
{ | ||
public GridEventsHub() | ||
{ | ||
} | ||
} |