Blazor WASM 및 REST API – 한 걸음 한 걸음
Blazor WASM 어플리케이션 만들기, 구성 요소 만들기, 탐색 추가, API 연결, API 호출 등의 주제에 대해 논의합니다.
전체 단계별 비디오를 유튜브에서 볼 수 있습니다.
모든 소스 코드를 다운로드할 수도 있습니다.
https://github.com/mohamadlawand087/v9-BlazorWASMAppWithREST
Blazor 여정의 첫 번째 부분입니다.
섹션 2:
애플리케이션을 구축하기 전에 다음과 같은 두 가지 아이디어가 필요합니다.
이제 첫 번째blazor 프로그램과 지원 라이브러리를 만듭니다
dotnet new blazorwasm -n "TodoClient"
blazor 프로젝트는 C# 및 razor 파일로 구성되어 있으며 구조적으로 Asp와 매우 유사합니다.Net 핵심 애플리케이션Razor 파일은 구성 요소라고 하는 UI 요소로 구성되며, 구성 요소는 C 언어로 작성된 #
구성 요소
@page "/counter"
이것은 우리가 이 구성 요소를 내비게이션할 수 있다는 것을 의미한다. 구성 요소는 html과 C# 코드를 포함하고 구성 요소의 C# 코드는 @code 부분에 있다.@code {
private int currentCount = 0;
private void IncrementCount()
{
currentCount++;
}
}
이제 이 프로그램을 실행해서 어떻게 작동하는지, 마이크로소프트가 우리에게 제공한 샘플 코드와의 관계를 봅시다.dotnet run
우리가 그것을 검사하면 프로그램으로 돌아가 프로그램의 구조를 확인하고 wwwroot 폴더를 훑어보고 색인을 열 수 있습니다.html 페이지.이 페이지는 우리 프로그램의 입구점입니다.우리는 이것이 간단한 html 페이지로 자바스크립트와 css에 대한 인용을 포함하고 응용 프로그램 탭도 포함한다는 것을 알 수 있다<app>Loading ...<app>
이 탭은blazor 프로그램의 표시 위치를 지정하고, 모든blazor 프로그램은 app라는 루트 구성 요소를 포함합니다.면도칼이 페이지의 끝에서 우리는 옳은 것을 볼 수 있다
<script src="_framework/blazor.webassembly.js"></script>
이것은 blazor의 실행과 컴파일된 blazor 프로그램을 다운로드하는 데 매우 중요한 파일입니다.Blazor 프로그램이 컴파일되어 dll로 브라우저에 다운로드되었습니다.Asp.Net Core와 Blazor 애플리케이션은 여러 구성 요소를 공유하며 파일 구조에서 하나의 프로그램을 볼 수 있습니다.cs 파일, 안에
builder.RootComponents.Add<App>("#app");
코드에서, 우리는 루트 구성 요소를 어떻게 지정하고, 응용 프로그램 전체에 사용할 태그를 어떻게 분배하는지 볼 수 있다.app 탭은 색인에 있는 탭과 같습니다.우리가 전에 토론한 html.우리도 위의 프로그램을 볼 수 있다.cs 프로그램이 하나 있습니다.razor는 여기에서 인용한 구성 요소입니다.Asp와 유사합니다.Net core blazor에는 내장된 종속성 주입도 포함됩니다.
프로그램 구성 요소를 열면 프로그램의 모든 루트를 책임지는 공유기 구성 요소를 볼 수 있습니다.이게 어떻게 된 일인지 사실은 매우 간단하다.프로그램이 시작될 때, 프로그램 집합은 존재하는 모든 구성 요소를 스캔한 다음, 인용을 하나의 페이지 목록에 저장합니다. 따라서 구성 요소로 이동할 때, 주 구성 요소는 스캔한 구성 요소 목록과 일치하는 경로를 지정한 다음 그것으로 다시 지정합니다.추가 매개 변수를 전달하고 기본 레이아웃을 정의합니다
모든 레이아웃 입력 출력 프로그램을 처리하는 메인 레이아웃도 정의할 수 있습니다. 메인 레이아웃도 공유 폴더의 구성 요소입니다.
MainLayout은 응용 프로그램의 모든 페이지의 구조를 정의합니다. 사용 중인 메인 템플릿처럼 여러 개의 메인 템플릿을 만들 수 있습니다.
우리가 개발 모험을 시작하기 전에 마지막 생각은 라조 페이지에서 보듯이 @code 부분이 있는데 라조 페이지를 관리할 c# 코드가 포함되어 있다. 이것은 소형 응용 프로그램에는 가능하지만 대형 응용 프로그램과 신축성에는 c# 코드를 일부 클래스에 놓고 코드를 숨기는 방법으로 응용 프로그램을 관리하기 쉽다는 것이다.
Blazor 응용 프로그램의 대부분 기초 지식을 소개한 후에 응용 프로그램에서 정리를 하겠습니다.
페이지 폴더에서 항목에서 카운터와 FetchData를 삭제합니다
모델 폴더에서 ItemData라고 불리는 새로운 클래스를 만들어야 합니다
public class ItemData
{
public int Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public bool Done { get; set; }
}
우리가 만들 첫 번째 구성 요소는 프로젝트 개요입니다. 페이지 폴더 아래에 만들 것입니다.우리가 왜 페이지 아래에서 그것을 만들어야 하는지, 왜냐하면 그것은 내가 내비게이션할 수 있는 구성 요소이기 때문이다.페이지 폴더 아래에서 우리는 두 개의 파일을 만들어야 한다프로젝트 개요를 전환해야 합니다.다음 코드를 사용하여 cs를 부분 클래스로 변환합니다.
public partial class ItemOverview
{
}
우리가 그것을 섹션 클래스로 설정한 것은 razor 파일이 컴파일된 후에 하나의 클래스로 변환되기 때문에 문제를 만들 것입니다. 섹션으로 설정하면 이 두 클래스를 통합합니다.ItemOverview 구성 요소로 이동하려면 다음 항목을 ItemOverview에 추가해야 합니다.면도칼.페이지 명령은 내비게이션에 사용할 URL을 지정할 수 있도록 합니다
@page "/itemoverview"
현재, 일부 클래스에 정적 데이터를 추가해야 하며, 나중에 API를 호출해서 완성할 것입니다public partial class ItemOverview
{
public IEnumerable<ItemData> Items { get; set; }
private void InitializeItems()
{
var e1 = new ItemData
{
Description = "Get bread, fruit, veg and cheese",
Done = false,
Id = 1,
Title = "Food shopping"
};
var e2 = new ItemData
{
Description = "Study well for AZ204",
Done = false,
Id = 2,
Title = "Study"
};
Items = new List<ItemData> { e1, e2 };
}
}
현재 다음 단계는 시각화된 구성 요소 중의 항목입니다. 이를 위해 구성 요소의 생명 주기를 알아야 합니다.구성 요소를 초기화하는 과정에서 많은 방법이 호출될 것입니다. 가장 중요한 방법 중 하나는 'On Initialzed Async' 입니다. Item Overview 섹션 클래스에서 다시 쓸 것입니다.protected override Task OnInitializedAsync()
{
InitializeItems();
return base.OnInitializedAsync();
}
razor에서 구조 함수는 이렇게 하는 가장 좋은 장소가 아니다.이제 Blazor 뷰를 구축하겠습니다.프로젝트 개요에서razor에서 다음 코드를 추가합니다.
@page "/itemoverview"
<h1 class="page-title">All items</h1>
<!-- the check here rely on the 2 way binding which will automatically detecht
when the data has been returned by our class, in our case its static data
but when we want to connect to our api to fetch tdata it will be useful -->
@if(Items == null)
{
<p>Loading ...</p>
}
else
{
<table class="table">
<thead>
<tr>
<td>Id</td>
<td>Title</td>
</tr>
</thead>
<tbody>
@foreach (var item in Items)
{
<tr>
<td>@item.Id</td>
<td>@item.Title</td>
</tr>
}
</tbody>
</table>
}
이제 우리는 첫 번째 구성 요소를 만들었으니 두 번째 구성 요소로 이동할 때가 되었다.두 번째 구성 요소는 ItemDetail이라고 합니다. 페이지 폴더의 항목 정보를 볼 수 있도록 합니다. ItemDetail이라는 새 razor 구성 요소를 만듭니다.razor 및 부분 클래스 ItemDetail대테러 엘리트public partial class ItemDetail
{
// in order for us to capture the specific id that we need to show its item
// we are sending an Id and in order for blazor to recognise this we need to have
// a variable with the same name of the queryString and with the Parameter attribute
[Parameter]
public string Id { get; set; }
// The item detail is bound to an item that we want to show
public ItemData Item {get;set;} = new ItemData();
public IEnumerable<ItemData> Items { get; set; }
private void InitializeItems()
{
var e1 = new ItemData
{
Description = "Get bread, fruit, veg and cheese",
Done = false,
Id = 1,
Title = "Food shopping"
};
var e2 = new ItemData
{
Description = "Study well for AZ204",
Done = false,
Id = 2,
Title = "Study"
};
Items = new List<ItemData> { e1, e2 };
}
// This is the function that w will use to call functions that will be initializing data
protected override Task OnInitializedAsync()
{
InitializeItems();
Item = Items.FirstOrDefault(x => x.Id == Convert.ToInt32(Id) );
return base.OnInitializedAsync();
}
}
@page "/itemdetail/{Id}"
<h1>Item detail @Item.Title</h1>
<div class="row">
<div class="col-md-12">
<div class="form-group row">
<label class="col-sm-4 col-form-label">Id</label>
<div class="col-sm-8">
<label type="text" readonly class="form-control-plaintext">@Item.Id</label>
</div>
</div>
<div class="form-group row">
<label class="col-sm-4 col-form-label">Title</label>
<div class="col-sm-8">
<label type="text" readonly class="form-control-plaintext">@Item.Title</label>
</div>
</div>
<div class="form-group row">
<label class="col-sm-4 col-form-label">Description</label>
<div class="col-sm-8">
<label type="text" readonly class="form-control-plaintext">@Item.Description</label>
</div>
</div>
<div class="form-group row">
<label class="col-sm-4 col-form-label">Is Done</label>
<div class="col-sm-8">
<label type="text" readonly class="form-control-plaintext">@Item.Done</label>
</div>
</div>
</div>
</div>
itemOverview를 열 수 있도록 색인을 업데이트해야 합니다.면도 및 업데이트 코드@page "/itemoverview"
<h1 class="page-title">All items</h1>
<!-- the check here rely on the 2 way binding which will automatically detecht
when the data has been returned by our class, in our case its static data
but when we want to connect to our api to fetch tdata it will be useful -->
@if(Items == null)
{
<p>Loading ...</p>
}
else
{
<table class="table">
<thead>
<tr>
<td>Id</td>
<td>Title</td>
<td></td>
</tr>
</thead>
<tbody>
@foreach (var item in Items)
{
<tr>
<td>@item.Id</td>
<td>@item.Title</td>
<td>
<a href="@($"itemdetail/{item.Id}")" class="btn btn-primary">
detail
</a>
</td>
</tr>
}
</tbody>
</table>
}
다음 단계는 메뉴 업데이트입니다. 이 점을 하려면 공유로 이동해야 합니다.→ 탐색 메뉴.면도기와 편집은 다음과 같다<div class="top-row pl-4 navbar navbar-dark">
<a class="navbar-brand" href="">TodoManagement</a>
<button class="navbar-toggler" @onclick="ToggleNavMenu">
<span class="navbar-toggler-icon"></span>
</button>
</div>
<div class="@NavMenuCssClass" @onclick="ToggleNavMenu">
<ul class="nav flex-column">
<li class="nav-item px-3">
<NavLink class="nav-link" href="" Match="NavLinkMatch.All">
<span class="oi oi-home" aria-hidden="true"></span> Home
</NavLink>
</li>
<li class="nav-item px-3">
<NavLink class="nav-link" href="ItemOverview">
<span class="oi oi-plus" aria-hidden="true"></span> Items
</NavLink>
</li>
</ul>
</div>
@code {
private bool collapseNavMenu = true;
private string NavMenuCssClass => collapseNavMenu ? "collapse" : null;
private void ToggleNavMenu()
{
collapseNavMenu = !collapseNavMenu;
}
}
NavLink만 참조해도 Microsoft에서 제공하는 라우팅 구성 요소현재, 우리는 이미 응용 프로그램을 준비했지만, 정적 데이터가 있으면, 다음 단계는 그것을 동적으로 만들고, blazor 응용 프로그램을 API에 연결할 것이다
클래스에 하드코딩된 정적 데이터를 바꾸기 위해 동적 데이터를 추가할 것입니다.
git hub에서 최신 버전의 API 응용 프로그램을 가져올 수 있습니다. 설명의 링크를 참조하십시오.
blazor 응용 프로그램에서 연결할 수 있도록 API의 포트를 먼저 수정합니다.
우리는 프로그램을 열고 프로그램으로 내비게이션을 했다.cs 및 다음 줄 추가
webBuilder.UseUrls("http://*:8090");
그리고 테스트 목적으로 이 코드를 주석해서 Todo Controller의 인증 요구를 삭제할 것입니다//[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
그 다음에 프로그램에 인증을 추가하는 또 다른 글이 있습니다.API에 대한 변경 사항은 CORS를 활성화하여 다른 응용 프로그램에서 연결할 수 있도록 하는 것입니다.startup 클래스에서는 Configure Services Method에 다음 코드를 추가해야 합니다.services.AddCors(options =>
{
options.AddPolicy("Open", builder => builder.AllowAnyOrigin().AllowAnyHeader());
});
설정 방법에서, 우리는 응용 프로그램에 다음 내용을 추가해야 한다.끝점 사용app.UseCors("Open");
IHttpClientFactory를 사용하여 API에 연결할 것입니다. 마이크로소프트는 이미 우리에게 기존의 것을 제공했고, HttpClient는 의존 주입을 통해 우리에게 제공할 것입니다.HttpClientFactory를 사용하려면 nuget 패키지를 추가해야 합니다.
dotnet add package Microsoft.Extensions.Http
nuget을 추가하면 루트 디렉터리에 서비스라는 새 폴더를 만듭니다. 이 서비스 폴더는 HttpClient 서비스를 포함합니다.우리는 우선 인터페이스 Itodata 서비스를 만들어야 한다
public interface ITodoDataService
{
Task<IEnumerable<ItemData>> GetAllItems();
Task<ItemData> GetItemDetails(int id);
}
그리고 ToDodat Servicepublic class TodoDataService : ITodoDataService
{
public async Task<IEnumerable<ItemData>> GetAllItems()
{
throw new System.NotImplementedException();
}
public async Task<ItemData> GetItemDetails(int id)
{
throw new System.NotImplementedException();
}
}
이후에 우리는 프로그램을 업데이트해야 한다.cs는 httpclient를 저희 서비스에 주입하여 저희가 서비스에서 직접 사용할 수 있도록 합니다builder.Services.AddHttpClient<ITodoDataService, TodoDataService>(x => x.BaseAddress = new Uri("http://localhost:8090"));
이제 ToDodat Service를 구현하고 API를 활용할 수 있습니다.public class TodoDataService : ITodoDataService
{
// Using the httpclient to call our API,
// its being initialized via the constructor injection
private readonly HttpClient _httpClient;
public TodoDataService(HttpClient httpClient)
{
_httpClient = httpClient;
}
public async Task<IEnumerable<ItemData>> GetAllItems()
{
var apiResponse = await _httpClient.GetStreamAsync($"api/todo");
return await JsonSerializer.DeserializeAsync<IEnumerable<ItemData>>
(apiResponse, new JsonSerializerOptions() { PropertyNameCaseInsensitive = true });
}
public async Task<ItemData> GetItemDetails(int id)
{
var apiResponse = await _httpClient.GetStreamAsync($"api/todo/{id}");
return await JsonSerializer.DeserializeAsync<ItemData>
(apiResponse, new JsonSerializerOptions() { PropertyNameCaseInsensitive = true });
}
}
다음 단계는 ItemDetail과 ItemOverview를 업데이트하고 모든 정적 데이터를 삭제하고 API를 사용해야 합니다ItemOverview 섹션 클래스를 열고 다음
public partial class ItemOverview
{
public IEnumerable<ItemData> Items { get; set; }
// Dynamicly inject from our DI container
[Inject]
public ITodoDataService TodoDataService {get;set;}
// This is the function that w will use to call functions that will be initializing data
protected async override Task OnInitializedAsync()
{
// Call our data service which call the API
Items = (await TodoDataService.GetAllItems()).ToList();
}
}
이제 ItemDetail 섹션 클래스를 열고 업데이트합니다.public partial class ItemDetail
{
// in order for us to capture the specific id that we need to show its item
// we are sending an Id and in order for blazor to recognise this we need to have
// a variable with the same name of the queryString and with the Parameter attribute
[Parameter]
public string Id { get; set; }
// The item detail is bound to an item that we want to show
public ItemData Item {get;set;} = new ItemData();
// Dynamicly inject from our DI container
[Inject]
public ITodoDataService TodoDataService {get;set;}
// This is the function that w will use to call functions that will be initializing data
protected async override Task OnInitializedAsync()
{
Item = await TodoDataService.GetItemDetails(Convert.ToInt32(Id));
}
}
이제 Blazor 애플리케이션과 API를 모두 실행하고 애플리케이션을 테스트해 보겠습니다.보시다시피 애플리케이션이 API에 연결되어 있고 데이터가 동적으로 추출되고 있습니다.
다음 글은blazor 프로그램에서 항목을 추가하거나 편집하거나 삭제하는 방법을 소개합니다
Reference
이 문제에 관하여(Blazor WASM 및 REST API – 한 걸음 한 걸음), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/moe23/blazor-wasm-with-rest-api-step-by-step-2djo텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)