[] init Project

This commit is contained in:
김선규 2024-09-30 15:27:17 +09:00
commit e554ba22b3
75 changed files with 2358 additions and 0 deletions

13
.idea/.idea.BlazorApp/.idea/.gitignore vendored Normal file
View File

@ -0,0 +1,13 @@
# 디폴트 무시된 파일
/shelf/
/workspace.xml
# Rider에서 무시된 파일
/projectSettingsUpdater.xml
/.idea.BlazorApp.iml
/modules.xml
/contentModel.xml
# 에디터 기반 HTTP 클라이언트 요청
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GitToolBoxBlameSettings">
<option name="version" value="2" />
</component>
</project>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="UserContentModel">
<attachedFolders />
<explicitIncludes />
<explicitExcludes />
</component>
</project>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

16
BlazorApp.sln Normal file
View File

@ -0,0 +1,16 @@

Microsoft Visual Studio Solution File, Format Version 12.00
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BlazorApp", "BlazorApp\BlazorApp.csproj", "{51FF16FD-EE1B-4849-8A8D-546F5965219A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{51FF16FD-EE1B-4849-8A8D-546F5965219A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{51FF16FD-EE1B-4849-8A8D-546F5965219A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{51FF16FD-EE1B-4849-8A8D-546F5965219A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{51FF16FD-EE1B-4849-8A8D-546F5965219A}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<Folder Include="ㅎNETCORE 학습\.NET\" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,20 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<base href="/"/>
<link rel="stylesheet" href="bootstrap/bootstrap.min.css"/>
<link rel="stylesheet" href="app.css"/>
<link rel="stylesheet" href="BlazorApp.styles.css"/>
<link rel="icon" type="image/png" href="favicon.png"/>
<HeadOutlet/>
</head>
<body>
<Routes/>
<script src="_framework/blazor.web.js"></script>
</body>
</html>

View File

@ -0,0 +1,23 @@
@inherits LayoutComponentBase
<div class="page">
<div class="sidebar">
<NavMenu/>
</div>
<main>
<div class="top-row px-4">
<a href="https://learn.microsoft.com/aspnet/core/" target="_blank">About</a>
</div>
<article class="content px-4">
@Body
</article>
</main>
</div>
<div id="blazor-error-ui">
An unhandled error has occurred.
<a href="" class="reload">Reload</a>
<a class="dismiss">🗙</a>
</div>

View File

@ -0,0 +1,96 @@
.page {
position: relative;
display: flex;
flex-direction: column;
}
main {
flex: 1;
}
.sidebar {
background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%);
}
.top-row {
background-color: #f7f7f7;
border-bottom: 1px solid #d6d5d5;
justify-content: flex-end;
height: 3.5rem;
display: flex;
align-items: center;
}
.top-row ::deep a, .top-row ::deep .btn-link {
white-space: nowrap;
margin-left: 1.5rem;
text-decoration: none;
}
.top-row ::deep a:hover, .top-row ::deep .btn-link:hover {
text-decoration: underline;
}
.top-row ::deep a:first-child {
overflow: hidden;
text-overflow: ellipsis;
}
@media (max-width: 640.98px) {
.top-row {
justify-content: space-between;
}
.top-row ::deep a, .top-row ::deep .btn-link {
margin-left: 0;
}
}
@media (min-width: 641px) {
.page {
flex-direction: row;
}
.sidebar {
width: 250px;
height: 100vh;
position: sticky;
top: 0;
}
.top-row {
position: sticky;
top: 0;
z-index: 1;
}
.top-row.auth ::deep a:first-child {
flex: 1;
text-align: right;
width: 0;
}
.top-row, article {
padding-left: 2rem !important;
padding-right: 1.5rem !important;
}
}
#blazor-error-ui {
background: lightyellow;
bottom: 0;
box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
display: none;
left: 0;
padding: 0.6rem 1.25rem 0.7rem 1.25rem;
position: fixed;
width: 100%;
z-index: 1000;
}
#blazor-error-ui .dismiss {
cursor: pointer;
position: absolute;
right: 0.75rem;
top: 0.5rem;
}

View File

@ -0,0 +1,35 @@
<div class="top-row ps-3 navbar navbar-dark">
<div class="container-fluid">
<a class="navbar-brand" href="">BlazorApp</a>
</div>
</div>
<input type="checkbox" title="Navigation menu" class="navbar-toggler"/>
<div class="nav-scrollable" onclick="document.querySelector('.navbar-toggler').click()">
<nav class="flex-column">
<div class="nav-item px-3">
<NavLink class="nav-link" href="" Match="NavLinkMatch.All">
<span class="bi bi-house-door-fill-nav-menu" aria-hidden="true"></span> Home
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="counter">
<span class="bi bi-plus-square-fill-nav-menu" aria-hidden="true"></span> Counter
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="weather">
<span class="bi bi-list-nested-nav-menu" aria-hidden="true"></span> Weather
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="todo">
<span class="oi oi-list-rich" aria-hidden="true"></span> Todo
</NavLink>
</div>
</nav>
</div>

View File

@ -0,0 +1,110 @@
.navbar-toggler {
appearance: none;
cursor: pointer;
width: 3.5rem;
height: 2.5rem;
color: white;
position: absolute;
top: 0.5rem;
right: 1rem;
border: 1px solid rgba(255, 255, 255, 0.1);
background: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e") no-repeat center/1.75rem rgba(255, 255, 255, 0.1);
}
.navbar-toggler:checked {
background-color: rgba(255, 255, 255, 0.5);
}
.top-row {
height: 3.5rem;
background-color: rgba(0,0,0,0.4);
}
.navbar-brand {
font-size: 1.1rem;
}
.bi {
display: inline-block;
position: relative;
width: 1.25rem;
height: 1.25rem;
margin-right: 0.75rem;
top: -1px;
background-size: cover;
}
.bi-calendar-event-nav-menu {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' class='bi bi-calendar-event' viewBox='0 0 16 16'%3E%3Cpath d='M11 6.5a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5z'/%3e%3c/svg%3e");
}
.bi-house-door-fill-nav-menu {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-house-door-fill' viewBox='0 0 16 16'%3E%3Cpath d='M6.5 14.5v-3.505c0-.245.25-.495.5-.495h2c.25 0 .5.25.5.5v3.5a.5.5 0 0 0 .5.5h4a.5.5 0 0 0 .5-.5v-7a.5.5 0 0 0-.146-.354L13 5.793V2.5a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5v1.293L8.354 1.146a.5.5 0 0 0-.708 0l-6 6A.5.5 0 0 0 1.5 7.5v7a.5.5 0 0 0 .5.5h4a.5.5 0 0 0 .5-.5Z'/%3E%3C/svg%3E");
}
.bi-plus-square-fill-nav-menu {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-plus-square-fill' viewBox='0 0 16 16'%3E%3Cpath d='M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2zm6.5 4.5v3h3a.5.5 0 0 1 0 1h-3v3a.5.5 0 0 1-1 0v-3h-3a.5.5 0 0 1 0-1h3v-3a.5.5 0 0 1 1 0z'/%3E%3C/svg%3E");
}
.bi-list-nested-nav-menu {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-list-nested' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M4.5 11.5A.5.5 0 0 1 5 11h10a.5.5 0 0 1 0 1H5a.5.5 0 0 1-.5-.5zm-2-4A.5.5 0 0 1 3 7h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5zm-2-4A.5.5 0 0 1 1 3h10a.5.5 0 0 1 0 1H1a.5.5 0 0 1-.5-.5z'/%3E%3C/svg%3E");
}
.nav-item {
font-size: 0.9rem;
padding-bottom: 0.5rem;
}
.nav-item:first-of-type {
padding-top: 1rem;
}
.nav-item:last-of-type {
padding-bottom: 1rem;
}
.nav-item ::deep .nav-link {
color: #d7d7d7;
background: none;
border: none;
border-radius: 4px;
height: 3rem;
display: flex;
align-items: center;
line-height: 3rem;
width: 100%;
}
.nav-item ::deep a.active {
background-color: rgba(255,255,255,0.37);
color: white;
}
.nav-item ::deep .nav-link:hover {
background-color: rgba(255,255,255,0.1);
color: white;
}
.nav-scrollable {
display: none;
}
.navbar-toggler:checked ~ .nav-scrollable {
display: block;
}
@media (min-width: 641px) {
.navbar-toggler {
display: none;
}
.nav-scrollable {
/* Never collapse the sidebar for wide screens */
display: block;
/* Allow sidebar to scroll for tall menus */
height: calc(100vh - 3.5rem);
overflow-y: auto;
}
}

View File

@ -0,0 +1,20 @@
@page "/counter"
@rendermode InteractiveServer
<PageTitle>Counter</PageTitle>
<h1>Counter</h1>
<p role="status">Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
private int currentCount = 0;
private void IncrementCount()
{
currentCount++;
}
}

View File

@ -0,0 +1,36 @@
@page "/Error"
@using System.Diagnostics
<PageTitle>Error</PageTitle>
<h1 class="text-danger">Error.</h1>
<h2 class="text-danger">An error occurred while processing your request.</h2>
@if (ShowRequestId)
{
<p>
<strong>Request ID:</strong> <code>@RequestId</code>
</p>
}
<h3>Development Mode</h3>
<p>
Swapping to <strong>Development</strong> environment will display more detailed information about the error that occurred.
</p>
<p>
<strong>The Development environment shouldn't be enabled for deployed applications.</strong>
It can result in displaying sensitive information from exceptions to end users.
For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>
and restarting the app.
</p>
@code{
[CascadingParameter] private HttpContext? HttpContext { get; set; }
private string? RequestId { get; set; }
private bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
protected override void OnInitialized() =>
RequestId = Activity.Current?.Id ?? HttpContext?.TraceIdentifier;
}

View File

@ -0,0 +1,7 @@
@page "/"
<PageTitle>Home</PageTitle>
<h1>Hello, world!</h1>
Welcome to your new app.

View File

@ -0,0 +1,34 @@
@page "/Todo"
@rendermode InteractiveServer
<PageTitle>Todo</PageTitle>
<h1>Todo (@todos.Count(todo => !todo.IsDone))</h1>
<ul>
@foreach (var todo in todos)
{
<li>
<input type="checkbox" @bind="todo.IsDone"/>
@todo.Title
</li>
}
</ul>
<input placeholder="Something TODO" @bind="newTodo"/>
<button @onclick = "AddTodo">Add Todo</button>
@code {
private List<TodoItem> todos = new();
private string? newTodo;
private void AddTodo()
{
if (!string.IsNullOrWhiteSpace(newTodo))
{
todos.Add(new TodoItem { Title = newTodo });
newTodo = string.Empty;
}
}
}

