From d9f1a5ac0fd9e4653237e7efb159f4e5dd1b7df3 Mon Sep 17 00:00:00 2001
From: Luke Latham <1622880+guardrex@users.noreply.github.com>
Date: Mon, 20 May 2019 15:48:00 -0500
Subject: [PATCH 1/8] Blazor call web API topic with sample
Updates
---
aspnetcore/blazor/call-web-api.md | 230 ++++++++++++++++++
.../Components/HTTPRequestTester.razor | 178 ++++++++++++++
.../3.x/BlazorSample/Pages/CallWebAPI.razor | 129 ++++++++++
.../common/samples/3.x/BlazorSample/README.md | 18 ++
.../3.x/BlazorSample/Shared/NavMenu.razor | 5 +
.../3.x/BlazorSample/wwwroot/css/site.css | 21 ++
aspnetcore/toc.yml | 2 +
7 files changed, 583 insertions(+)
create mode 100644 aspnetcore/blazor/call-web-api.md
create mode 100644 aspnetcore/blazor/common/samples/3.x/BlazorSample/Components/HTTPRequestTester.razor
create mode 100644 aspnetcore/blazor/common/samples/3.x/BlazorSample/Pages/CallWebAPI.razor
diff --git a/aspnetcore/blazor/call-web-api.md b/aspnetcore/blazor/call-web-api.md
new file mode 100644
index 000000000000..0e160bd6ebf7
--- /dev/null
+++ b/aspnetcore/blazor/call-web-api.md
@@ -0,0 +1,230 @@
+---
+title: Call a web API
+author: guardrex
+description: Learn how to call a web API from a Blazor app using JSON helpers, including making cross-origin resource sharing (CORS) requests.
+monikerRange: '>= aspnetcore-3.0'
+ms.author: riande
+ms.custom: mvc
+ms.date: 05/20/2019
+uid: blazor/call-web-api
+---
+# Call a web API
+
+By [Luke Latham](https://github.com/guardrex)
+
+Blazor apps call web API services using [HttpClient](xref:fundamentals/http-requests). Compose requests using Blazor JSON helpers or with , which can include JavaScript [Fetch API](https://developer.mozilla.org/docs/Web/API/Fetch_API) request options.
+
+[View or download sample code](https://github.com/aspnet/AspNetCore.Docs/tree/master/aspnetcore/blazor/common/samples/) ([how to download](xref:index#how-to-download-a-sample))
+
+See the following components in the sample app:
+
+* Call Web API (*Pages/CallWebAPI.razor*)
+* HTTP Request Tester (*Components/HTTPRequestTester.razor*)
+
+## HttpClient and JSON helpers
+
+Use [HttpClient](xref:fundamentals/http-requests) and JSON helpers to call a web API service endpoint in a Razor component. Blazor client-side uses the [Fetch API](https://developer.mozilla.org/docs/Web/API/Fetch_API), while Blazor server-side uses .
+
+Include an `@using` statement for for asynchronous web API calls and inject an `HttpClient` instance:
+
+```cshtml
+@using System.Threading.Tasks
+@inject HttpClient Http
+```
+
+In the following examples, a Todo web API service processes create, read, update, and delete (CRUD) operations. The examples are based on a `TodoItem` class that stores the:
+
+* ID (`Id`, `long`) – Unique ID of the item.
+* Name (`Name`, `string`) – Name of the item.
+* Status (`IsComplete`, `bool`) – Indication if the Todo item is finished.
+
+```csharp
+private class TodoItem
+{
+ public long Id { get; set; }
+ public string Name { get; set; }
+ public bool IsComplete { get; set; }
+}
+```
+
+JSON helper methods send requests to a URI (a web API in the following examples) and process the response:
+
+* `GetJsonAsync` – Sends a GET request and parses the JSON response body to create an object.
+
+ In the following code, the `_todoItems` are displayed by the component. The `GetTodoItems` method is triggered when the component is finished rendering ([OnInitAsync](xref:blazor/components#lifecycle-methods)). See the sample app for a complete example.
+
+ ```cshtml
+ @using Microsoft.AspNetCore.Blazor.Http
+ @inject HttpClient Http
+
+ @functions {
+ private const string ServiceEndpoint = "https://localhost:10000/api/todo";
+ private TodoItem[] _todoItems;
+
+ protected override async Task OnInitAsync() =>
+ await GetTodoItems();
+
+ private async Task GetTodoItems() =>
+ _todoItems = await Http.GetJsonAsync(ServiceEndpoint);
+ }
+ ```
+
+* `PostJsonAsync` – Sends a POST request, including JSON-encoded content, and parses the JSON response body to create an object.
+
+ In the following code, `_newItemName` is provided by a bound element of the component. The `AddItem` method is triggered by selecting a `
+}
+
+@functions {
+ private string _uri = "https://localhost:10000/api/todo";
+ private string _method = "POST";
+ private string _requestBody = @"{""name"":""A New Todo Item"",""isComplete"":false}";
+ private List _requestHeaders = new List()
+{
+ new RequestHeader() { Name = "Content-Type", Value = "application/json" },
+ new RequestHeader() { Name = "Authorization", Value = "Bearer MHrHDcEfxjoYZgeFONFh7HgQ" }
+ };
+ private string _requestReferrer;
+ private string _credentials = "include";
+ private HttpStatusCode? _responseStatusCode;
+ private string _responseBody;
+ private string _responseHeaders;
+
+ protected override void OnInit()
+ {
+ _requestReferrer = UriHelper.GetAbsoluteUri();
+ }
+
+ private async void DoRequest()
+ {
+ _responseStatusCode = null;
+
+ try
+ {
+ var requestMessage = new HttpRequestMessage()
+ {
+ Method = new HttpMethod(_method),
+ RequestUri = new Uri(_uri),
+ Content = string.IsNullOrEmpty(_requestBody)
+ ? null
+ : new StringContent(_requestBody)
+ };
+
+ foreach (var header in _requestHeaders)
+ {
+ // StringContent automatically adds its own Content-Type header with default value "text/plain"
+ // If the developer is trying to specify a content type explicitly, we need to replace the default value,
+ // rather than adding a second Content-Type header.
+ if (header.Name.Equals("Content-Type", StringComparison.OrdinalIgnoreCase) && requestMessage.Content != null)
+ {
+ requestMessage.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(header.Value);
+ continue;
+ }
+
+ if (!requestMessage.Headers.TryAddWithoutValidation(header.Name, header.Value))
+ {
+ requestMessage.Content?.Headers.TryAddWithoutValidation(header.Name, header.Value);
+ }
+ }
+
+ requestMessage.Properties[WebAssemblyHttpMessageHandler.FetchArgs] = new
+ {
+ referrer = _requestReferrer,
+ credentials = _credentials
+ };
+
+ var response = await Http.SendAsync(requestMessage);
+ _responseStatusCode = response.StatusCode;
+ _responseBody = await response.Content.ReadAsStringAsync();
+ var allHeaders = response.Headers.Concat(response.Content?.Headers
+ ?? Enumerable.Empty>>());
+ _responseHeaders = string.Join(
+ Environment.NewLine,
+ allHeaders.Select(pair => $"{pair.Key}: {pair.Value.First()}").ToArray());
+ }
+ catch (Exception ex)
+ {
+ if (ex is AggregateException)
+ {
+ ex = ex.InnerException;
+ }
+ _responseStatusCode = HttpStatusCode.SeeOther;
+ _responseBody = ex.Message + Environment.NewLine + ex.StackTrace;
+ }
+
+ StateHasChanged();
+ }
+
+ private void AddHeader()
+ => _requestHeaders.Add(new RequestHeader());
+
+ private void RemoveHeader(RequestHeader header)
+ => _requestHeaders.Remove(header);
+
+ private class RequestHeader
+ {
+ public string Name { get; set; }
+ public string Value { get; set; }
+ }
+}
diff --git a/aspnetcore/blazor/common/samples/3.x/BlazorSample/Pages/CallWebAPI.razor b/aspnetcore/blazor/common/samples/3.x/BlazorSample/Pages/CallWebAPI.razor
new file mode 100644
index 000000000000..119d8ab4adf0
--- /dev/null
+++ b/aspnetcore/blazor/common/samples/3.x/BlazorSample/Pages/CallWebAPI.razor
@@ -0,0 +1,129 @@
+@page "/CallWebAPI"
+@using System.IO
+@using System.Linq
+@using System.Threading.Tasks
+@inject HttpClient Http
+
+
Call a Web API from Blazor
+
+
Blazor Example
+
+
This example requires a running web API service based on the sample app for the Tutorial: Create a web API with ASP.NET Core MVC topic. This Blazor sample app makes requests to the web API service at https://localhost:10000/api/todo. If a different service address is used, update the ServiceEndpoint constant value in the Razor component's @@functions block.
+
+
The Blazor sample app makes a cross-origin resource sharing (CORS) request from http://localhost:5000 or https://localhost:5001 to the web API service app. Add the following CORS middleware configuration to the web API's service's Startup.Configure method before it calls UseMvc:
Adjust the domains and ports of WithOrigins as needed for the Blazor app.
+
+
Todo Items
+
+@if (_todoItems == null)
+{
+
No Todo Items found.
+}
+else
+{
+
+
+
+
Complete
+
Name
+
+
+
+
+
+
+
+
+
+
+
+
+ Save
+ Cancel
+
+
+ @foreach (var item in _todoItems)
+ {
+
+
+ @if (item.IsComplete)
+ {
+ ✔
+ }
+
+
@item.Name
+
+ Edit
+ Delete
+
+
+ }
+
+
+
+
+
+
+ Add
+
+
+
+
+}
+
+
+
+@functions {
+ private const string ServiceEndpoint = "https://localhost:10000/api/todo";
+ private TodoItem[] _todoItems;
+ private TodoItem _editItem = new TodoItem();
+ private string _editRowStyle = "none";
+ private string _newItemName;
+
+ protected override async Task OnInitAsync() => await GetTodoItems();
+
+ private async Task GetTodoItems() => _todoItems = await Http.GetJsonAsync(ServiceEndpoint);
+
+ private void EditItem(long id)
+ {
+ var editItem = _todoItems.Single(i => i.Id == id);
+ _editItem = new TodoItem { Id = editItem.Id, Name = editItem.Name, IsComplete = editItem.IsComplete };
+ _editRowStyle = "table-row";
+ }
+
+ private async Task AddItem()
+ {
+ var addItem = new TodoItem { Name = _newItemName, IsComplete = false };
+ await Http.PostJsonAsync(ServiceEndpoint, addItem);
+ _newItemName = string.Empty;
+ await GetTodoItems();
+ _editRowStyle = "none";
+ }
+
+ private async Task SaveItem()
+ {
+ await Http.PutJsonAsync(Path.Combine(ServiceEndpoint, _editItem.Id.ToString()), _editItem);
+ await GetTodoItems();
+ _editRowStyle = "none";
+ }
+
+ private async Task DeleteItem(long id)
+ {
+ await Http.DeleteAsync(Path.Combine(ServiceEndpoint, id.ToString()));
+ await GetTodoItems();
+ _editRowStyle = "none";
+ }
+
+ private class TodoItem
+ {
+ public long Id { get; set; }
+ public string Name { get; set; }
+ public bool IsComplete { get; set; }
+ }
+}
diff --git a/aspnetcore/blazor/common/samples/3.x/BlazorSample/README.md b/aspnetcore/blazor/common/samples/3.x/BlazorSample/README.md
index b98ea521e350..eabbb5516430 100644
--- a/aspnetcore/blazor/common/samples/3.x/BlazorSample/README.md
+++ b/aspnetcore/blazor/common/samples/3.x/BlazorSample/README.md
@@ -1,3 +1,21 @@
# Blazor (client-side) Sample App
This sample illustrates the use of Blazor scenarios described in the Blazor documentation.
+
+## Call web API example
+
+The web API example requires a running web API service based on the sample app for the Tutorial: Create a web API with ASP.NET Core MVC topic. The sample app makes requests to the web API service at `https://localhost:10000/api/todo`. If a different service address is used, update the `ServiceEndpoint` constant value in the Razor component's `@functions` block.
+
+The sample app makes a cross-origin resource sharing (CORS) request from `http://localhost:5000` or `https://localhost:5001` to the web API service app. Credentials (authorization cookies/headers) are permitted. Add the following CORS middleware configuration to the web API service's `Startup.Configure` method before it calls `UseMvc`:
+
+```csharp
+app.UseCors(policy =>
+ policy.WithOrigins("http://localhost:5000", "https://localhost:5001")
+ .AllowAnyMethod()
+ .WithHeaders(HeaderNames.ContentType, HeaderNames.Authorization)
+ .AllowCredentials());
+```
+
+Adjust the domains and ports of `WithOrigins` as needed for the Blazor app.
+
+The web API service is configured for CORS to permit authorization cookies/headers and requests from client code, but the service as created by the tutorial doesn't actually authorize requests. See the ASP.NET Core Security and Identity articles for implementation guidance.
diff --git a/aspnetcore/blazor/common/samples/3.x/BlazorSample/Shared/NavMenu.razor b/aspnetcore/blazor/common/samples/3.x/BlazorSample/Shared/NavMenu.razor
index 13ed562052e7..4786f13a7644 100644
--- a/aspnetcore/blazor/common/samples/3.x/BlazorSample/Shared/NavMenu.razor
+++ b/aspnetcore/blazor/common/samples/3.x/BlazorSample/Shared/NavMenu.razor
@@ -64,6 +64,11 @@
JavaScript Interop
+
+
+ Call a Web API
+
+
diff --git a/aspnetcore/blazor/common/samples/3.x/BlazorSample/wwwroot/css/site.css b/aspnetcore/blazor/common/samples/3.x/BlazorSample/wwwroot/css/site.css
index 24e247ab262e..f19e5a0a1234 100644
--- a/aspnetcore/blazor/common/samples/3.x/BlazorSample/wwwroot/css/site.css
+++ b/aspnetcore/blazor/common/samples/3.x/BlazorSample/wwwroot/css/site.css
@@ -4,6 +4,11 @@ html, body {
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
}
+textarea {
+ width: 100%;
+ height: 60px;
+}
+
app {
position: relative;
display: flex;
@@ -155,6 +160,22 @@ app {
border-top-width: 0;
}
+.table td {
+ vertical-align: middle;
+}
+
+.table input {
+ width: 100%;
+}
+
+.table #editRow {
+ background-color: lightyellow;
+}
+
+.table #addRow {
+ background-color: palegreen;
+}
+
@media (max-width: 767.98px) {
.main .top-row {
display: none;
diff --git a/aspnetcore/toc.yml b/aspnetcore/toc.yml
index 6bb6a9e457ef..13e30414ef80 100644
--- a/aspnetcore/toc.yml
+++ b/aspnetcore/toc.yml
@@ -299,6 +299,8 @@
uid: blazor/javascript-interop
- name: Debug
uid: blazor/debug
+ - name: Call a web API
+ uid: blazor/call-web-api
- name: Host and deploy
items:
- name: Overview
From 48f7bd450f3dfe8dc8f54b884ea14a86adbab441 Mon Sep 17 00:00:00 2001
From: Luke Latham <1622880+guardrex@users.noreply.github.com>
Date: Fri, 14 Jun 2019 12:51:55 -0500
Subject: [PATCH 2/8] Title update
---
aspnetcore/blazor/call-web-api.md | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/aspnetcore/blazor/call-web-api.md b/aspnetcore/blazor/call-web-api.md
index 0e160bd6ebf7..5d2d679b8847 100644
--- a/aspnetcore/blazor/call-web-api.md
+++ b/aspnetcore/blazor/call-web-api.md
@@ -1,14 +1,14 @@
---
-title: Call a web API
+title: Call a web API from ASP.NET Core Blazor
author: guardrex
description: Learn how to call a web API from a Blazor app using JSON helpers, including making cross-origin resource sharing (CORS) requests.
monikerRange: '>= aspnetcore-3.0'
ms.author: riande
ms.custom: mvc
-ms.date: 05/20/2019
+ms.date: 06/14/2019
uid: blazor/call-web-api
---
-# Call a web API
+# Call a web API from ASP.NET Core Blazor
By [Luke Latham](https://github.com/guardrex)
From d0f6126d3a1949b83dd8bb803753c98c99338bfe Mon Sep 17 00:00:00 2001
From: Luke Latham <1622880+guardrex@users.noreply.github.com>
Date: Fri, 21 Jun 2019 14:21:02 -0500
Subject: [PATCH 3/8] React to feedback
---
aspnetcore/blazor/call-web-api.md | 106 ++++++++----------
.../common/samples/3.x/BlazorSample/App.razor | 6 +-
.../3.x/BlazorSample/BlazorSample.csproj | 12 +-
.../Components/HTTPRequestTester.razor | 24 ++--
.../JsInteropClasses/ExampleJsInterop.cs | 2 +-
.../3.x/BlazorSample/Pages/CallWebAPI.razor | 27 ++---
.../3.x/BlazorSample/wwwroot/css/site.css | 12 ++
7 files changed, 91 insertions(+), 98 deletions(-)
diff --git a/aspnetcore/blazor/call-web-api.md b/aspnetcore/blazor/call-web-api.md
index 5d2d679b8847..56e5f4efa9b2 100644
--- a/aspnetcore/blazor/call-web-api.md
+++ b/aspnetcore/blazor/call-web-api.md
@@ -5,12 +5,12 @@ description: Learn how to call a web API from a Blazor app using JSON helpers, i
monikerRange: '>= aspnetcore-3.0'
ms.author: riande
ms.custom: mvc
-ms.date: 06/14/2019
+ms.date: 06/21/2019
uid: blazor/call-web-api
---
# Call a web API from ASP.NET Core Blazor
-By [Luke Latham](https://github.com/guardrex)
+By [Luke Latham](https://github.com/guardrex) and [Daniel Roth](https://github.com/danroth27)
Blazor apps call web API services using [HttpClient](xref:fundamentals/http-requests). Compose requests using Blazor JSON helpers or with , which can include JavaScript [Fetch API](https://developer.mozilla.org/docs/Web/API/Fetch_API) request options.
@@ -21,14 +21,19 @@ See the following components in the sample app:
* Call Web API (*Pages/CallWebAPI.razor*)
* HTTP Request Tester (*Components/HTTPRequestTester.razor*)
+> [!NOTE]
+> This topic applies to Blazor client-side apps that call web APIs in a Razor Component.
+>
+> In Blazor server-side apps, the implementation is provided by .NET Core. An `HttpClient` service for Blazor server-side apps is in-design. For more information, see [Making HTTP requests from Blazor apps](https://github.com/aspnet/AspNetCore/issues/10397) in the aspnet/AspNetCore GitHub repository.
+
## HttpClient and JSON helpers
-Use [HttpClient](xref:fundamentals/http-requests) and JSON helpers to call a web API service endpoint in a Razor component. Blazor client-side uses the [Fetch API](https://developer.mozilla.org/docs/Web/API/Fetch_API), while Blazor server-side uses .
+Use [HttpClient](xref:fundamentals/http-requests) and JSON helpers to call a web API service endpoint from a Blazor app. In Blazor client-side apps, `HttpClient` is implemented using the browser [Fetch API](https://developer.mozilla.org/docs/Web/API/Fetch_API) and is subject to its limitations, including enforcement of the same origin policy. In Blazor server-side apps, the implementation is provided by .NET Core and can be used when making web API requests in server-side code.
-Include an `@using` statement for for asynchronous web API calls and inject an `HttpClient` instance:
+In Blazor client-side apps, `HttpClient` is available as a service. The client's base address is set to the originating server's address. Inject an `HttpClient` instance using the `@inject` directive. If the component isn't routable and thus doesn't include the `@page` directive, import with an `@using` directive:
```cshtml
-@using System.Threading.Tasks
+@using System.Net.Http
@inject HttpClient Http
```
@@ -54,18 +59,14 @@ JSON helper methods send requests to a URI (a web API in the following examples)
In the following code, the `_todoItems` are displayed by the component. The `GetTodoItems` method is triggered when the component is finished rendering ([OnInitAsync](xref:blazor/components#lifecycle-methods)). See the sample app for a complete example.
```cshtml
- @using Microsoft.AspNetCore.Blazor.Http
+ @using System.Net.Http
@inject HttpClient Http
- @functions {
- private const string ServiceEndpoint = "https://localhost:10000/api/todo";
+ @code {
private TodoItem[] _todoItems;
protected override async Task OnInitAsync() =>
- await GetTodoItems();
-
- private async Task GetTodoItems() =>
- _todoItems = await Http.GetJsonAsync(ServiceEndpoint);
+ _todoItems = await Http.GetJsonAsync("api/todo");
}
```
@@ -74,20 +75,19 @@ JSON helper methods send requests to a URI (a web API in the following examples)
In the following code, `_newItemName` is provided by a bound element of the component. The `AddItem` method is triggered by selecting a `` element. See the sample app for a complete example.
```cshtml
- @using Microsoft.AspNetCore.Blazor.Http
+ @using System.Net.Http
@inject HttpClient Http
-
- Add
+
+ Add
- @functions {
- private const string ServiceEndpoint = "https://localhost:10000/api/todo";
+ @code {
private string _newItemName;
private async Task AddItem()
{
var addItem = new TodoItem { Name = _newItemName, IsComplete = false };
- await Http.PostJsonAsync(ServiceEndpoint, addItem);
+ await Http.PostJsonAsync("api/todo", addItem);
}
}
```
@@ -97,67 +97,67 @@ JSON helper methods send requests to a URI (a web API in the following examples)
In the following code, `_editItem` values (`Id`, `Name`, `IsCompleted`) are provided by bound elements of the component. The `SaveItem` method is triggered by selecting the Save `` element. See the sample app for a complete example.
```cshtml
- @using Microsoft.AspNetCore.Blazor.Http
+ @using System.Net.Http
@inject HttpClient Http
-
-
-
- Save
+
+
+
+ Save
- @functions {
- private const string ServiceEndpoint = "https://localhost:10000/api/todo";
+ @code {
private TodoItem _editItem = new TodoItem();
- private async Task SaveItem()
- {
- await Http.PutJsonAsync(
- Path.Combine(ServiceEndpoint, _editItem.Id.ToString()), _editItem);
- }
+ private async Task SaveItem() =>
+ await Http.PutJsonAsync($"api/todo/{_editItem.Id}, _editItem);
}
```
includes additional extension methods for sending HTTP requests and receiving HTTP responses. [HttpClient.DeleteAsync](xref:System.Net.Http.HttpClient.DeleteAsync*) is used to send a DELETE request to a web API.
-In the following code, the Delete `` element supplies the `id` when it's selected in the UI. See the sample app for a complete example.
+In the following code, the Delete `` element calls the `DeleteItem` method. The bound `` element supplies the `id` of the item to delete. See the sample app for a complete example.
```cshtml
-@using Microsoft.AspNetCore.Blazor.Http
+@using System.Net.Http
@inject HttpClient Http
-
-Delete
+
+Delete
@functions {
- private const string ServiceEndpoint = "https://localhost:10000/api/todo";
private long _id;
- private async Task DeleteItem()
- {
- await Http.DeleteAsync(Path.Combine(ServiceEndpoint, _id.ToString()));
- }
+ private async Task DeleteItem() =>
+ await Http.DeleteAsync($"api/todo/{_id}");
}
```
+## Cross-origin resource sharing (CORS)
+
+Browser security prevents a web page from making requests to a different domain than the one that served the web page. This restriction is called the *same-origin policy*. The same-origin policy prevents a malicious site from reading sensitive data from another site. Sometimes, you might want to allow other sites make cross-origin resource sharing (CORS) requests to your app.
+
+The sample app demonstrates the use of CORS in the Call Web API component (*Pages/CallWebAPI.razor*).
+
+For more information, see .
+
## HttpClient and HttpRequestMessage with Fetch API request options
-Use [HttpClient](xref:fundamentals/http-requests) and to supply request options to the underlying JavaScript [Fetch API](https://developer.mozilla.org/docs/Web/API/Fetch_API).
+Use [HttpClient](xref:fundamentals/http-requests) and to customize requests.
In the following example:
-* JSON serialization and deserialization must be handled by user code (*not shown*).
-* The `credentials` property is set to any of the following values:
+When running on WebAssembly in a Blazor client-side app, supply request options to the underlying JavaScript [Fetch API](https://developer.mozilla.org/docs/Web/API/Fetch_API) using the `WebAssemblyHttpMessageHandler.FetchArgs` property on the request. As shown in the following example, the `credentials` property is set to any of the following values:
- * `FetchCredentialsOption.Include` ("include") – Advises the browser to send credentials (such as cookies or HTTP auth headers) even for cross-origin requests. Only allowed when the CORS Middleware policy in the web API is configured to .
+ * `FetchCredentialsOption.Include` ("include") – Advises the browser to send credentials (such as cookies or HTTP authentication headers) even for cross-origin requests. Only allowed when the CORS policy is configured to allow credentials.
* `FetchCredentialsOption.Omit` ("omit") – Advises the browser never to send credentials (such as cookies or HTTP auth headers).
* `FetchCredentialsOption.SameOrigin` ("same-origin") – Advises the browser to send credentials (such as cookies or HTTP auth headers) only if the target URL is on the same origin as the calling application.
```cshtml
+@using System.Net.Http
@using System.Net.Http.Headers
-@using Microsoft.AspNetCore.Blazor.Http
@inject HttpClient Http
-@functions {
+@code {
private async Task PostRequest()
{
Http.DefaultRequestHeaders.Authorization =
@@ -191,7 +191,7 @@ In the following example:
}
```
-For more information on Fetch API options, see [MDN web docs: WindowOrWorkerGlobalScope.fetch():Parameters](https://developer.mozilla.org/docs/Web/API/WindowOrWorkerGlobalScope/fetch#Parameters).
+For more information on Fetch API options, see [MDN web docs: WindowOrWorkerGlobalScope.fetch():Parameters](https://developer.mozilla.org/docs/Web/API/WindowOrWorkerGlobalScope/fetch#Parameters).
When sending credentials (authorization cookies/headers) on CORS requests, allow the `Authorization` header when creating the CORS policy for CORS middleware. The following policy includes configuration for:
@@ -210,20 +210,6 @@ app.UseCors(policy =>
For more information, see and the sample app's HTTP Request Tester component (*Components/HTTPRequestTester.razor*).
-## Cross-origin resource sharing (CORS)
-
-For more information on making cross-origin resource sharing (CORS) requests, see . The sample app demonstrates CORS. See the Call Web API component (*Pages/CallWebAPI.razor*).
-
-## HTTP Request Tester
-
-The sample app includes an HTTP Request Tester component (*Components/HTTPRequestTester.razor*). The component is included in the Call Web API component:
-
-```cshtml
-
-```
-
-Use the component to test request-responses against web API service endpoints.
-
## Additional resources
*
diff --git a/aspnetcore/blazor/common/samples/3.x/BlazorSample/App.razor b/aspnetcore/blazor/common/samples/3.x/BlazorSample/App.razor
index 80fb778674c0..eb5c93b6dee4 100644
--- a/aspnetcore/blazor/common/samples/3.x/BlazorSample/App.razor
+++ b/aspnetcore/blazor/common/samples/3.x/BlazorSample/App.razor
@@ -1 +1,5 @@
-
+
+
+