바위 ✊ 종이 ✋ 가위 ✌️

발행: (2026년 2월 15일 오전 04:46 GMT+9)
10 분 소요
원문: Dev.to

Source: Dev.to

WebForms Core란?

WebForms CoreElanat에서 만든 새로운 멀티플랫폼 기술로, 현대 프론트엔드 프레임워크와 경쟁하도록 설계되었습니다 – .NET Core에 포팅된 오래된 버전이 아닙니다.

예시: 가위 바위 보

이 예시는 WebForms Core를 사용한 완전 오프라인 구현입니다. 명령은 서버에 작성되며 클라이언트에 대한 동작을 선언합니다.

WebForms Core Games

Note: 예시의 HTML 출력은 서버 없이 오프라인에서 복사해 사용할 수 있습니다.

다른 서버‑구동 UI 시스템과 달리, WebForms Core의 서버는 HTML과 직접적인 관계가 없습니다; 상태가 없으며 완전히 눈이 멀어 있습니다. 이러한 “서버 눈멀음”은 여러 가지 이점을 제공합니다:

  • 유연성 – 서버는 서로 다른 뷰를 가진 다양한 클라이언트(웹, 모바일, 데스크톱)를 제공할 수 있습니다.
  • 확장성 – 서로 다른 팀이 서버와 클라이언트 측을 병렬로 작업할 수 있습니다.
  • 유지보수 용이 – 사이트 외관을 변경해도 서버 로직을 바꿀 필요가 없습니다.
  • 보안 – 데이터는 원시 형태로 전송되고 클라이언트는 필요한 것만 표시합니다.
  • 재사용성 – 내장 API를 여러 프로젝트에서 사용할 수 있습니다.

Golden sentence
서버가 눈이 먼 이유는 이해하지 못해서가 아니라;
볼 필요가 없기 때문에 눈이 멀었습니다.

HTML

@page
@controller RockPaperScissorsController

    WebForms Core Technology
    

    

바위 ✊ 종이 ✋ 가위 ✌️

Rock ✊
Paper ✋
Scissors ✌️

컴퓨터 선택:

게임 매치: 0

게임 승리: 0


## 서버 코드

