본문 바로가기

C#/근웹 연대기

c#으로 근본 없는 웹서버 개발기 29 : cshtml - html로 전송

⚠WARNING
ASP.NET에 대한 포스팅이 아닙니다
나가실 문은 오른쪽 하단입니다

 

 

cshtml은 최종적으로 html로 변환되어 전송된다. 

즉 c#으로 작성된 내용은 클라이언트로 노출되지 않으니 cshtml에 다소 보안에 민감한 내용을 적어도 안심이 될것이다. (페이지 자체가 전송될 일은 없으므로...)

 

다음 코드는 이전글에서 작성한 Assembly 객체를 이용하여  View 객체를 생성하고 그것이 html을 만든다.

    public void Render(string name, JO ViewData = null, int? statusCode = null)
    {
        Status(statusCode);
        var className = View.GetClassName("Views/cshtml/" + name + ".cshtml");
        var type = viewAsm.GetType("Views." + className);
        var view = Activator.CreateInstance(type, this, ViewData, ViewBag, req.TempData) as View;
        var html = view.GetHTML();

        var header = new StringBuilder(100);
        var bodyData = Encoding.UTF8.GetBytes(html);

        header.AddL("HTTP/1.1 " + SCodeStr);
        header.AddL("date: " + Util.UTime);
        header.AddL("Server: test server");
        header.AddL("Content-type:text/html; charset=UTF-8");
        header.AddL("Content-Length: " + bodyData.Length);
        header.AddL("Connection: close");

        ToClient(header, bodyData);
    }

 

과거에 언급이 없던 파라미터인 ViewBag은 단순히 멤버객체로 System.Dynamic.ExpandoObject의 인스턴스이다.

그리고 req.TempData는 이전글에서 부록으로 나온 TempJO의 인스턴스로 세션값에 등록 되어 유지가 되는 객체이다.

 

 

다음 코드는 위의 내용을 호출하는 부분이다.

var app = new Express();
app.Get("/test/cshtml", (req, res) =>
{
    res.ViewBag.MyBag = "MyBag is Empty";
    if (!req.TempData.Has("cnt")) req.TempData["cnt"] = 0;

    req.TempData["cnt"] = (int)req.TempData.Peek("cnt") + 1;

    res.Render("test2", J.O(("title", "Hello Title")));
});

Express 대한 자세한 내용은 :

2022.01.05 - [C#/근웹 연대기] - c#으로 근본 없는 웹서버 개발기 16 : node express?

 

 

그리고 test2.cshtml의 내용이다

@using System.Linq;
@layout("Views/cshtml/layout.cshtml")
@{ //한글은 왜?
    string str = $"hello section";
    int[] arr = new[] { 1, 2, 3 ,4,5,6};
}
<div width= "500">
    <h1>@TempData["cnt"]</h1>
    <h2>@ViewBag.MyBag</h2>
    @foreach (var item in arr) @item
</div>
<script>
    let ss = "ggg"
</script>
   
@section testsec{
    <h2>test section</h2>
    <h1>@str</h1>
    @if(arr.Length>0){

    }else{

    }
}

@layout 는 내멋대로식 표현법으로 Views/cshtml/layout.cshtml는 이전글의 layout이다. 

 

CS파일로 다음과 같이 자동 생성된다.

using dotweb;
using System.Linq;

namespace Views;
//--------------------------------------------
// <auto-generated>                          
//     This code was generated by a tool.    
// </auto-generated>                          
//--------------------------------------------
public class Views_cshtml_test2 : View
{
    public Views_cshtml_test2(Response res, JO ViewData, dynamic ViewBag, TempJO TempData) :
        base(res, ViewData, (object)ViewBag, TempData) { }
    public Views_cshtml_test2(View child) : base(child) { }

    public override string GetHTML()
    {
        Layout = "Views/cshtml/layout.cshtml";
W(@"

");
    string str = $"hello section";
    int[] arr = new[] { 1, 2, 3 ,4,5,6};
W(@"
<div width= "500">
    <h1>"+TempData["cnt"]+@"</h1>
    <h2>"+ViewBag.MyBag+@"</h2>
    ");foreach (var item in arr) W(item);W(@"
</div>
<script>
    let ss = "ggg"
</script>
   
");
SetSection("testsec");
W(@"
    <h2>test section</h2>
    <h1>"+str+@"</h1>
    ");if(arr.Length>0){

    }else{

    }W(@"
");
OffSection("testsec");
W(@"

");
        if (Layout == null) return GetW();
        var type = Type.GetType("Views." + GetClassName());
        return (Activator.CreateInstance(type, this) as View).GetHTML();
    }
}

 

프로젝트를 실행하여 해당 URL로 접속하면 브라우저에 다음과 같이 표시된다.

레이아웃 페이지 안에 본문이 들어가 있다.

...

이것으로 렌더링 및 cshtml 파트는 끝이다.

이 카테고리의 내용자체도 이제 더 쓸 내용이 남아 있지않다.

 

아참, 한가지. 자체 RDBMS를 개발하여 연결한다는 계획이 남아 있긴한데, 지금 당장 준비된 부분이 없어서 다음 포스팅까지는 상당한 정체기가 있을거같다. 

DB연동 자체는 거창한 것이 아니고 한페이지면 설명이 끝나는 거라 실질적으로 마무리라고 봐도 무방하다.

 

그럼 Adious~!