일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- 코드업100제
- 파이썬알고리즘
- 블레이저
- 데이터분석
- 자연어처리
- 파이썬기초100제
- 알고리즘
- 데이터사이언스
- 코드업
- 구글퀵랩
- nlp
- 코드업파이썬
- GenerativeAI
- attention
- Microsoft
- Blazor
- Python
- 파이썬
- 머신러닝
- 파이썬기초
- Azure
- 한빛미디어
- 클라우드
- 생성형AI
- 빅데이터
- C#
- DataScience
- gcp
- codeup
- GenAI
Archives
- Today
- Total
Tech for good
[Blazor, C#] Blazor WebAssembly Blog Series 5 본문
* 해당 영상을 공부하며 정리한 자료입니다.
https://www.youtube.com/playlist?list=PLF1jhYUTnHo5XFX9lgS0YsNSDJHpYnRxK
✔ 기본세팅
: Blazor WebAssembly, .Net6
✔ 학습목표
: Create 페이지를 생성하고 동작을 구현한다.
5. Forms, Validation & HTTP POST with Blazor WebAssembly
5.1. Create new component in Pages folder and Change some code in NavMenu.razor file
// BlazorBlog.Client/Pages/Create.razor
@page "/create"
<h3>Create a New Blog Post</h3>
// Add new controls or built-in components of blazor web assembly
<EditForm Model="@newBlogPost" OnValidSubmit="CreateNewBlogPost">
<button type="submit" class="btn btn-primary">Create</button>
</EditForm>
@code {
BlazorBlog.Shared.BlogPost newBlogPost = new BlazorBlog.Shared.BlogPost();
void CreateNewBlogPost()
{
Console.WriteLine("Create that blog post!");
}
}
// BlazorBlog.Client/Pages/Create.razor
@page "/create"
<h3>Create a New Blog Post</h3>
// Add new controls or built-in components of blazor web assembly
<EditForm Model="@newBlogPost" OnValidSubmit="CreateNewBlogPost">
<button type="submit" class="btn btn-primary">Create</button>
</EditForm>
@code {
BlazorBlog.Shared.BlogPost newBlogPost = new BlazorBlog.Shared.BlogPost();
void CreateNewBlogPost()
{
Console.WriteLine("Create that blog post!");
}
}
5.2. Add some components to the forms
// BlazorBlog.Client/Pages/Create.razor
@page "/create"
<h3>Create a New Blog Post</h3>
<EditForm Model="@newBlogPost" OnValidSubmit="CreateNewBlogPost">
<div class="form-group">
<label for="title">Title</label>
<InputText id="title" @bind-Value="newBlogPost.Title" class="form-control" />
</div>
<button type="submit" class="btn btn-primary">Create</button>
</EditForm>
@code {
BlazorBlog.Shared.BlogPost newBlogPost = new BlazorBlog.Shared.BlogPost();
void CreateNewBlogPost()
{
Console.WriteLine("Create that blog post!");
}
}
Title에 텍스트 입력 후, Create 버튼 누르면 Validate되어 입력창 테두리가 초록색으로 바뀜
// BlazorBlog.Client/Pages/Create.razor
@page "/create"
<h3>Create a New Blog Post</h3>
<EditForm Model="@newBlogPost" OnValidSubmit="CreateNewBlogPost">
<div class="form-group">
<label for="title">Title</label>
<InputText id="title" @bind-Value="newBlogPost.Title" class="form-control" />
</div>
<div class="form-group">
<label for="url">Url</label>
<InputText id="url" @bind-Value="newBlogPost.Url" class="form-control" />
</div>
<div class="form-group">
<label for="description">Description</label>
<InputText id="description" @bind-Value="newBlogPost.Description" class="form-control" />
</div>
<div class="form-group">
<label for="content">Content</label>
<InputTextArea id="content" @bind-Value="newBlogPost.Content" class="form-control" />
</div>
<div class="form-group">
<label for="date">Date</label>
<InputDate id="date" @bind-Value="newBlogPost.DateCreated" class="form-control" />
</div>
<div class="form-check">
<InputCheckbox id="isPublished" @bind-Value="newBlogPost.IsPublished" class="form-check-input" />
<label for="isPublished">Publish</label>
</div>
<button type="submit" class="btn btn-primary">Create</button>
</EditForm>
@code {
BlazorBlog.Shared.BlogPost newBlogPost = new BlazorBlog.Shared.BlogPost();
void CreateNewBlogPost()
{
Console.WriteLine("Create that blog post!");
}
}
마찬가지로 Url, Description, Content, Date, Publish 창도 생성한다.
5.3. Validation (Forms에 입력한 데이터 값을 db에 등록하는 것)
// BlazorBlog.Shared/BlogPost.cs
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BlazorBlog.Shared
{
public class BlogPost
{
public int Id { get; set; }
[Required, StringLength(20)]
public string Url { get; set; }
[Required]
// [Required] Attribute 추가 => 위의 텍스트 입력 후 빨간 줄 떴을 때 => ctrl + . 눌러서 using 구문 추가
public string Title { get; set; }
public string Content { get; set; }
public string Description { get; set; }
public string Author { get; set; }
public DateTime DateCreated { get; set; } = DateTime.Now;
public bool IsPublished { get; set; } = true;
public bool IsDeleted { get; set; } = false;
}
}
// BlazorBlog.Client/Pages/Create.razor
@page "/create"
<h3>Create a New Blog Post</h3>
<EditForm Model="@newBlogPost" OnValidSubmit="CreateNewBlogPost">
<DataAnnotationsValidator />
<div class="form-group">
<label for="title">Title</label>
<InputText id="title" @bind-Value="newBlogPost.Title" class="form-control" />
</div>
<div class="form-group">
<label for="url">Url</label>
<InputText id="url" @bind-Value="newBlogPost.Url" class="form-control" />
</div>
<div class="form-group">
<label for="description">Description</label>
<InputText id="description" @bind-Value="newBlogPost.Description" class="form-control" />
</div>
<div class="form-group">
<label for="content">Content</label>
<InputTextArea id="content" @bind-Value="newBlogPost.Content" class="form-control" />
</div>
<div class="form-group">
<label for="date">Date</label>
<InputDate id="date" @bind-Value="newBlogPost.DateCreated" class="form-control" />
</div>
<div class="form-check">
<InputCheckbox id="isPublished" @bind-Value="newBlogPost.IsPublished" class="form-check-input" />
<label for="isPublished">Publish</label>
</div>
<button type="submit" class="btn btn-primary">Create</button>
<ValidationSummary />
</EditForm>
@code {
BlazorBlog.Shared.BlogPost newBlogPost = new BlazorBlog.Shared.BlogPost();
void CreateNewBlogPost()
{
Console.WriteLine("Create that blog post!");
}
}
빈칸으로 둔 상태에서 Create 버튼 누르면 입력창 테두리가 빨간색으로 표시되며 하단의 경고 문구를 확인할 수 있다.
// BlazorBlog.Shared/BlogPost.cs
namespace BlazorBlog.Shared
{
public class BlogPost
{
public int Id { get; set; }
[Required, StringLength(20, ErrorMessage = "Please use only 20 characters.")]
public string Url { get; set; }
[Required]
public string Title { get; set; }
public string Content { get; set; }
public string Description { get; set; }
public string Author { get; set; }
public DateTime DateCreated { get; set; } = DateTime.Now;
public bool IsPublished { get; set; } = true;
public bool IsDeleted { get; set; } = false;
}
}
Custom Message도 입력하여 보여줄 수 있다.
// BlazorBlog.Client/Pages/Create.razor
@page "/create"
<h3>Create a New Blog Post</h3>
<EditForm Model="@newBlogPost" OnValidSubmit="CreateNewBlogPost">
<DataAnnotationsValidator />
<div class="form-group">
<label for="title">Title</label>
<InputText id="title" @bind-Value="newBlogPost.Title" class="form-control" />
<ValidationMessage For="@(() => newBlogPost.Title)" />
</div>
<div class="form-group">
<label for="url">Url</label>
<InputText id="url" @bind-Value="newBlogPost.Url" class="form-control" />
<ValidationMessage For="@(() => newBlogPost.Url)" />
</div>
<div class="form-group">
<label for="description">Description</label>
<InputText id="description" @bind-Value="newBlogPost.Description" class="form-control" />
</div>
<div class="form-group">
<label for="content">Content</label>
<InputTextArea id="content" @bind-Value="newBlogPost.Content" class="form-control" />
</div>
<div class="form-group">
<label for="date">Date</label>
<InputDate id="date" @bind-Value="newBlogPost.DateCreated" class="form-control" />
</div>
<div class="form-check">
<InputCheckbox id="isPublished" @bind-Value="newBlogPost.IsPublished" class="form-check-input" />
<label for="isPublished">Publish</label>
</div>
<button type="submit" class="btn btn-primary">Create</button>
<ValidationSummary />
</EditForm>
@code {
BlazorBlog.Shared.BlogPost newBlogPost = new BlazorBlog.Shared.BlogPost();
void CreateNewBlogPost()
{
Console.WriteLine("Create that blog post!");
}
}
ValidationMessage를 추가하면 각각의 입력창 아래에 메세지들을 확인할 수 있다.
https://docs.microsoft.com/en-us/aspnet/core/blazor/forms-validation?view=aspnetcore-6.0
// BlazorBlog.Client/Services/IBlogService.cs
namespace BlazorBlog.Client.Services
{
interface IBlogService
{
Task<List<BlazorBlog.Shared.BlogPost>> GetBlogPosts();
Task<BlazorBlog.Shared.BlogPost> GetBlogPostByUrl(string url);
// To return the blog posts
Task<BlazorBlog.Shared.BlogPost> CreateNewBlogPost(BlazorBlog.Shared.BlogPost request);
}
}
// BlazorBlog.Client/Services/BlogService.cs
namespace BlazorBlog.Client.Services
{
public class BlogService : IBlogService
{
private readonly HttpClient _http;
public BlogService(HttpClient http)
{
_http = http;
}
public async Task<BlogPost> CreateNewBlogPost(BlogPost request)
{
var result = await _http.PostAsJsonAsync("api/Blog", request);
return await result.Content.ReadFromJsonAsync<BlogPost>();
}
...
}
}
// BlazorBlog.Client/Pages/Create.razor
@page "/create"
@inject BlazorBlog.Client.Services.IBlogService BlogService
@inject NavigationManager NavigationManager
...
@code {
BlazorBlog.Shared.BlogPost newBlogPost = new BlazorBlog.Shared.BlogPost();
async Task CreateNewBlogPost()
{
var result = await BlogService.CreateNewBlogPost(newBlogPost);
NavigationManager.NavigateTo($"posts/{result.Url}");
}
}
5.4. Create a newBlogPost controller
// BlazorBlog.Server/Controllers/BlogController.cs
namespace BlazorBlog.Server.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class BlogController : ControllerBase
{
private readonly BlazorBlog.Server.Data.DataContext _context;
// Inject data context
public BlogController(BlazorBlog.Server.Data.DataContext context)
{
_context = context;
}
[HttpGet]
public ActionResult<List<BlazorBlog.Shared.BlogPost>> GiveMeAllTheBlogPosts()
{
return Ok(_context.BlogPosts);
}
[HttpGet("{url}")]
public ActionResult<BlazorBlog.Shared.BlogPost> GiveMeThatSingleBlogPost(string url)
{
var post = _context.BlogPosts.FirstOrDefault(p => p.Url.ToLower().Equals(url.ToLower()));
if (post is null)
{
return NotFound("This post does not exist.");
}
return Ok(post);
}
[HttpPost]
public async Task<ActionResult<BlazorBlog.Shared.BlogPost>> CreateNewBlogPost(BlazorBlog.Shared.BlogPost request)
{
_context.Add(request);
await _context.SaveChangesAsync();
return request;
}
}
}
위의 과정을 끝내고 Create 버튼을 누르면, 데이터가 db에 잘 저장이 된다!
※ 주의사항!!
.Net6의 경우, HTTP 통신할 때 객체에 null 값이 있으면 자동 HTTP 400 응답 에러를 뱉는다.
// BlazorBlog.Shared/BlogPost.cs
namespace BlazorBlog.Shared
{
public class BlogPost
{
public int Id { get; set; }
[Required, StringLength(20, ErrorMessage = "Please use only 20 characters.")]
// .NET6는 NULL 값 허용을 안해주기 때문에 아래와 같이 .Empty를 붙여줘야함!!
public string Url { get; set; } = String.Empty;
[Required]
public string Title { get; set; } = String.Empty;
public string Content { get; set; } = String.Empty;
public string Description { get; set; } = String.Empty;
public string Author { get; set; } = String.Empty;
public DateTime DateCreated { get; set; } = DateTime.Now;
public bool IsPublished { get; set; } = true;
public bool IsDeleted { get; set; } = false;
}
}
// BlazorBlog.Server/Program.cs
using BlazorBlog.Server.Data;
using Microsoft.AspNetCore.ResponseCompression;
using Microsoft.EntityFrameworkCore;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
// .NET6는 NULL 값 허용을 안해주기 때문에 해당 옵션을 추가해주어야함‼
builder.Services.AddControllersWithViews().ConfigureApiBehaviorOptions(options =>
{
options.SuppressModelStateInvalidFilter = true;
});
builder.Services.AddRazorPages();
builder.Services.AddDbContext<DataContext>(x => x.UseSqlite(builder.Configuration.GetConnectionString("DefaultConnection")));
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseWebAssemblyDebugging();
}
else
{
app.UseExceptionHandler("/Error");
// 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.UseBlazorFrameworkFiles();
app.UseStaticFiles();
app.UseRouting();
app.MapRazorPages();
app.MapControllers();
app.MapFallbackToFile("index.html");
app.Run();
Create 버튼을 누른 결과, 다음과 같은 화면을 확인할 수 있다!
db에도 데이터가 잘 추가되었음을 확인할 수 있다.
'IT > Computer Science' 카테고리의 다른 글
[파이썬/Python] CodeUp 파이썬 기초 100제 6065 - 6070 (0) | 2022.03.06 |
---|---|
[파이썬/Python] CodeUp 파이썬 기초 100제 6059 - 6064 (0) | 2022.02.27 |
[Blazor, C#] Blazor WebAssembly Blog Series 4 (0) | 2022.02.23 |
[Blazor, C#] Blazor WebAssembly Blog Series (1~3) (0) | 2022.02.23 |
[파이썬/Python] CodeUp 파이썬 기초 100제 6046 - 6058 (0) | 2022.02.20 |