View File

@ -0,0 +1,67 @@
@page "/weather"
@attribute [StreamRendering]
<PageTitle>Weather</PageTitle>
<h1>Weather</h1>
<p>This component demonstrates showing data.</p>
@if (forecasts == null)
{
<p>
<em>Loading...</em>
</p>
}
else
{
<table class="table">
<thead>
<tr>
<th>Date</th>
<th>Temp. (C)</th>
<th>Temp. (F)</th>
<th>Summary</th>
</tr>
</thead>
<tbody>
@foreach (var forecast in forecasts)
{
<tr>
<td>@forecast.Date.ToShortDateString()</td>
<td>@forecast.TemperatureC</td>
<td>@forecast.TemperatureF</td>
<td>@forecast.Summary</td>
</tr>
}
</tbody>
</table>
}
@code {
private WeatherForecast[]? forecasts;
protected override async Task OnInitializedAsync()
{
// Simulate asynchronous loading to demonstrate streaming rendering
await Task.Delay(500);
var startDate = DateOnly.FromDateTime(DateTime.Now);
var summaries = new[] { "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" };
forecasts = Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = startDate.AddDays(index),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = summaries[Random.Shared.Next(summaries.Length)]
}).ToArray();
}
private class WeatherForecast
{
public DateOnly Date { get; set; }
public int TemperatureC { get; set; }
public string? Summary { get; set; }
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
}
}

View File

@ -0,0 +1,6 @@
<Router AppAssembly="typeof(Program).Assembly">
<Found Context="routeData">
<RouteView RouteData="routeData" DefaultLayout="typeof(Layout.MainLayout)"/>
<FocusOnNavigate RouteData="routeData" Selector="h1"/>
</Found>
</Router>

View File

@ -0,0 +1,10 @@
@using System.Net.Http
@using System.Net.Http.Json
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.Web
@using static Microsoft.AspNetCore.Components.Web.RenderMode
@using Microsoft.AspNetCore.Components.Web.Virtualization
@using Microsoft.JSInterop
@using BlazorApp
@using BlazorApp.Components

28
BlazorApp/Program.cs Normal file
View File

@ -0,0 +1,28 @@
using BlazorApp.Components;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error", createScopeForErrors: true);
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAntiforgery();
app.MapRazorComponents<App>()
.AddInteractiveServerRenderMode();
app.Run();

View File

@ -0,0 +1,38 @@
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:47160",
"sslPort": 44383
}
},
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "http://localhost:5273",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "https://localhost:7260;http://localhost:5273",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

0
BlazorApp/README.md Normal file
View File

7
BlazorApp/TodoItem.cs Normal file
View File

@ -0,0 +1,7 @@
namespace BlazorApp;
public class TodoItem
{
public string? Title { get; set; }
public bool IsDone { get; set; }
}

View File

@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}

View File

@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}

Binary file not shown.

View File

@ -0,0 +1,23 @@
{
"runtimeTarget": {
"name": ".NETCoreApp,Version=v8.0",
"signature": ""
},
"compilationOptions": {},
"targets": {
".NETCoreApp,Version=v8.0": {
"BlazorApp/1.0.0": {
"runtime": {
"BlazorApp.dll": {}
}
}
}
},
"libraries": {
"BlazorApp/1.0.0": {
"type": "project",
"serviceable": false,
"sha512": ""
}
}
}

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,19 @@
{
"runtimeOptions": {
"tfm": "net8.0",
"frameworks": [
{
"name": "Microsoft.NETCore.App",
"version": "8.0.0"
},
{
"name": "Microsoft.AspNetCore.App",
"version": "8.0.0"
}
],
"configProperties": {
"System.GC.Server": true,
"System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": false
}
}
}

View File

@ -0,0 +1 @@
{"ContentRoots":["/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/wwwroot/","/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/obj/Debug/net8.0/scopedcss/bundle/"],"Root":{"Children":{"app.css":{"Children":null,"Asset":{"ContentRootIndex":0,"SubPath":"app.css"},"Patterns":null},"bootstrap":{"Children":{"bootstrap.min.css":{"Children":null,"Asset":{"ContentRootIndex":0,"SubPath":"bootstrap/bootstrap.min.css"},"Patterns":null},"bootstrap.min.css.map":{"Children":null,"Asset":{"ContentRootIndex":0,"SubPath":"bootstrap/bootstrap.min.css.map"},"Patterns":null}},"Asset":null,"Patterns":null},"favicon.png":{"Children":null,"Asset":{"ContentRootIndex":0,"SubPath":"favicon.png"},"Patterns":null},"index.html":{"Children":null,"Asset":{"ContentRootIndex":0,"SubPath":"index.html"},"Patterns":null},"BlazorApp.styles.css":{"Children":null,"Asset":{"ContentRootIndex":1,"SubPath":"BlazorApp.styles.css"},"Patterns":null}},"Asset":null,"Patterns":[{"ContentRootIndex":0,"Pattern":"**","Depth":0}]}}

View File

@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}

View File

@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}

View File

@ -0,0 +1,69 @@
{
"format": 1,
"restore": {
"/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/BlazorApp.csproj": {}
},
"projects": {
"/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/BlazorApp.csproj": {
"version": "1.0.0",
"restore": {
"projectUniqueName": "/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/BlazorApp.csproj",
"projectName": "BlazorApp",
"projectPath": "/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/BlazorApp.csproj",
"packagesPath": "/Users/seankim/.nuget/packages/",
"outputPath": "/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/obj/",
"projectStyle": "PackageReference",
"configFilePaths": [
"/Users/seankim/.nuget/NuGet/NuGet.Config"
],
"originalTargetFrameworks": [
"net8.0"
],
"sources": {
"https://api.nuget.org/v3/index.json": {}
},
"frameworks": {
"net8.0": {
"targetAlias": "net8.0",
"projectReferences": {}
}
},
"warningProperties": {
"warnAsError": [
"NU1605"
]
},
"restoreAuditProperties": {
"enableAudit": "true",
"auditLevel": "low",
"auditMode": "direct"
}
},
"frameworks": {
"net8.0": {
"targetAlias": "net8.0",
"imports": [
"net461",
"net462",
"net47",
"net471",
"net472",
"net48",
"net481"
],
"assetTargetFallback": true,
"warn": true,
"frameworkReferences": {
"Microsoft.AspNetCore.App": {
"privateAssets": "none"
},
"Microsoft.NETCore.App": {
"privateAssets": "all"
}
},
"runtimeIdentifierGraphPath": "/usr/local/share/dotnet/sdk/8.0.401/PortableRuntimeIdentifierGraph.json"
}
}
}
}
}

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<RestoreSuccess Condition=" '$(RestoreSuccess)' == '' ">True</RestoreSuccess>
<RestoreTool Condition=" '$(RestoreTool)' == '' ">NuGet</RestoreTool>
<ProjectAssetsFile Condition=" '$(ProjectAssetsFile)' == '' ">$(MSBuildThisFileDirectory)project.assets.json</ProjectAssetsFile>
<NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">/Users/seankim/.nuget/packages/</NuGetPackageRoot>
<NuGetPackageFolders Condition=" '$(NuGetPackageFolders)' == '' ">/Users/seankim/.nuget/packages/</NuGetPackageFolders>
<NuGetProjectStyle Condition=" '$(NuGetProjectStyle)' == '' ">PackageReference</NuGetProjectStyle>
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">6.10.1</NuGetToolVersion>
</PropertyGroup>
<ItemGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<SourceRoot Include="/Users/seankim/.nuget/packages/" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" />

View File

@ -0,0 +1,4 @@
// <autogenerated />
using System;
using System.Reflection;
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v8.0", FrameworkDisplayName = ".NET 8.0")]

View File