```csharp
using CodeBehind;

public partial class RockPaperScissorsController : CodeBehindController
{
    public void PageLoad(HttpContext context)
    {
        WebForms form = new WebForms();

        form.SetCommentEvent("*", HtmlEvent.OnClick, "play");
        form.StartIndex("play");
        form.Increase("counter|", 1);
        form.AddSessionCacheValue("random", Fetch.Random(0, 3));
        form.SetText("result", "😢 You lose!");
        form.IsEqualTo(Fetch.GetAttribute("$", "win-with"), Fetch.Saved("random"));
        form.StartBracket();
        form.SetText("result", "😀 You win!");
        form.Increase("win-counter|", 1);
        form.EndBracket();
        form.IsEqualTo(Fetch.GetAttribute("$", "value"), Fetch.Saved("random"));
        form.SetText("result", "😐 Equal!");
        form.IsEqualTo("0", Fetch.Saved("random"));
        form.SetText("computer|", "Rock ✊");
        form.IsEqualTo("1", Fetch.Saved("random"));
        form.SetText("computer|", "Paper ✋");
        form.IsEqualTo("2", Fetch.Saved("random"));
        form.SetText("computer|", "Scissors ✌️");

        Write(form.ExportToHtmlComment());
    }
}

Result (HTML with embedded WebForms comment)

*=onclick|play|
#=play
gtcounter|=i|1
SA=random|@mr3,0
stresult=😢 You lose!
{et=@$a$,win-with|@csrandom
{
stresult=😀 You win!
gtwin-counter|=i|1
}
{et=@$a$,value|@csrandom
stresult=😐 Equal!
{et=0|@csrandom
stcomputer|=Rock ✊
{et=1|@csrandom
stcomputer|=Paper ✋
{et=2|@csrandom
stcomputer|=Scissors ✌️-->
    WebForms Core Technology
    

    

바위 ✊ 종이 ✋ 가위 ✌️

바위 ✊
종이 ✋
가위 ✌️

컴퓨터 선택:

게임 매치: 0

게임 승리: 0

예제 개요

이 예제는 JavaScript 비즈니스 로직을 작성하지 않고 완전하게 인터랙티브한 가위‑바위‑보 게임을 보여줍니다.

  • 모든 게임 로직은 서버에서 실행됩니다.
  • 브라우저는 깔끔하고 표준적인 HTML을 받습니다.
  • 가벼운 클라이언트 엔진이 선언적 지시를 실행합니다.
  • 상호작용 중 페이지 새로고침이 발생하지 않습니다.

HTML 섹션: 구조만, 로직 없음

HTML은 사용자 인터페이스만 정의합니다:

Rock ✊
Paper ✋
Scissors ✌️

핵심 포인트

  • value는 사용자의 선택을 나타냅니다.
  • win-with는 현재 선택을 이기는 옵션을 정의합니다.

서버‑사이드 선언적 동작 정의

서버에서 WebForms 객체를 생성하고 전체 페이지 동작을 선언적으로 정의합니다.

이벤트 바인딩

form.SetCommentEvent("*", HtmlEvent.OnClick, "play");

어떤 요소가 클릭될 때 play 라는 이름의 이벤트를 트리거합니다.

로직의 진입점

form.StartIndex("play");

이후의 모든 로직은 play 이벤트가 트리거될 때만 실행됩니다.

Game Logic – Step by Step

1. Increase the Match Counter

form.Increase("counter|", 1);

각 클릭마다 총 매치 수가 1씩 증가합니다.

2. Generate the Computer’s Choice

form.AddSessionCacheValue("random", Fetch.Random(0, 3));

무작위 값(0‑2)이 생성되어 세션에 저장됩니다.

3. Default Result – Loss

form.SetText("result", "😢 You lose!");

게임은 기본적으로 패배로 간주합니다. 이후 조건에 따라 결과가 바뀔 수 있습니다.

4. Check for User Win

If the clicked button’s win-with attribute matches the computer’s choice:

form.SetText("result", "😀 You win!");
form.Increase("win-counter|", 1);

결과가 업데이트되고 승리 카운터가 증가합니다.

5. Check for a Draw

If the button’s value matches the computer’s choice:

form.SetText("result", "😐 Equal!");

게임이 무승부로 끝납니다.

6. Display the Computer’s Choice

Random valueDisplayed text
0바위 ✊
1보 ✋
2가위 ✌️

최종 출력 – HTML 주석 안의 DSL

All server‑defined behavior is exported as a compact DSL and embedded into the HTML as a comment:

*=onclick|play|
#=play
gtcounter|=i|1
...
-->
  • 이 주석은 브라우저의 렌더링 엔진에 의해 무시됩니다.
  • 이 주석은 WebForms Core 클라이언트 엔진에 의해 파싱됩니다.
  • 부분적인 DOM 업데이트를 가능하게 하여 전체 페이지 새로고침을 방지합니다.
  • HTML을 깔끔하고 손대지 않은 상태로 유지합니다.

최종 결과

이 예시는 WebForms Core를 사용했을 때 다음을 보여줍니다:

  • HTML은 순수하게 구조만을 담당합니다 – JavaScript, 조건문, 이벤트 핸들러가 없습니다.
  • 모든 비즈니스 로직은 서버에서 처리됩니다.
  • JavaScript는 가벼운 실행 엔진 역할만 합니다.
  • UI 업데이트는 SPA 프레임워크 없이도 반응형으로 이루어집니다.

Rock‑Paper‑Scissors 데모는 현대적이고 상태를 유지하며 인터랙티브한 웹 애플리케이션을 구현하면서도 전통적인 HTML의 단순함과 명료함을 유지하는 방법을 보여줍니다.

이 예제가 증명하는 바는?

1. WebForms Core는 진정한 서버‑구동 UI

  • PostBack 없음, ViewState 없음.
  • 이벤트가 선언형처럼 동작합니다.
  • 상태는 서버에서 결정되어 클라이언트에 전송됩니다.
  • 논리적인 차이점만 클라이언트로 전송됩니다.

이는 현대 라이브 UI 철학과 밀접하게 일치합니다.

2. HTML이 완전히 깔끔하고 표준적임

Rock
  • 이상한 태그, 무거운 커스텀 속성, 혹은 지저분한 마크업이 없습니다.

결과

  • SEO 친화적
  • 점진적 향상
  • 프론트엔드 도구와 완전 호환

3. JavaScript 한 줄도 없이 작성된 게임 로직

  • 많은 현대 프레임워크에서는 JavaScript가 무겁거나 WebAssembly가 필요하거나 복잡한 빌드 파이프라인이 요구됩니다.
  • 여기서는 **모든 게임 로직이 C#**에 있으며, UI는 단순히 리스너 역할을 합니다.

이는 많은 사람들이 찾고 있던 핵심 포인트입니다.

4. 주석 안의 DSL – 예상치 못한 스마트한 접근

  • JSON도 없고, 인라인 스크립트도 없으며, 데이터 블롭도 없습니다.
  • 여전히 구문 분석 가능, 보안, 캐시 친화적, 그리고 브라우저에 보이지 않습니다.

이 설계는 기술에 대한 의식적이고 깊은 접근을 보여줍니다.

0 조회
Back to Blog

관련 글

더 보기 »

Server Components는 SSR이 아니다!

SSR vs. React Server Components 개발 세계에서 React Server Components(RSC)는 종종 또 다른 형태의 Server‑Side Rendering(SSR)으로 오해받는다. 두 가지 모두…