[번역본]
출처 : http://www.binaryintellect.net/articles/55355722-96b6-4bbc-a110-999e5e61235e.aspx
몇 년 전 ASP.NET Core 2.0 MVC, Razor Pages 및 Web API가 단일 웹 애플리케이션에서 공존할 수 있는 방법을 설명하는 기사를 작성했습니다 . 그 이후로 ASP.NET Core는 제품군에 몇 가지 새로운 구성원을 추가했습니다. 이제 단일 프로젝트에서 ASP.NET Core 6.0 MVC, Razor Pages, Blazor Server, API 컨트롤러 및 minimal API를 함께 사용하는 유사한 웹 애플리케이션을 다시 빌드해야 합니다.
일반적으로 개발자는 MVC 또는 Blazor와 같은 특정 프로젝트 템플릿을 기반으로 새 ASP.NET Core 프로젝트를 만듭니다. 그러나 단일 개발 옵션으로 제한되지 않습니다. ASP.NET Core는 여러 개발 옵션을 제공하며 요구 사항에 따라 단일 프로젝트에서 이를 활용할 수 있습니다.
이 연습에서는 빈 프로젝트로 시작하여 MVC, Razor Pages, Blazor Server, API 컨트롤러 및 minimal API를 하나씩 추가합니다. 이렇게 하면 어떤 구성이 필요한지, 이러한 상황에서 다양한 파일이 구성되는 방식을 이해하는 데 도움이 됩니다.
빈 프로젝트 템플릿을 기반으로 AspNetCoreAllInOne 이라는 ASP.NET Core 를 만들어 시작하겠습니다.
솔루션 탐색기에서 새로 생성된 프로젝트는 아래와 같습니다
먼저 프로젝트에 MVC를 추가합니다. 따라서 Program.cs 파일을 열고 다음 코드를 추가합니다
var builder = WebApplication.CreateBuilder(args);
//추가
builder.Services.AddControllersWithViews();
var app = builder.Build();
//추가 3개
app.UseStaticFiles();
app.UseRouting();
app.MapDefaultControllerRoute();
app.Run();
AddControllersWithViews()를 호출하여 DI 컨테이너에 MVC 서비스를 등록합니다.
UseStaticFiles() 호출은 지원하는 정적 파일(이미지, JS 파일 등)을 앱에 추가합니다.
UseRouting() 및 MapDefaultControllerRoute() 메서드는 앱에서 사용하는 MVC 라우팅을 처리합니다. 이 예에서는 경로에 대해 기본 /controller/action/id 패턴을 사용할 것이므로 다른 경로 패턴을 지정하지 않았습니다.
이제 Models, Views, Controllers 및 wwwroot라는 4개의 폴더를 프로젝트에 추가합니다.
그런 다음 New Item 추가 대화 상자를 사용하여 Models 폴더에 AppModel 이라는 새 클래스를 추가합니다.
AppModel.cs 파일에 다음 코드를 작성합니다.
namespace AspNetCoreAllInOne.Models
{
public class AppModel
{
public string Message { get; set; }
}
}
AppModel 클래스에는 Message라는 속성이 하나만 있습니다.
그런 다음 HomeController 라는 새 컨트롤러 클래스를 Controllers 폴더에 추가합니다.
HomeController 클래스에 다음 코드를 작성합니다
using Microsoft.AspNetCore.Mvc;
using AspNetCoreAllInOne.Models;
namespace AspNetCoreAllInOne.Controllers
{
public class HomeController : Controller
{
public IActionResult Index()
{
AppModel data = new AppModel()
{
Message = "Hello World!"
};
return View(data);
}
}
}
HomeController 클래스에는 Index() action 이 포함되어 있습니다. Index() action 은 AppModel 개체를 만들고 해당 Message 속성을 Hello World! 로 설정합니다. 그리고 해당 model object 를 Index view 에 전달합니다.
Create Views > Home folder 를 만들고 그 안에 Index.cshtml 이라는 새 Razor view 파일을 추가합니다.
Index.cshtml 파일에 다음 코드를 작성합니다.
@model AspNetCoreAllInOne.AppModel
<h1>@Model.Message</h1>
여기서 우리는 단순히 브라우저에서 Message 속성을 출력합니다.
wwwroot 폴더에 Default.html이라는 새 HTML 페이지를 추가합니다. 이 예제의 뒷부분에서 이 페이지를 사용합니다. 당분간은 그냥 비워두세요.
이 단계에서 프로젝트는 다음과 같습니다.
응용 프로그램을 실행하면 다음과 같은 출력이 표시됩니다.
이제 MVC가 프로젝트에 추가되었으므로 Razor Pages를 추가해 보겠습니다.
Program.cs 파일을 다시 열고 다음 코드를 추가합니다.
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllersWithViews();
//추가
builder.Services.AddRazorPages();
var app = builder.Build();
app.UseStaticFiles();
app.UseRouting();
app.MapDefaultControllerRoute();
//추가
app.MapRazorPages();
app.Run();
Razor Pages를 지원하기 위해 AddRazorPages() 및 MapRazorPages()라는 두 가지 호출을 더 추가했습니다.
그런 다음 프로젝트 루트 아래에 Pages 폴더를 추가합니다. 그리고 Index.cshtml 이라는 새 Razor 페이지를 추가합니다.
Index.cshtml.cs 의 page model class 를 열고 다음 코드를 추가합니다.
public class IndexModel : PageModel
{
public AppModel Data = new AppModel();
public void OnGet()
{
Data.Message = "Hello Galaxy!";
}
}
AppModel 의 개체를 만들고 OnGet() page handler 에서 Message 속성을 Hello Galaxy로 설정합니다! .
그런 다음 Index.cshtml 페이지를 열고 아래와 같이 Message 속성을 출력합니다.
@page
@model AspNetCoreAllInOne.Pages.IndexModel
<h1>@Model.Data.Message</h1>
애플리케이션을 실행하면 다음과 같은 출력이 표시됩니다.
Razor Pages 를 추가한 후 웹 응용 프로그램의 기본 페이지가 /Home/Index(MVC 기본값)에서 /Index(Razor Pages 기본값)로 변경되었습니다. 물론 원하는 URL로 수동으로 이동하고 필요에 따라 MVC 또는 Razor Pages 를 호출할 수 있습니다.
Blazor 서버를 추가하는 것은 MVC 및 Razor Page를 추가하는 것보다 약간 더 복잡합니다. 계속해서 그렇게 합시다.
Program.cs 파일을 열고 다음 코드를 추가합니다.
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllersWithViews();
builder.Services.AddRazorPages();
//추가
builder.Services.AddServerSideBlazor();
var app = builder.Build();
app.UseStaticFiles();
app.UseRouting();
app.MapDefaultControllerRoute();
app.MapRazorPages();
//아래 2개 추가
app.MapBlazorHub();
app.MapFallbackToPage("/_Host");
app.Run();
먼저 AddServerSideBlazor()를 호출하여 Blazor 서버 서비스를 등록합니다. 그런 다음 MapBlazorHub() 및 MapFallbackToPage() 메서드를 사용하여 Blazor 및 fallback page 를 설정합니다.
다음으로 프로젝트의 root 폴더에 Blazor의 root component 인 App.razor 를 추가합니다.
root 폴더에 새로 생성한 App.razor 의 코드는 다음과 같습니다.
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.Web
<Router AppAssembly="@typeof(App).Assembly">
<Found Context="routeData">
<RouteView RouteData="@routeData" />
</Found>
<NotFound>
<PageTitle>Not found</PageTitle>
<LayoutView>
<p>Sorry, there's
nothing at this address.</p>
<a href="/Default.html">Go to Default page</a>
</LayoutView>
</NotFound>
</Router>
여기서는 기본적으로 Blazor의 router 를 설정합니다. router 가 URL을 찾을 수 없으면 오류 메시지가 표시되고 사용자가 Default.html 페이지로 이동할 수 있습니다(이 예제의 앞부분에서 MVC를 구성하는 동안 Default.html 페이지를 추가했습니다).
App.razor component 는 _Host.cshtml 파일에서 로드됩니다. 따라서 Pages 폴더에 _Host.cshtml 이라는 새 Razor View 파일을 추가합니다.
_Host.cshtml 파일에 다음 코드를 추가합니다.
@page
@using Microsoft.AspNetCore.Components.Web
@using AspNetCoreAllInOne
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,
initial-scale=1.0" />
<base href="~/" />
<component type="typeof(HeadOutlet)"
render-mode="ServerPrerendered" />
</head>
<body>
<component type="typeof(App)" render-mode="ServerPrerendered" />
<script src="_framework/blazor.server.js"></script>
</body>
</html>
<component> 구문을 사용하여 App.razor component 를 렌더링합니다. 또한 </body> 태그 바로 앞에 blazor.server.js에 대한 <script> 참조를 추가합니다.
다음으로 두 개의 간단한 Razor component 를 추가합니다. 먼저 프로젝트 root 아래에 Shared 라는 새 폴더를 만듭니다. 그리고 WelcomeMessage.razor 라는 새로운 razor component 를 추가합니다.
WelcomeMessage component 내부에 다음 코드를 작성합니다.
@code{
[Parameter]
public string Message { get; set; }
}
<h1>@Message</h1>
보시다시피 parent component 에서 message 를 지정하는 데 사용할 Message 매개 변수 속성이 있습니다. 지정된 메시지는 단순히 페이지에 출력됩니다.
WelcomeMessage.razor component 는 Index.razor component 에서 사용됩니다. 따라서 Pages 폴더에 Index.razor component 를 추가합니다. 이 예의 앞부분에서 Index Razor Page를 만드는 동안 이미 Pages 폴더를 추가했습니다.
Index.razor 파일에 다음 코드를 작성합니다.
@page "/"
@page "/IndexBlazor"
@using AspNetCoreAllInOne.Shared
<WelcomeMessage Message="Hello Universe!" />
We used the WelcomeMessage component and specify the Message to be Hello Universe!. Notice that we have also used @page directive to specify a route /IndexBlazor. This way the Index component can be accessed at /IndexBlazor. We already have Index.cshtml file in the Pages folder. Therefore, we can't assign /Index route to the newly added razor component.
These two components are shown in the Solution Explorer below:
WelcomeMessage component 를 사용하고 메시지를 Hello Universe!로 지정했습니다. @page 지시문을 사용하여 /IndexBlazor 경로를 지정했습니다. 이 방법으로 Index component 는 /IndexBlazor 에서 액세스할 수 있습니다.
Pages 폴더에 이미 Index.cshtml 파일이 존재하므로 새로 추가된 razor component 에 /Index 경로를 사용할 수 없습니다.
이 두 component 는 아래 솔루션 탐색기에 표시됩니다.
애플리케이션을 실행하고 /IndexBlazor 로 이동합니다.
이 단계에서 Razor Pages 기본 페이지가 브라우저에 표시됩니다. Blazor 앱을 기본 default 로 사용하려면 어떻게 해야 할까요? 그걸하자.
Index.cshtml 의 이름을 IndexRazorPages.cshtml로 바꿉니다. 그리고 아래와 같이 _Host.cshtml을 수정합니다.
@page "/"
@using Microsoft.AspNetCore.Components.Web
@using AspNetCoreAllInOne
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,
initial-scale=1.0" />
<base href="~/" />
<component type="typeof(HeadOutlet)"
render-mode="ServerPrerendered" />
</head>
<body>
<component type="typeof(App)" render-mode="ServerPrerendered" />
<script src="_framework/blazor.server.js"></script>
</body>
</html>
@page 지시문은 이제 경로를 /로 지정합니다. (@page "/")
이 변경을 수행한 후 앱을 실행하면 Index.razor component 의 출력이 직접 표시됩니다.
물론 /IndexBlazor를 사용하여 component 에 액세스할 수도 있습니다
이제 프로젝트에 API 컨트롤러를 추가해 보겠습니다. Program.cs를 다시 열고 다음 코드 줄을 추가합니다.
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllersWithViews();
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();
//추가
builder.Services.AddControllers();
var app = builder.Build();
app.UseStaticFiles();
app.UseRouting();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.MapBlazorHub();
app.MapFallbackToPage("/_Host");
//추가
app.MapControllers();
app.Run();
AddControllers() 및 MapControllers() 를 호출하며, 이는 Web API 관련 기능을 처리합니다.
이제 Controllers 폴더에 ValuesController 라는 API 컨트롤러를 추가합니다.
ValuesController.cs 에 다음 코드를 작성합니다
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
[HttpGet]
public IActionResult Get()
{
string[] data = new string[] {
"Hello World!",
"Hello Galaxy!",
"Hello Universe!"
};
return Ok(data);
}
}
예를 들어 ValuesController 에 하나의 action 만 추가했습니다. Get() 작업은 [HttpGet] 속성으로 표시되며 Hello World!, Hello Galaxy!, Hello Universe! 라는 세 가지 문자열 값의 배열을 반환합니다.
애플리케이션을 실행하고 /api/Values로 이동하여 Get() 작업을 호출합니다. 출력은 다음과 같습니다
예상대로 브라우저는 세 개의 문자열 요소가 있는 배열을 보여줍니다.
minimal 의 API를 추가하는 것은 매우 간단합니다. Program.cs 파일을 열고 app.Run() 바로 앞에 다음 MapGet() 호출을 추가합니다.
app.MapGet("/minimalapi/values", () =>
{
string[] data = new string[] {
"Hello World!",
"Hello Galaxy!",
"Hello Universe!"
};
return Results.Ok(data);
});
보시다시피 MapGet() 호출은 끝점 URL을 /minimalapi/values로 지정하고 핸들러 함수는 단순히 문자열 값의 배열을 반환합니다.
앱을 다시 실행하고 /minimalapi/values로 이동합니다. 출력은 다음과 같습니다.
보시다시피 출력은 API 컨트롤러와 동일하지만 다른 endpoint (/minimalapi/values)을 사용하여 minimal API를 호출했습니다.
wwwroot 폴더에 Default.html 페이지를 추가했습니다. 지금까지 만든 모든 endpoint 에 대한 URL을 포함하는 데 사용하겠습니다. Default.html 을 열고 다음 코드를 추가합니다.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<h1>This is default page!</h1>
<h3><a href="/Home/Index">
Go to ASP.NET Core MVC</a></h3>
<h3><a href="/IndexRazorPages">
Go to ASP.NET Core Razor Pages</a></h3>
<h3><a href="/IndexBlazor">
Go to ASP.NET Core Blazor</a></h3>
<h3><a href="/Api/Values">
Go to ASP.NET Core API Controller</a></h3>
<h3><a href="/MinimalApi/Values">
Go to ASP.NET Core Minimal API</a></h3>
</body>
</html>
이것은 하이퍼링크가 포함된 간단한 페이지이며 브라우저에서 다음과 같이 보입니다.
이제 Index.razor component 를 열고 다음과 같이 이를 제거 합니다.
@page "/"
삭제 후 Index.razor 는 더 이상 default component 가 아니며 앱을 실행한 후, 이 오류가 발생합니다.
Go to Default page 를 클릭하면 Default.html 페이지로 이동합니다.
각 link 를 클릭하고 올바른 출력을 얻는지 확인해 보세요.
http://www.binaryintellect.net/articles/55355722-96b6-4bbc-a110-999e5e61235e.aspx
.Net Core 6.0 Web API 의 JWT Token 인증 및 권한 부여 (4) | 2022.04.21 |
---|---|
React 및 Asp Net Core 3 애플리케이션을 IIS 로 운영하기 (2) | 2022.04.21 |
ASP.NET 6.0 Web API 로 Redis Cache 사용해 보기(Parallel.ForEach 활용) (4) | 2022.03.30 |
ASP.NET Core 5.0 에서 IDataProtector 활용하여 데이터 보호하는 방법 (0) | 2022.03.11 |
.NET 6.0 - Web Api 를 통해 Refresh Tokens 와 함께 JWT 인증 Tutorial (0) | 2022.02.28 |