@ -0,0 +1,22 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("BlazorApp")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0")]
[assembly: System.Reflection.AssemblyProductAttribute("BlazorApp")]
[assembly: System.Reflection.AssemblyTitleAttribute("BlazorApp")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
// MSBuild WriteCodeFragment 클래스에서 생성되었습니다.

View File

@ -0,0 +1 @@
dde306ccf7bf4bb8d082a60aec7ba74921708f37594eac062aeef1d7dbc4376b

View File

@ -0,0 +1,59 @@
is_global = true
build_property.TargetFramework = net8.0
build_property.TargetPlatformMinVersion =
build_property.UsingMicrosoftNETSdkWeb = true
build_property.ProjectTypeGuids =
build_property.InvariantGlobalization =
build_property.PlatformNeutralAssembly =
build_property.EnforceExtendedAnalyzerRules =
build_property._SupportedPlatformList = Linux,macOS,Windows
build_property.RootNamespace = BlazorApp
build_property.RootNamespace = BlazorApp
build_property.ProjectDir = /Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/
build_property.EnableComHosting =
build_property.EnableGeneratedComInterfaceComImportInterop =
build_property.RazorLangVersion = 8.0
build_property.SupportLocalizedComponentNames =
build_property.GenerateRazorMetadataSourceChecksumAttributes =
build_property.MSBuildProjectDirectory = /Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp
build_property._RazorSourceGeneratorDebug =
[/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/Components/App.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50cy9BcHAucmF6b3I=
build_metadata.AdditionalFiles.CssScope =
[/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/Components/Pages/Counter.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50cy9QYWdlcy9Db3VudGVyLnJhem9y
build_metadata.AdditionalFiles.CssScope =
[/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/Components/Pages/Error.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50cy9QYWdlcy9FcnJvci5yYXpvcg==
build_metadata.AdditionalFiles.CssScope =
[/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/Components/Pages/Home.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50cy9QYWdlcy9Ib21lLnJhem9y
build_metadata.AdditionalFiles.CssScope =
[/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/Components/Pages/Todo.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50cy9QYWdlcy9Ub2RvLnJhem9y
build_metadata.AdditionalFiles.CssScope =
[/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/Components/Pages/Weather.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50cy9QYWdlcy9XZWF0aGVyLnJhem9y
build_metadata.AdditionalFiles.CssScope =
[/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/Components/Routes.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50cy9Sb3V0ZXMucmF6b3I=
build_metadata.AdditionalFiles.CssScope =
[/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/Components/_Imports.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50cy9fSW1wb3J0cy5yYXpvcg==
build_metadata.AdditionalFiles.CssScope =
[/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/Components/Layout/MainLayout.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50cy9MYXlvdXQvTWFpbkxheW91dC5yYXpvcg==
build_metadata.AdditionalFiles.CssScope = b-fekawvbbds
[/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/Components/Layout/NavMenu.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50cy9MYXlvdXQvTmF2TWVudS5yYXpvcg==
build_metadata.AdditionalFiles.CssScope = b-zswk0q6kaa

View File

@ -0,0 +1,17 @@
// <auto-generated/>
global using global::Microsoft.AspNetCore.Builder;
global using global::Microsoft.AspNetCore.Hosting;
global using global::Microsoft.AspNetCore.Http;
global using global::Microsoft.AspNetCore.Routing;
global using global::Microsoft.Extensions.Configuration;
global using global::Microsoft.Extensions.DependencyInjection;
global using global::Microsoft.Extensions.Hosting;
global using global::Microsoft.Extensions.Logging;
global using global::System;
global using global::System.Collections.Generic;
global using global::System.IO;
global using global::System.Linq;
global using global::System.Net.Http;
global using global::System.Net.Http.Json;
global using global::System.Threading;
global using global::System.Threading.Tasks;

Binary file not shown.

View File

@ -0,0 +1 @@
0b4a6664a422117388860abdb563a3db32bb8de9362e58982c645637e7d5a02f

View File

@ -0,0 +1,29 @@
/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/bin/Debug/net8.0/appsettings.Development.json
/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/bin/Debug/net8.0/appsettings.json
/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/bin/Debug/net8.0/BlazorApp.staticwebassets.runtime.json
/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/bin/Debug/net8.0/BlazorApp
/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/bin/Debug/net8.0/BlazorApp.deps.json
/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/bin/Debug/net8.0/BlazorApp.runtimeconfig.json
/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/bin/Debug/net8.0/BlazorApp.dll
/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/bin/Debug/net8.0/BlazorApp.pdb
/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/obj/Debug/net8.0/BlazorApp.GeneratedMSBuildEditorConfig.editorconfig
/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/obj/Debug/net8.0/BlazorApp.AssemblyInfoInputs.cache
/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/obj/Debug/net8.0/BlazorApp.AssemblyInfo.cs
/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/obj/Debug/net8.0/BlazorApp.csproj.CoreCompileInputs.cache
/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/obj/Debug/net8.0/BlazorApp.MvcApplicationPartsAssemblyInfo.cache
/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/obj/Debug/net8.0/staticwebassets.build.json
/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/obj/Debug/net8.0/staticwebassets.development.json
/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/obj/Debug/net8.0/staticwebassets/msbuild.BlazorApp.Microsoft.AspNetCore.StaticWebAssets.props
/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/obj/Debug/net8.0/staticwebassets/msbuild.build.BlazorApp.props
/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/obj/Debug/net8.0/staticwebassets/msbuild.buildMultiTargeting.BlazorApp.props
/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/obj/Debug/net8.0/staticwebassets/msbuild.buildTransitive.BlazorApp.props
/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/obj/Debug/net8.0/staticwebassets.pack.json
/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/obj/Debug/net8.0/scopedcss/Components/Layout/MainLayout.razor.rz.scp.css
/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/obj/Debug/net8.0/scopedcss/Components/Layout/NavMenu.razor.rz.scp.css
/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/obj/Debug/net8.0/scopedcss/bundle/BlazorApp.styles.css
/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/obj/Debug/net8.0/scopedcss/projectbundle/BlazorApp.bundle.scp.css
/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/obj/Debug/net8.0/BlazorApp.dll
/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/obj/Debug/net8.0/refint/BlazorApp.dll
/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/obj/Debug/net8.0/BlazorApp.pdb
/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/obj/Debug/net8.0/BlazorApp.genruntimeconfig.cache
/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/obj/Debug/net8.0/ref/BlazorApp.dll

Binary file not shown.

View File

@ -0,0 +1 @@
86cec912a56536606abff7c9b8e754d974b32164bc1f705d520d6ba3bd2c0441

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,96 @@
.page[b-fekawvbbds] {
position: relative;
display: flex;
flex-direction: column;
}
main[b-fekawvbbds] {
flex: 1;
}
.sidebar[b-fekawvbbds] {
background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%);
}
.top-row[b-fekawvbbds] {
background-color: #f7f7f7;
border-bottom: 1px solid #d6d5d5;
justify-content: flex-end;
height: 3.5rem;
display: flex;
align-items: center;
}
.top-row[b-fekawvbbds] a, .top-row[b-fekawvbbds] .btn-link {
white-space: nowrap;
margin-left: 1.5rem;
text-decoration: none;
}
.top-row[b-fekawvbbds] a:hover, .top-row[b-fekawvbbds] .btn-link:hover {
text-decoration: underline;
}
.top-row[b-fekawvbbds] a:first-child {
overflow: hidden;
text-overflow: ellipsis;
}
@media (max-width: 640.98px) {
.top-row[b-fekawvbbds] {
justify-content: space-between;
}
.top-row[b-fekawvbbds] a, .top-row[b-fekawvbbds] .btn-link {
margin-left: 0;
}
}
@media (min-width: 641px) {
.page[b-fekawvbbds] {
flex-direction: row;
}
.sidebar[b-fekawvbbds] {
width: 250px;
height: 100vh;
position: sticky;
top: 0;
}
.top-row[b-fekawvbbds] {
position: sticky;
top: 0;
z-index: 1;
}
.top-row.auth[b-fekawvbbds] a:first-child {
flex: 1;
text-align: right;
width: 0;
}
.top-row[b-fekawvbbds], article[b-fekawvbbds] {
padding-left: 2rem !important;
padding-right: 1.5rem !important;
}
}
#blazor-error-ui[b-fekawvbbds] {
background: lightyellow;
bottom: 0;
box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
display: none;
left: 0;
padding: 0.6rem 1.25rem 0.7rem 1.25rem;
position: fixed;
width: 100%;
z-index: 1000;
}
#blazor-error-ui .dismiss[b-fekawvbbds] {
cursor: pointer;
position: absolute;
right: 0.75rem;
top: 0.5rem;
}

View File

@ -0,0 +1,110 @@
.navbar-toggler[b-zswk0q6kaa] {
appearance: none;
cursor: pointer;
width: 3.5rem;
height: 2.5rem;
color: white;
position: absolute;
top: 0.5rem;
right: 1rem;
border: 1px solid rgba(255, 255, 255, 0.1);
background: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e") no-repeat center/1.75rem rgba(255, 255, 255, 0.1);
}
.navbar-toggler:checked[b-zswk0q6kaa] {
background-color: rgba(255, 255, 255, 0.5);
}
.top-row[b-zswk0q6kaa] {
height: 3.5rem;
background-color: rgba(0,0,0,0.4);
}
.navbar-brand[b-zswk0q6kaa] {
font-size: 1.1rem;
}
.bi[b-zswk0q6kaa] {
display: inline-block;
position: relative;
width: 1.25rem;
height: 1.25rem;
margin-right: 0.75rem;
top: -1px;
background-size: cover;
}
.bi-calendar-event-nav-menu[b-zswk0q6kaa] {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' class='bi bi-calendar-event' viewBox='0 0 16 16'%3E%3Cpath d='M11 6.5a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5z'/%3e%3c/svg%3e");
}
.bi-house-door-fill-nav-menu[b-zswk0q6kaa] {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-house-door-fill' viewBox='0 0 16 16'%3E%3Cpath d='M6.5 14.5v-3.505c0-.245.25-.495.5-.495h2c.25 0 .5.25.5.5v3.5a.5.5 0 0 0 .5.5h4a.5.5 0 0 0 .5-.5v-7a.5.5 0 0 0-.146-.354L13 5.793V2.5a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5v1.293L8.354 1.146a.5.5 0 0 0-.708 0l-6 6A.5.5 0 0 0 1.5 7.5v7a.5.5 0 0 0 .5.5h4a.5.5 0 0 0 .5-.5Z'/%3E%3C/svg%3E");
}
.bi-plus-square-fill-nav-menu[b-zswk0q6kaa] {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-plus-square-fill' viewBox='0 0 16 16'%3E%3Cpath d='M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2zm6.5 4.5v3h3a.5.5 0 0 1 0 1h-3v3a.5.5 0 0 1-1 0v-3h-3a.5.5 0 0 1 0-1h3v-3a.5.5 0 0 1 1 0z'/%3E%3C/svg%3E");
}
.bi-list-nested-nav-menu[b-zswk0q6kaa] {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-list-nested' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M4.5 11.5A.5.5 0 0 1 5 11h10a.5.5 0 0 1 0 1H5a.5.5 0 0 1-.5-.5zm-2-4A.5.5 0 0 1 3 7h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5zm-2-4A.5.5 0 0 1 1 3h10a.5.5 0 0 1 0 1H1a.5.5 0 0 1-.5-.5z'/%3E%3C/svg%3E");
}
.nav-item[b-zswk0q6kaa] {
font-size: 0.9rem;
padding-bottom: 0.5rem;
}
.nav-item:first-of-type[b-zswk0q6kaa] {
padding-top: 1rem;
}
.nav-item:last-of-type[b-zswk0q6kaa] {
padding-bottom: 1rem;
}
.nav-item[b-zswk0q6kaa] .nav-link {
color: #d7d7d7;
background: none;
border: none;
border-radius: 4px;
height: 3rem;
display: flex;
align-items: center;
line-height: 3rem;
width: 100%;
}
.nav-item[b-zswk0q6kaa] a.active {
background-color: rgba(255,255,255,0.37);
color: white;
}
.nav-item[b-zswk0q6kaa] .nav-link:hover {
background-color: rgba(255,255,255,0.1);
color: white;
}
.nav-scrollable[b-zswk0q6kaa] {
display: none;
}
.navbar-toggler:checked ~ .nav-scrollable[b-zswk0q6kaa] {
display: block;
}
@media (min-width: 641px) {
.navbar-toggler[b-zswk0q6kaa] {
display: none;
}
.nav-scrollable[b-zswk0q6kaa] {
/* Never collapse the sidebar for wide screens */
display: block;
/* Allow sidebar to scroll for tall menus */
height: calc(100vh - 3.5rem);
overflow-y: auto;
}
}

View File

@ -0,0 +1,208 @@
/* _content/BlazorApp/Components/Layout/MainLayout.razor.rz.scp.css */
.page[b-fekawvbbds] {
position: relative;
display: flex;
flex-direction: column;
}
main[b-fekawvbbds] {
flex: 1;
}
.sidebar[b-fekawvbbds] {
background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%);
}
.top-row[b-fekawvbbds] {
background-color: #f7f7f7;
border-bottom: 1px solid #d6d5d5;
justify-content: flex-end;
height: 3.5rem;
display: flex;
align-items: center;
}
.top-row[b-fekawvbbds] a, .top-row[b-fekawvbbds] .btn-link {
white-space: nowrap;
margin-left: 1.5rem;
text-decoration: none;
}
.top-row[b-fekawvbbds] a:hover, .top-row[b-fekawvbbds] .btn-link:hover {
text-decoration: underline;
}
.top-row[b-fekawvbbds] a:first-child {
overflow: hidden;
text-overflow: ellipsis;
}
@media (max-width: 640.98px) {
.top-row[b-fekawvbbds] {
justify-content: space-between;
}
.top-row[b-fekawvbbds] a, .top-row[b-fekawvbbds] .btn-link {
margin-left: 0;
}
}
@media (min-width: 641px) {
.page[b-fekawvbbds] {
flex-direction: row;
}
.sidebar[b-fekawvbbds] {
width: 250px;
height: 100vh;
position: sticky;
top: 0;
}
.top-row[b-fekawvbbds] {
position: sticky;
top: 0;
z-index: 1;
}
.top-row.auth[b-fekawvbbds] a:first-child {
flex: 1;
text-align: right;
width: 0;
}
.top-row[b-fekawvbbds], article[b-fekawvbbds] {
padding-left: 2rem !important;
padding-right: 1.5rem !important;
}
}
#blazor-error-ui[b-fekawvbbds] {
background: lightyellow;
bottom: 0;
box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
display: none;
left: 0;
padding: 0.6rem 1.25rem 0.7rem 1.25rem;
position: fixed;
width: 100%;
z-index: 1000;
}
#blazor-error-ui .dismiss[b-fekawvbbds] {
cursor: pointer;
position: absolute;
right: 0.75rem;
top: 0.5rem;
}
/* _content/BlazorApp/Components/Layout/NavMenu.razor.rz.scp.css */
.navbar-toggler[b-zswk0q6kaa] {
appearance: none;
cursor: pointer;
width: 3.5rem;
height: 2.5rem;
color: white;
position: absolute;
top: 0.5rem;
right: 1rem;
border: 1px solid rgba(255, 255, 255, 0.1);
background: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e") no-repeat center/1.75rem rgba(255, 255, 255, 0.1);
}
.navbar-toggler:checked[b-zswk0q6kaa] {
background-color: rgba(255, 255, 255, 0.5);
}
.top-row[b-zswk0q6kaa] {
height: 3.5rem;
background-color: rgba(0,0,0,0.4);
}
.navbar-brand[b-zswk0q6kaa] {
font-size: 1.1rem;
}
.bi[b-zswk0q6kaa] {
display: inline-block;
position: relative;
width: 1.25rem;
height: 1.25rem;
margin-right: 0.75rem;
top: -1px;
background-size: cover;
}
.bi-calendar-event-nav-menu[b-zswk0q6kaa] {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' class='bi bi-calendar-event' viewBox='0 0 16 16'%3E%3Cpath d='M11 6.5a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5z'/%3e%3c/svg%3e");
}
.bi-house-door-fill-nav-menu[b-zswk0q6kaa] {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-house-door-fill' viewBox='0 0 16 16'%3E%3Cpath d='M6.5 14.5v-3.505c0-.245.25-.495.5-.495h2c.25 0 .5.25.5.5v3.5a.5.5 0 0 0 .5.5h4a.5.5 0 0 0 .5-.5v-7a.5.5 0 0 0-.146-.354L13 5.793V2.5a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5v1.293L8.354 1.146a.5.5 0 0 0-.708 0l-6 6A.5.5 0 0 0 1.5 7.5v7a.5.5 0 0 0 .5.5h4a.5.5 0 0 0 .5-.5Z'/%3E%3C/svg%3E");
}
.bi-plus-square-fill-nav-menu[b-zswk0q6kaa] {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-plus-square-fill' viewBox='0 0 16 16'%3E%3Cpath d='M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2zm6.5 4.5v3h3a.5.5 0 0 1 0 1h-3v3a.5.5 0 0 1-1 0v-3h-3a.5.5 0 0 1 0-1h3v-3a.5.5 0 0 1 1 0z'/%3E%3C/svg%3E");
}
.bi-list-nested-nav-menu[b-zswk0q6kaa] {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-list-nested' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M4.5 11.5A.5.5 0 0 1 5 11h10a.5.5 0 0 1 0 1H5a.5.5 0 0 1-.5-.5zm-2-4A.5.5 0 0 1 3 7h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5zm-2-4A.5.5 0 0 1 1 3h10a.5.5 0 0 1 0 1H1a.5.5 0 0 1-.5-.5z'/%3E%3C/svg%3E");
}
.nav-item[b-zswk0q6kaa] {
font-size: 0.9rem;
padding-bottom: 0.5rem;
}
.nav-item:first-of-type[b-zswk0q6kaa] {
padding-top: 1rem;
}
.nav-item:last-of-type[b-zswk0q6kaa] {
padding-bottom: 1rem;
}
.nav-item[b-zswk0q6kaa] .nav-link {
color: #d7d7d7;
background: none;
border: none;
border-radius: 4px;
height: 3rem;
display: flex;
align-items: center;
line-height: 3rem;
width: 100%;
}
.nav-item[b-zswk0q6kaa] a.active {
background-color: rgba(255,255,255,0.37);
color: white;
}
.nav-item[b-zswk0q6kaa] .nav-link:hover {
background-color: rgba(255,255,255,0.1);
color: white;
}
.nav-scrollable[b-zswk0q6kaa] {
display: none;
}
.navbar-toggler:checked ~ .nav-scrollable[b-zswk0q6kaa] {
display: block;
}
@media (min-width: 641px) {
.navbar-toggler[b-zswk0q6kaa] {
display: none;
}
.nav-scrollable[b-zswk0q6kaa] {
/* Never collapse the sidebar for wide screens */
display: block;
/* Allow sidebar to scroll for tall menus */
height: calc(100vh - 3.5rem);
overflow-y: auto;
}
}

View File

@ -0,0 +1,208 @@
/* _content/BlazorApp/Components/Layout/MainLayout.razor.rz.scp.css */
.page[b-fekawvbbds] {
position: relative;
display: flex;
flex-direction: column;
}
main[b-fekawvbbds] {
flex: 1;
}
.sidebar[b-fekawvbbds] {
background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%);
}
.top-row[b-fekawvbbds] {
background-color: #f7f7f7;
border-bottom: 1px solid #d6d5d5;
justify-content: flex-end;
height: 3.5rem;
display: flex;
align-items: center;
}
.top-row[b-fekawvbbds] a, .top-row[b-fekawvbbds] .btn-link {
white-space: nowrap;
margin-left: 1.5rem;
text-decoration: none;
}
.top-row[b-fekawvbbds] a:hover, .top-row[b-fekawvbbds] .btn-link:hover {
text-decoration: underline;
}
.top-row[b-fekawvbbds] a:first-child {
overflow: hidden;
text-overflow: ellipsis;
}
@media (max-width: 640.98px) {
.top-row[b-fekawvbbds] {
justify-content: space-between;
}
.top-row[b-fekawvbbds] a, .top-row[b-fekawvbbds] .btn-link {
margin-left: 0;
}
}
@media (min-width: 641px) {
.page[b-fekawvbbds] {
flex-direction: row;
}
.sidebar[b-fekawvbbds] {
width: 250px;
height: 100vh;
position: sticky;
top: 0;
}
.top-row[b-fekawvbbds] {
position: sticky;
top: 0;
z-index: 1;
}
.top-row.auth[b-fekawvbbds] a:first-child {
flex: 1;
text-align: right;
width: 0;
}
.top-row[b-fekawvbbds], article[b-fekawvbbds] {
padding-left: 2rem !important;
padding-right: 1.5rem !important;
}
}
#blazor-error-ui[b-fekawvbbds] {
background: lightyellow;
bottom: 0;
box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
display: none;
left: 0;
padding: 0.6rem 1.25rem 0.7rem 1.25rem;
position: fixed;
width: 100%;
z-index: 1000;
}
#blazor-error-ui .dismiss[b-fekawvbbds] {
cursor: pointer;
position: absolute;
right: 0.75rem;
top: 0.5rem;
}
/* _content/BlazorApp/Components/Layout/NavMenu.razor.rz.scp.css */
.navbar-toggler[b-zswk0q6kaa] {
appearance: none;
cursor: pointer;
width: 3.5rem;
height: 2.5rem;
color: white;
position: absolute;
top: 0.5rem;
right: 1rem;
border: 1px solid rgba(255, 255, 255, 0.1);
background: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e") no-repeat center/1.75rem rgba(255, 255, 255, 0.1);
}
.navbar-toggler:checked[b-zswk0q6kaa] {
background-color: rgba(255, 255, 255, 0.5);
}
.top-row[b-zswk0q6kaa] {
height: 3.5rem;
background-color: rgba(0,0,0,0.4);
}
.navbar-brand[b-zswk0q6kaa] {
font-size: 1.1rem;
}
.bi[b-zswk0q6kaa] {
display: inline-block;
position: relative;
width: 1.25rem;
height: 1.25rem;
margin-right: 0.75rem;
top: -1px;
background-size: cover;
}
.bi-calendar-event-nav-menu[b-zswk0q6kaa] {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' class='bi bi-calendar-event' viewBox='0 0 16 16'%3E%3Cpath d='M11 6.5a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5z'/%3e%3c/svg%3e");
}
.bi-house-door-fill-nav-menu[b-zswk0q6kaa] {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-house-door-fill' viewBox='0 0 16 16'%3E%3Cpath d='M6.5 14.5v-3.505c0-.245.25-.495.5-.495h2c.25 0 .5.25.5.5v3.5a.5.5 0 0 0 .5.5h4a.5.5 0 0 0 .5-.5v-7a.5.5 0 0 0-.146-.354L13 5.793V2.5a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5v1.293L8.354 1.146a.5.5 0 0 0-.708 0l-6 6A.5.5 0 0 0 1.5 7.5v7a.5.5 0 0 0 .5.5h4a.5.5 0 0 0 .5-.5Z'/%3E%3C/svg%3E");
}
.bi-plus-square-fill-nav-menu[b-zswk0q6kaa] {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-plus-square-fill' viewBox='0 0 16 16'%3E%3Cpath d='M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2zm6.5 4.5v3h3a.5.5 0 0 1 0 1h-3v3a.5.5 0 0 1-1 0v-3h-3a.5.5 0 0 1 0-1h3v-3a.5.5 0 0 1 1 0z'/%3E%3C/svg%3E");
}
.bi-list-nested-nav-menu[b-zswk0q6kaa] {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-list-nested' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M4.5 11.5A.5.5 0 0 1 5 11h10a.5.5 0 0 1 0 1H5a.5.5 0 0 1-.5-.5zm-2-4A.5.5 0 0 1 3 7h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5zm-2-4A.5.5 0 0 1 1 3h10a.5.5 0 0 1 0 1H1a.5.5 0 0 1-.5-.5z'/%3E%3C/svg%3E");
}
.nav-item[b-zswk0q6kaa] {
font-size: 0.9rem;
padding-bottom: 0.5rem;
}
.nav-item:first-of-type[b-zswk0q6kaa] {
padding-top: 1rem;
}
.nav-item:last-of-type[b-zswk0q6kaa] {
padding-bottom: 1rem;
}
.nav-item[b-zswk0q6kaa] .nav-link {
color: #d7d7d7;
background: none;
border: none;
border-radius: 4px;
height: 3rem;
display: flex;
align-items: center;
line-height: 3rem;
width: 100%;
}
.nav-item[b-zswk0q6kaa] a.active {
background-color: rgba(255,255,255,0.37);
color: white;
}
.nav-item[b-zswk0q6kaa] .nav-link:hover {
background-color: rgba(255,255,255,0.1);
color: white;
}
.nav-scrollable[b-zswk0q6kaa] {
display: none;
}
.navbar-toggler:checked ~ .nav-scrollable[b-zswk0q6kaa] {
display: block;
}
@media (min-width: 641px) {
.navbar-toggler[b-zswk0q6kaa] {
display: none;
}
.nav-scrollable[b-zswk0q6kaa] {
/* Never collapse the sidebar for wide screens */
display: block;
/* Allow sidebar to scroll for tall menus */
height: calc(100vh - 3.5rem);
overflow-y: auto;
}
}

View File

@ -0,0 +1,153 @@
{
"Version": 1,
"Hash": "nUrCSvVwb6tU31OGGQHmAGFJpGYCNW+n/4158dIVOMM=",
"Source": "BlazorApp",
"BasePath": "_content/BlazorApp",
"Mode": "Default",
"ManifestType": "Build",
"ReferencedProjectsConfiguration": [],
"DiscoveryPatterns": [
{
"Name": "BlazorApp/wwwroot",
"Source": "BlazorApp",
"ContentRoot": "/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/wwwroot/",
"BasePath": "_content/BlazorApp",
"Pattern": "**"
}
],
"Assets": [
{
"Identity": "/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/obj/Debug/net8.0/scopedcss/bundle/BlazorApp.styles.css",
"SourceId": "BlazorApp",
"SourceType": "Computed",
"ContentRoot": "/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/obj/Debug/net8.0/scopedcss/bundle/",
"BasePath": "_content/BlazorApp",
"RelativePath": "BlazorApp.styles.css",
"AssetKind": "All",
"AssetMode": "CurrentProject",
"AssetRole": "Primary",
"AssetMergeBehavior": "",
"AssetMergeSource": "",
"RelatedAsset": "",
"AssetTraitName": "ScopedCss",
"AssetTraitValue": "ApplicationBundle",
"CopyToOutputDirectory": "Never",
"CopyToPublishDirectory": "PreserveNewest",
"OriginalItemSpec": "/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/obj/Debug/net8.0/scopedcss/bundle/BlazorApp.styles.css"
},
{
"Identity": "/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/obj/Debug/net8.0/scopedcss/projectbundle/BlazorApp.bundle.scp.css",
"SourceId": "BlazorApp",
"SourceType": "Computed",
"ContentRoot": "/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/obj/Debug/net8.0/scopedcss/projectbundle/",
"BasePath": "_content/BlazorApp",
"RelativePath": "BlazorApp.bundle.scp.css",
"AssetKind": "All",
"AssetMode": "Reference",
"AssetRole": "Primary",
"AssetMergeBehavior": "",
"AssetMergeSource": "",
"RelatedAsset": "",
"AssetTraitName": "ScopedCss",
"AssetTraitValue": "ProjectBundle",
"CopyToOutputDirectory": "Never",
"CopyToPublishDirectory": "PreserveNewest",
"OriginalItemSpec": "/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/obj/Debug/net8.0/scopedcss/projectbundle/BlazorApp.bundle.scp.css"
},
{
"Identity": "/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/wwwroot/app.css",
"SourceId": "BlazorApp",
"SourceType": "Discovered",
"ContentRoot": "/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/wwwroot/",
"BasePath": "_content/BlazorApp",
"RelativePath": "app.css",
"AssetKind": "All",
"AssetMode": "All",
"AssetRole": "Primary",
"AssetMergeBehavior": "PreferTarget",
"AssetMergeSource": "",
"RelatedAsset": "",
"AssetTraitName": "",
"AssetTraitValue": "",
"CopyToOutputDirectory": "Never",
"CopyToPublishDirectory": "PreserveNewest",
"OriginalItemSpec": "wwwroot/app.css"
},
{
"Identity": "/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/wwwroot/bootstrap/bootstrap.min.css",
"SourceId": "BlazorApp",
"SourceType": "Discovered",
"ContentRoot": "/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/wwwroot/",
"BasePath": "_content/BlazorApp",
"RelativePath": "bootstrap/bootstrap.min.css",
"AssetKind": "All",
"AssetMode": "All",
"AssetRole": "Primary",
"AssetMergeBehavior": "PreferTarget",
"AssetMergeSource": "",
"RelatedAsset": "",
"AssetTraitName": "",
"AssetTraitValue": "",
"CopyToOutputDirectory": "Never",
"CopyToPublishDirectory": "PreserveNewest",
"OriginalItemSpec": "wwwroot/bootstrap/bootstrap.min.css"
},
{
"Identity": "/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/wwwroot/bootstrap/bootstrap.min.css.map",
"SourceId": "BlazorApp",
"SourceType": "Discovered",
"ContentRoot": "/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/wwwroot/",
"BasePath": "_content/BlazorApp",
"RelativePath": "bootstrap/bootstrap.min.css.map",
"AssetKind": "All",
"AssetMode": "All",
"AssetRole": "Primary",
"AssetMergeBehavior": "PreferTarget",
"AssetMergeSource": "",
"RelatedAsset": "",
"AssetTraitName": "",
"AssetTraitValue": "",
"CopyToOutputDirectory": "Never",
"CopyToPublishDirectory": "PreserveNewest",
"OriginalItemSpec": "wwwroot/bootstrap/bootstrap.min.css.map"
},
{
"Identity": "/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/wwwroot/favicon.png",
"SourceId": "BlazorApp",
"SourceType": "Discovered",
"ContentRoot": "/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/wwwroot/",
"BasePath": "_content/BlazorApp",
"RelativePath": "favicon.png",
"AssetKind": "All",
"AssetMode": "All",
"AssetRole": "Primary",
"AssetMergeBehavior": "PreferTarget",
"AssetMergeSource": "",
"RelatedAsset": "",
"AssetTraitName": "",
"AssetTraitValue": "",
"CopyToOutputDirectory": "Never",
"CopyToPublishDirectory": "PreserveNewest",
"OriginalItemSpec": "wwwroot/favicon.png"
},
{
"Identity": "/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/wwwroot/index.html",
"SourceId": "BlazorApp",
"SourceType": "Discovered",
"ContentRoot": "/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/wwwroot/",
"BasePath": "_content/BlazorApp",
"RelativePath": "index.html",
"AssetKind": "All",
"AssetMode": "All",
"AssetRole": "Primary",
"AssetMergeBehavior": "PreferTarget",
"AssetMergeSource": "",
"RelatedAsset": "",
"AssetTraitName": "",
"AssetTraitValue": "",
"CopyToOutputDirectory": "Never",
"CopyToPublishDirectory": "PreserveNewest",
"OriginalItemSpec": "wwwroot/index.html"
}
]
}

View File

@ -0,0 +1 @@
{"ContentRoots":["/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/wwwroot/","/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/obj/Debug/net8.0/scopedcss/bundle/"],"Root":{"Children":{"app.css":{"Children":null,"Asset":{"ContentRootIndex":0,"SubPath":"app.css"},"Patterns":null},"bootstrap":{"Children":{"bootstrap.min.css":{"Children":null,"Asset":{"ContentRootIndex":0,"SubPath":"bootstrap/bootstrap.min.css"},"Patterns":null},"bootstrap.min.css.map":{"Children":null,"Asset":{"ContentRootIndex":0,"SubPath":"bootstrap/bootstrap.min.css.map"},"Patterns":null}},"Asset":null,"Patterns":null},"favicon.png":{"Children":null,"Asset":{"ContentRootIndex":0,"SubPath":"favicon.png"},"Patterns":null},"index.html":{"Children":null,"Asset":{"ContentRootIndex":0,"SubPath":"index.html"},"Patterns":null},"BlazorApp.styles.css":{"Children":null,"Asset":{"ContentRootIndex":1,"SubPath":"BlazorApp.styles.css"},"Patterns":null}},"Asset":null,"Patterns":[{"ContentRootIndex":0,"Pattern":"**","Depth":0}]}}

View File

@ -0,0 +1,45 @@
{
"Files": [
{
"Id": "/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/obj/Debug/net8.0/scopedcss/projectbundle/BlazorApp.bundle.scp.css",
"PackagePath": "staticwebassets/BlazorApp.bundle.scp.css"
},
{
"Id": "/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/wwwroot/app.css",
"PackagePath": "staticwebassets/app.css"
},
{
"Id": "/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/wwwroot/bootstrap/bootstrap.min.css",
"PackagePath": "staticwebassets/bootstrap/bootstrap.min.css"
},
{
"Id": "/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/wwwroot/bootstrap/bootstrap.min.css.map",
"PackagePath": "staticwebassets/bootstrap/bootstrap.min.css.map"
},
{
"Id": "/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/wwwroot/favicon.png",
"PackagePath": "staticwebassets/favicon.png"
},
{
"Id": "/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/wwwroot/index.html",
"PackagePath": "staticwebassets/index.html"
},
{
"Id": "obj/Debug/net8.0/staticwebassets/msbuild.BlazorApp.Microsoft.AspNetCore.StaticWebAssets.props",
"PackagePath": "build\\Microsoft.AspNetCore.StaticWebAssets.props"
},
{
"Id": "obj/Debug/net8.0/staticwebassets/msbuild.build.BlazorApp.props",
"PackagePath": "build\\BlazorApp.props"
},
{
"Id": "obj/Debug/net8.0/staticwebassets/msbuild.buildMultiTargeting.BlazorApp.props",
"PackagePath": "buildMultiTargeting\\BlazorApp.props"
},
{
"Id": "obj/Debug/net8.0/staticwebassets/msbuild.buildTransitive.BlazorApp.props",
"PackagePath": "buildTransitive\\BlazorApp.props"
}
],
"ElementsToRemove": []
}

View File

@ -0,0 +1,100 @@
<Project>
<ItemGroup>
<StaticWebAsset Include="$([System.IO.Path]::GetFullPath($(MSBuildThisFileDirectory)..\staticwebassets\app.css))">
<SourceType>Package</SourceType>
<SourceId>BlazorApp</SourceId>
<ContentRoot>$(MSBuildThisFileDirectory)..\staticwebassets\</ContentRoot>
<BasePath>_content/BlazorApp</BasePath>
<RelativePath>app.css</RelativePath>
<AssetKind>All</AssetKind>
<AssetMode>All</AssetMode>
<AssetRole>Primary</AssetRole>
<RelatedAsset></RelatedAsset>
<AssetTraitName></AssetTraitName>
<AssetTraitValue></AssetTraitValue>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
<OriginalItemSpec>$([System.IO.Path]::GetFullPath($(MSBuildThisFileDirectory)..\staticwebassets\app.css))</OriginalItemSpec>
</StaticWebAsset>
<StaticWebAsset Include="$([System.IO.Path]::GetFullPath($(MSBuildThisFileDirectory)..\staticwebassets\BlazorApp.bundle.scp.css))">
<SourceType>Package</SourceType>
<SourceId>BlazorApp</SourceId>
<ContentRoot>$(MSBuildThisFileDirectory)..\staticwebassets\</ContentRoot>
<BasePath>_content/BlazorApp</BasePath>
<RelativePath>BlazorApp.bundle.scp.css</RelativePath>
<AssetKind>All</AssetKind>
<AssetMode>Reference</AssetMode>
<AssetRole>Primary</AssetRole>
<RelatedAsset></RelatedAsset>
<AssetTraitName>ScopedCss</AssetTraitName>
<AssetTraitValue>ProjectBundle</AssetTraitValue>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
<OriginalItemSpec>$([System.IO.Path]::GetFullPath($(MSBuildThisFileDirectory)..\staticwebassets\BlazorApp.bundle.scp.css))</OriginalItemSpec>
</StaticWebAsset>
<StaticWebAsset Include="$([System.IO.Path]::GetFullPath($(MSBuildThisFileDirectory)..\staticwebassets\bootstrap\bootstrap.min.css))">
<SourceType>Package</SourceType>
<SourceId>BlazorApp</SourceId>
<ContentRoot>$(MSBuildThisFileDirectory)..\staticwebassets\</ContentRoot>
<BasePath>_content/BlazorApp</BasePath>
<RelativePath>bootstrap/bootstrap.min.css</RelativePath>
<AssetKind>All</AssetKind>
<AssetMode>All</AssetMode>
<AssetRole>Primary</AssetRole>
<RelatedAsset></RelatedAsset>
<AssetTraitName></AssetTraitName>
<AssetTraitValue></AssetTraitValue>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
<OriginalItemSpec>$([System.IO.Path]::GetFullPath($(MSBuildThisFileDirectory)..\staticwebassets\bootstrap\bootstrap.min.css))</OriginalItemSpec>
</StaticWebAsset>
<StaticWebAsset Include="$([System.IO.Path]::GetFullPath($(MSBuildThisFileDirectory)..\staticwebassets\bootstrap\bootstrap.min.css.map))">
<SourceType>Package</SourceType>
<SourceId>BlazorApp</SourceId>
<ContentRoot>$(MSBuildThisFileDirectory)..\staticwebassets\</ContentRoot>
<BasePath>_content/BlazorApp</BasePath>
<RelativePath>bootstrap/bootstrap.min.css.map</RelativePath>
<AssetKind>All</AssetKind>
<AssetMode>All</AssetMode>
<AssetRole>Primary</AssetRole>
<RelatedAsset></RelatedAsset>
<AssetTraitName></AssetTraitName>
<AssetTraitValue></AssetTraitValue>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
<OriginalItemSpec>$([System.IO.Path]::GetFullPath($(MSBuildThisFileDirectory)..\staticwebassets\bootstrap\bootstrap.min.css.map))</OriginalItemSpec>
</StaticWebAsset>
<StaticWebAsset Include="$([System.IO.Path]::GetFullPath($(MSBuildThisFileDirectory)..\staticwebassets\favicon.png))">
<SourceType>Package</SourceType>
<SourceId>BlazorApp</SourceId>
<ContentRoot>$(MSBuildThisFileDirectory)..\staticwebassets\</ContentRoot>
<BasePath>_content/BlazorApp</BasePath>
<RelativePath>favicon.png</RelativePath>
<AssetKind>All</AssetKind>
<AssetMode>All</AssetMode>
<AssetRole>Primary</AssetRole>
<RelatedAsset></RelatedAsset>
<AssetTraitName></AssetTraitName>
<AssetTraitValue></AssetTraitValue>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
<OriginalItemSpec>$([System.IO.Path]::GetFullPath($(MSBuildThisFileDirectory)..\staticwebassets\favicon.png))</OriginalItemSpec>
</StaticWebAsset>
<StaticWebAsset Include="$([System.IO.Path]::GetFullPath($(MSBuildThisFileDirectory)..\staticwebassets\index.html))">
<SourceType>Package</SourceType>
<SourceId>BlazorApp</SourceId>
<ContentRoot>$(MSBuildThisFileDirectory)..\staticwebassets\</ContentRoot>
<BasePath>_content/BlazorApp</BasePath>
<RelativePath>index.html</RelativePath>
<AssetKind>All</AssetKind>
<AssetMode>All</AssetMode>
<AssetRole>Primary</AssetRole>
<RelatedAsset></RelatedAsset>
<AssetTraitName></AssetTraitName>
<AssetTraitValue></AssetTraitValue>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
<OriginalItemSpec>$([System.IO.Path]::GetFullPath($(MSBuildThisFileDirectory)..\staticwebassets\index.html))</OriginalItemSpec>
</StaticWebAsset>
</ItemGroup>
</Project>

View File

@ -0,0 +1,3 @@
<Project>
<Import Project="Microsoft.AspNetCore.StaticWebAssets.props" />
</Project>

View File

@ -0,0 +1,3 @@
<Project>
<Import Project="../build/BlazorApp.props" />
</Project>

View File

@ -0,0 +1,3 @@
<Project>
<Import Project="../buildMultiTargeting/BlazorApp.props" />
</Project>

View File

@ -0,0 +1,74 @@
{
"version": 3,
"targets": {
"net8.0": {}
},
"libraries": {},
"projectFileDependencyGroups": {
"net8.0": []
},
"packageFolders": {
"/Users/seankim/.nuget/packages/": {}
},
"project": {
"version": "1.0.0",
"restore": {
"projectUniqueName": "/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/BlazorApp.csproj",
"projectName": "BlazorApp",
"projectPath": "/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/BlazorApp.csproj",
"packagesPath": "/Users/seankim/.nuget/packages/",
"outputPath": "/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/obj/",
"projectStyle": "PackageReference",
"configFilePaths": [
"/Users/seankim/.nuget/NuGet/NuGet.Config"
],
"originalTargetFrameworks": [
"net8.0"
],
"sources": {
"https://api.nuget.org/v3/index.json": {}
},
"frameworks": {
"net8.0": {
"targetAlias": "net8.0",
"projectReferences": {}
}
},
"warningProperties": {
"warnAsError": [
"NU1605"
]
},
"restoreAuditProperties": {
"enableAudit": "true",
"auditLevel": "low",
"auditMode": "direct"
}
},
"frameworks": {
"net8.0": {
"targetAlias": "net8.0",
"imports": [
"net461",
"net462",
"net47",
"net471",
"net472",
"net48",
"net481"
],
"assetTargetFallback": true,
"warn": true,
"frameworkReferences": {
"Microsoft.AspNetCore.App": {
"privateAssets": "none"
},
"Microsoft.NETCore.App": {
"privateAssets": "all"
}
},
"runtimeIdentifierGraphPath": "/usr/local/share/dotnet/sdk/8.0.401/PortableRuntimeIdentifierGraph.json"
}
}
}
}

View File

@ -0,0 +1,8 @@
{
"version": 2,
"dgSpecHash": "l5xqho5lZk0=",
"success": true,
"projectFilePath": "/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/BlazorApp.csproj",
"expectedPackageFiles": [],
"logs": []
}

View File

@ -0,0 +1 @@
"restore":{"projectUniqueName":"/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/BlazorApp.csproj","projectName":"BlazorApp","projectPath":"/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/BlazorApp.csproj","outputPath":"/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/obj/","projectStyle":"PackageReference","originalTargetFrameworks":["net8.0"],"sources":{"https://api.nuget.org/v3/index.json":{}},"frameworks":{"net8.0":{"targetAlias":"net8.0","projectReferences":{}}},"warningProperties":{"warnAsError":["NU1605"]},"restoreAuditProperties":{"enableAudit":"true","auditLevel":"low","auditMode":"direct"}}"frameworks":{"net8.0":{"targetAlias":"net8.0","imports":["net461","net462","net47","net471","net472","net48","net481"],"assetTargetFallback":true,"warn":true,"frameworkReferences":{"Microsoft.AspNetCore.App":{"privateAssets":"none"},"Microsoft.NETCore.App":{"privateAssets":"all"}},"runtimeIdentifierGraphPath":"/usr/local/share/dotnet/sdk/8.0.401/PortableRuntimeIdentifierGraph.json"}}

View File

@ -0,0 +1 @@
17274215440122346

View File

@ -0,0 +1 @@
17274215440122346

51
BlazorApp/wwwroot/app.css Normal file
View File

@ -0,0 +1,51 @@
html, body {
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
}
a, .btn-link {
color: #006bb7;
}
.btn-primary {
color: #fff;
background-color: #1b6ec2;
border-color: #1861ac;
}
.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {
box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb;
}
.content {
padding-top: 1.1rem;
}
h1:focus {
outline: none;
}
.valid.modified:not([type=checkbox]) {
outline: 1px solid #26b050;
}
.invalid {
outline: 1px solid #e50000;
}
.validation-message {
color: #e50000;
}
.blazor-error-boundary {
background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
padding: 1rem 1rem 1rem 3.7rem;
color: white;
}
.blazor-error-boundary::after {
content: "An error has occurred."
}
.darker-border-checkbox.form-check-input {
border-color: #929292;
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1,22 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>MyBlazorApp</title>
<!-- 이미 설치된 Bootstrap -->
<link href="bootstrap/bootstrap.min.css" rel="stylesheet" />
<!-- Bootstrap Icons 추가 -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css" rel="stylesheet">
<!-- 추가 스타일 -->
<link href="css/app.css" rel="stylesheet" />
</head>
<body>
<div id="app">Loading...</div>
<script src="_framework/blazor.webassembly.js"></script>
</body>
</html>

View File

@ -0,0 +1,173 @@
# ASP.NET Core Blazor 학습하기
## 시작하기
### 1. 생성
- 새 솔루션 > 프로젝트 유형/웹 선택 > 템플릿 에서 [Blazor Web App] 선택 > 기타 설정 > 생성
### 2. 구조
| | 설명 |
|:----------------------------:|:------------------------------------------------------------------------------------------------------------------------------------------------|
| ![프로젝트 구조](./캡쳐/프로젝트_구조.png) | - wwwroot 폴더<br/> HTML, JS, CSS 같은 정적 자산을 포함한다.<br/> - appsettings.json<br/> 연결 문자열과 같은 `구성 데이터`를 포함한다.<br/>- Program.cs<br/> 실행될 코드들을 포함하고 있다. |
- 파일 생성시에 보면 다음 이미지와 같이 2가지 파일중 하나를 생성해야 한다.<br>
![img.png](./캡쳐/Razor설정.png)
- 선택하는 항목에 따라 생성되는 파일의 종류가 달라지게 된다.
1. Blazor 구성요소: .razor
2. Razor 페이지 : .cshtml
- 둘 다 ASP.NET 기반의 웹 개발에서 사용되는 뷰 파일이지만, Blazor와 ASP.NET Core MVC/Razor Pages 라는 서로 다른 기술 스택에서 사용된다.
- 둘의 주된 차이점은 기술 스택과 사용 목적, 구성방식에 있다.
#### 1. .razor 파일
- Blazor에서 사용되는 C# 기반의 컴포넌트 파일로 C#을 이용해 UI를 구성하고 상호작용을 처리하는 SPA(Single Page Application)프레임워크이다.
- Blazor WebAssembly 와 Blazor Server에서 모두 사용되며 `클라이언트와 서버 모두` C# 코드로 UI를 처리할 수 있는 방식이다.
<br>
#### 특징
- C#과 HTML을 함께 사용해 UI를 정의한다.
- 동적 UI를 클라이언트에서 C#으로 처리 할 수 있다. - 브라우저 실행 C# 코드로 이벤트 처리 및 데이터 바인딩이 가능하다.
- 양방향 데이터 바인딩을 지원하고, 상태 변경시 UI가 자동 갱신되는 상태 관리 및 데이터 바인딩을 할 수 있다.
- 클라이언트와 서버 측 모두 사용가능하다.
- SPA 방식의 웹 애플리케이션에서 주로 사용한다.
#### 2. .cshtml 파일
- ASP.NET Core MVC/Razor Pages 에서 사용되는 `서버 측`뷰 파일이다.
- Razor 구문을 사용해 C#과 HTML을 함께 작성하며 주로 서버에서 랜더링된 HTML 페이지를 클라이언트에 전송하는데 사용한다.
<br>
#### 특징
- 클라이언트에서 요청이 오면 서버에서 HTML 페이지가 완성되어 브라우저로 전송된다.
- HTML 과 C#을 섞어서 작성할 수 있는 Razor 구문을 사용한다.
- 주로 전통적인 페이지 기반 웹사이트에 사용된다. 페이지 단위로 전체 페이지를 다시 로드한다.
- JS 와 함께 클라이언트 측 동작을 처리할 수 있다.
#### 3. 결론
- JS 도 모르고 서버와 클라이언트 양쪽을 전부 컨트롤 할 것이기에 1의 razor 파일로 하는 Blazor를 사용한다.
---
## 구성 요소
- Blazor 앱은 `구성요소`를 기반으로 동작한다.
- 구성요소를 기반으로 동작한다는 것은 애플리케이션을 독립적이고 재사용 가능한 작은 단위인 `Components(구성요소)`로 나누어 개발한다는것을 의미한다.
- 이러한 접근 방법은 웹 개발에서 많이 사용하는 방식이다.
- 일반적으로 구성 요소 클래스는`.razor` 파일 확장자를 가진 Razor 태그 페이지 형식으로 작성된다.
- 공식적으로는 `Razor 구성요소`라고 하지만 비공식적으로는 `Blazor 구성요소`라고 한다.
- 생산성을 위해 설계된 HTML 과 C# 코드를 결합하는 구문으로 IntelliSense를 통한 동일 파일 내 HTML 과 C#간 전환이 가능하다.
## 전체 스택 웹앱 빌드
### Blazor Web Apps
- 단일 솔루션에서 서버 및 전체 클라이언트 쪽 대화 작업을 포함하는 구성 요소 기반 아키텍쳐를 제공한다.
- 요청에 대한 응답으로 서버에서 HTML 콘텐츠를 렌더링해 브라우저에 UI 신속 제공할 수 있다.
- JS 다운 필요 없이 서버에서 UI 렌더링이 가능함
- 브라우저와 실시간 연결을 통해 서버에서 UI 상호작용을 치리하는 대화형 SSR(Server Side Rendering)을 지원한다.
- 대화형 SSR을 사용하면 클라이언트 앱에서 기대하는 것처럼 풍부한 사용자 환경을 제공하면서 서버 리소스에 액세스하기 위해 API 엔드포인트를 만들 필요가 없다.
> ### 대화형 SSR(Server Side Rendering)
> - 서버에서 웹 페이지를 렌더링하고 클라이언트와의 상호작용을 시기간으로 처리하는 방식을 의미
> - 여기서는 Blazor Server 모델을 통해 구현한다.
> - 서버에서 구성요소를 렌더링하고, 클라와의 상호작용은 SignalIR을 통해 실시간으로 처리한다.
> #### 개념
> 1. SSR
> - 서버에서 HTML 생성해 클라에 전달
> - 초기 페이지 로드가 빠르고 SEO에 유리
> 2. 대화형
> - 페이지 로드후에도 사용자와 상호작용이 실시간 처리됨
- 앱을 사용해 다운로드할 수 있는 `WebAssembly`로 빌드된 .NET 런타입을 사용하는 CSR(Client Side Rendering)을 사용해 대화형 작업을 지원한다.
- WebAssembly에서 실행하는 Blazor의 경우 .NET 코드는 브라우저의 전체 기능에 엑세스하고 JS와 상호 운용가능하다.
## Blazor Hybrid 사용한 네이티브 클라이언트 앱
- .NET MAUI를 사용해 .NET Multi-platform App UI 빌드된다.
---
# 실습
## 1. Todo 페이지 만들기
- Pages 디렉토리에 Todo.razor 파일을 생성
```csharp
// Todo.razor
@page "/Todo"
@rendermode InteractiveServer
<PageTitle>Todo</PageTitle>
<h1>Todo</h1>
@code {
}
```
- 해당 코드 NavMenu.razor 에 추가
```html
<div class="nav-item px-3">
<NavLink class="nav-link" href="todo">
<span class="oi oi-list-rich" aria-hidden="true"></span> Todo
</NavLink>
</div>
```
- 루트 디렉토리에 `TodoItem.cs` 파일 생성
- Todo 페이지에서 사용할 투두 목록 아이템 클래스 설정
```csharp
namespace BlazorApp;
public class TodoItem
{
public string? Title { get; set; }
public bool IsDone { get; set; }
}
```
- `Todo.razor` 파일에 코드 추가
- 화면에 리스트에 써줄 TextField 와 버튼 만들어줌
- Txf에 값 넣고 버튼 클릭시 리스트에 값 추가
- 리스트에 아이템을 추가 하기 위해서 @code에 c# 동작코드 입력
```csharp
<ul>
@foreach (var todo in todos)
{
<li>@todo.Title</li>
}
</ul>
<input placeholder="Something TODO" @bind="newTodo"/>
<button @onclick = "AddTodo">Add Todo</button>
@code {
private List<TodoItem> todos = new();
private string? newTodo;
private void AddTodo()
{
if (!string.IsNullOrWhiteSpace(newTodo))
{
todos.Add(new TodoItem { Title = newTodo });
newTodo = string.Empty;
}
}
}
```
- Todo.razor 에 조금 더 코드 추가
- 투두 생성 시 완료 안되어있으면 카운터 하는 기능과
- 완료 체크박스 그리기
```csharp
<h1>Todo (@todos.Count(todo => !todo.IsDone))</h1>
<ul>
@foreach (var todo in todos)
{
<li>
<input type="checkbox" @bind="todo.IsDone"/>
@todo.Title
</li>
}
</ul>
```
---
## 2. 영화 데이터베이스 페이지 만들기
-

View File

@ -0,0 +1,193 @@
안녕하세요! 이미 탄탄한 개발 배경과 C# 기본기를 갖추고 계시니, .NET Core, WebAssembly, Blazor, 그리고 Entity Framework 6(EF6)를 효과적으로 학습하실 수 있을 것입니다. 아래에 단계별로 구체적인 학습 방향과 방법을 제안드리겠습니다.
## **1. .NET Core 심화 학습**
### **목표:**
.NET Core의 구조와 기능을 깊이 이해하고, 다양한 프로젝트를 설정하고 관리할 수 있는 능력 배양.
### **학습 내용:**
- **.NET Core의 구조와 구성 요소 이해**
- .NET Core와 .NET Framework의 차이점
- 런타임, 라이브러리, SDK의 역할
- **프로젝트 설정 및 관리**
- CLI(Command Line Interface)를 사용한 프로젝트 생성 및 관리
- 프로젝트 파일(.csproj) 구조와 설정
- **종속성 관리**
- NuGet 패키지 관리
- 의존성 주입(Dependency Injection) 이해 및 활용
- **.NET Core CLI 사용법**
- 빌드, 실행, 테스트 명령어 숙지
### **추천 자료:**
- [Microsoft .NET Core 공식 문서](https://docs.microsoft.com/ko-kr/dotnet/core/)
- **온라인 강좌**:
- Udemy: ".NET Core를 이용한 실전 프로젝트"
- Pluralsight: ".NET Core Fundamentals"
### **학습 방법:**
- 공식 문서를 체계적으로 읽고, 주요 개념을 정리하세요.
- 간단한 콘솔 애플리케이션과 라이브러리를 만들어보며 .NET Core의 기능을 실습하세요.
- CLI를 활용하여 프로젝트를 생성하고 관리해보세요.
## **2. ASP.NET Core 웹 개발**
### **목표:**
ASP.NET Core를 사용한 웹 애플리케이션 개발 능력 배양.
### **학습 내용:**
- **MVC 패턴 이해 및 구현**
- 모델(Model), 뷰(View), 컨트롤러(Controller)의 역할과 상호작용
- **라우팅 및 미들웨어**
- 요청 처리 파이프라인 구성
- 커스텀 미들웨어 작성
- **의존성 주입(Dependency Injection)**
- 서비스 등록 및 주입 방법
- **보안 및 인증**
- 인증(Authentication)과 권한 부여(Authorization) 개념
- JWT(Json Web Token) 활용
### **추천 자료:**
- [ASP.NET Core 공식 문서](https://docs.microsoft.com/ko-kr/aspnet/core/)
- **온라인 강좌**:
- Udemy: "ASP.NET Core MVC - 실전 웹 애플리케이션 개발"
- Microsoft Learn: "ASP.NET Core 웹 애플리케이션 구축"
### **학습 방법:**
- MVC 패턴을 적용한 간단한 웹 애플리케이션을 만들어보세요.
- 미들웨어를 활용하여 요청 처리 과정을 커스터마이징해보세요.
- 인증과 권한 부여를 구현하여 보안 기능을 추가해보세요.
## **3. Entity Framework 6(EF6) 학습**
### **목표:**
EF6를 사용한 데이터베이스 연동 및 ORM(Object-Relational Mapping) 개념 이해.
### **학습 내용:**
- **EF6 개요 및 설치**
- EF6의 구조와 특징
- NuGet 패키지를 통한 EF6 설치
- **코드 퍼스트(Code-First) 접근법**
- 모델 클래스 정의 및 데이터베이스 생성
- **데이터베이스 퍼스트(Database-First) 접근법**
- 기존 데이터베이스를 EF6 모델로 변환
- **CRUD 연산 구현**
- Create, Read, Update, Delete 작업
- **고급 기능**
- 관계 설정, 지연 로딩(Lazy Loading), 병합(Migrations) 등
### **추천 자료:**
- [Entity Framework 6 공식 문서](https://docs.microsoft.com/ko-kr/ef/ef6/)
- **온라인 강좌**:
- Udemy: "Entity Framework 6 - 심화 학습"
- Pluralsight: "EF6: Getting Started"
### **학습 방법:**
- 간단한 데이터베이스와 연동되는 애플리케이션을 만들어보세요.
- 코드 퍼스트와 데이터베이스 퍼스트 접근법을 모두 실습해보세요.
- 복잡한 관계 설정과 고급 기능을 적용하여 데이터 모델을 확장해보세요.
## **4. WebAssembly 및 Blazor 학습**
### **목표:**
WebAssembly의 개념을 이해하고, Blazor를 사용하여 클라이언트 사이드 웹 애플리케이션 개발 능력 배양.
### **학습 내용:**
#### **A. WebAssembly 기본 이해**
- **WebAssembly 개요**
- WebAssembly의 목적과 장점
- JavaScript와의 상호운용성
- **.NET과 WebAssembly**
- Blazor WebAssembly의 작동 원리
#### **B. Blazor 학습**
- **Blazor의 종류**
- Blazor Server vs. Blazor WebAssembly
- **컴포넌트 기반 개발**
- Razor 컴포넌트 작성
- 재사용 가능한 컴포넌트 설계
- **데이터 바인딩 및 이벤트 처리**
- 양방향 데이터 바인딩
- 이벤트 핸들링
- **라우팅 및 네비게이션**
- 페이지 간 이동과 라우팅 설정
- **상태 관리**
- 상태 유지 및 공유 방법
- **서비스 및 의존성 주입**
- Blazor에서의 서비스 등록과 주입
- **호스팅 및 배포**
- Blazor 애플리케이션 배포 방법
### **추천 자료:**
- [Blazor 공식 문서](https://docs.microsoft.com/ko-kr/aspnet/core/blazor/)
- **온라인 강좌**:
- Udemy: "Blazor - 실전 웹 애플리케이션 개발"
- Pluralsight: "Building Web Applications with Blazor"
### **학습 방법:**
- Blazor Server와 Blazor WebAssembly의 차이점을 이해하고, 각각의 예제 프로젝트를 만들어보세요.
- Razor 컴포넌트를 작성하고, 다양한 UI 요소를 구현해보세요.
- 상태 관리와 의존성 주입을 활용하여 복잡한 애플리케이션 구조를 설계해보세요.
- 실제 배포 과정을 통해 호스팅 환경에 배포해보세요.
## **5. 종합 프로젝트 수행**
### **목표:**
학습한 모든 기술을 통합하여 실제로 동작하는 애플리케이션을 개발함으로써 실무 능력 향상.
### **프로젝트 제안:**
- **할 일 목록(To-Do List) 애플리케이션**
- 사용자 인증 기능
- CRUD 기능을 통한 할 일 관리
- Blazor를 사용한 실시간 UI 업데이트
- **블로그 플랫폼**
- 게시글 작성, 수정, 삭제 기능
- 카테고리 및 태그 관리
- 댓글 기능 및 실시간 알림
### **학습 방법:**
- 프로젝트 기획 단계에서 요구사항을 정의하고, 설계도를 작성하세요.
- .NET Core와 ASP.NET Core를 사용하여 백엔드 API를 구현하세요.
- Entity Framework 6를 사용하여 데이터베이스와 연동하세요.
- Blazor를 사용하여 프론트엔드 UI를 개발하세요.
- 프로젝트를 GitHub 등에 배포하고, 버전 관리를 철저히 하세요.
## **6. 추가 학습 및 심화**
### **목표:**
학습한 기술을 더욱 심화시키고, 최신 트렌드와 베스트 프랙티스를 습득.
### **학습 내용:**
- **테스트 주도 개발(TDD)**
- 단위 테스트, 통합 테스트 작성
- xUnit, NUnit 등 테스트 프레임워크 활용
- **CI/CD 파이프라인 구축**
- GitHub Actions, Azure DevOps 등을 사용한 자동화 배포
- **클라우드 서비스 연동**
- Azure, AWS, GCP 등 클라우드 플랫폼을 활용한 애플리케이션 배포 및 관리
- **성능 최적화**
- 애플리케이션 성능 분석 및 최적화 기법
### **추천 자료:**
- [Microsoft Learn: 테스트 및 배포](https://docs.microsoft.com/ko-kr/learn/)
- **온라인 강좌**:
- Udemy: "ASP.NET Core와 Azure를 활용한 CI/CD 파이프라인 구축"
- Pluralsight: "Blazor 고급 기능 및 최적화"
### **학습 방법:**
- 단위 테스트와 통합 테스트를 작성하여 코드 품질을 유지하세요.
- CI/CD 파이프라인을 구축하여 자동화된 빌드 및 배포 과정을 경험하세요.
- 클라우드 서비스를 활용하여 애플리케이션을 배포하고, 실시간 모니터링을 설정하세요.
- 성능 분석 도구를 사용하여 애플리케이션의 병목 지점을 찾아 최적화하세요.
## **학습 팁**
1. **프로젝트 기반 학습**: 이론을 학습하면서 동시에 작은 프로젝트를 진행하세요. 실제로 코드를 작성하고 문제를 해결하는 과정에서 많은 것을 배우게 됩니다.
2. **커뮤니티 참여**: Stack Overflow, GitHub, .NET 관련 포럼 등에 적극적으로 참여하여 질문하고, 다른 사람의 코드를 리뷰하며 학습하세요.
3. **문서화와 노트 정리**: 학습한 내용을 정리하고 문서화하면 복습할 때 유용합니다. 블로그에 글을 작성해보는 것도 좋은 방법입니다.
4. **꾸준한 연습**: 매일 일정 시간을 할애하여 코딩하고, 새로운 기술을 실습하세요. 꾸준함이 실력을 키우는 데 중요합니다.
5. **피드백 받기**: 작성한 코드를 다른 개발자와 공유하고 피드백을 받아 개선하세요. 코드 리뷰를 통해 더 나은 코딩 습관을 형성할 수 있습니다.
## **결론**
이미 다양한 개발 경험과 기본기를 갖추고 계신 만큼, .NET Core와 Blazor, EF6를 체계적으로 학습하신다면 빠르게 실력을 향상시킬 수 있을 것입니다. 제안드린 단계별 학습 방법을 따라가며, 실습과 프로젝트를 통해 이론을 실제로 적용해보세요. 학습 과정에서 궁금한 점이나 어려운 부분이 생기면 언제든지 질문해 주세요. 성공적인 학습과 개발 여정을 응원합니다! 화이팅하세요!

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB