mini-web-server
mini-web-server copied to clipboard
Support Razor in Mvc
Mvc sẽ sử dụng một phiên bản thu gọn của Asp.Net Core Razor, các tính năng được hỗ trợ bao gồm:
- Nhúng các đoạn code C# sử dụng cú pháp: @() (dùng cho biểu thức) hoặc @{} (dùng cho khối lệnh).
- Định nghĩa kiểu của Model sử dụng cú pháp @model
. - Cho phép sử dụng using với cú pháp @using
- Hỗ trợ DI sử dụng cú pháp @inject
- Hỗ trợ các đối tượng ViewBag và ViewData.
- Hỗ trợ Layout view (tham khảo: https://learn.microsoft.com/en-us/aspnet/core/mvc/views/layout?view=aspnetcore-7.0)
Các bước thực thi về cơ bản sẽ như sau:
- Mvc middleware dịch mã razor thành một file C#.
- Dùng Roslyn để dịch thành một Assembly.
- Load assembly vào bộ nhớ và khởi tạo một object.
- Gọi hàm InvokeAsync trên object đó.
- Lấy kết quả trả về và tạo một ViewResultStreamContent.
- Đưa content object vào response, đặt HTTP phù hợp (200 OK) và trả về cho Mini-Web-Server.
File minirazor chúng ta cần dịch sang C# sẽ tương tự như sau:
@model RazorTest.Model.TestModel
@using RazorTest.Utils
@inject RazorTest.TimeService TimeService
<html>
<head>
<title>
Mini Razor Test 1
</title>
</head>
Hello Mini Razor @(" world")!
@{
int second = DateTime.Now.Second;
int s100 = 100 * second;
}
<b>100 * @(second) = @(s100.ToString())</b>
Model.TotalValue = @(RazorTestUtils.ToMoneyString(@(Model.TotalValue)))
</html>
Sẽ được dịch ra dạng như sau:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using RazorTest.Utils;
public class MiniRazorView__[x]: MiniRazorView // [x] is a string identifying which view
{
private readonly RazorTest.Model.TestModel __model;
private Model => __model;
private readonly RazorTest.TimeService TimeService;
public MiniRazorView__[x] (IServiceProvider serviceProvider, RazorTest.Model.TestModel model) {
__model = model;
TimeService = serviceProvider.GetRequiredService<RazorTest.TimeService>();
}
public override void GenerateContent(StringBuilder sb)
{
sb.Append(@"
<html>
<head>
<title>
Mini Razor Test 1
</title>
</head>
Hello Mini Razor ");
sb.Append(" world");
sb.Append(@"!
");
int second = TimeService.GetNow().Second;
int s100 = 100 * second;
sb.Append(@"
<b> 100 * "); sb.Append(second); sb.Append(@" = "); sb.Append(s100.ToString()); sb.Append(@"</b>
Model.TotalValue = "); sb.Append(RazorTestUtils.ToMoneyString(@(Model.TotalValue)));
sb.Append(@"
</html>");
}
}
MiniRazorView needs some IMiniAppContext components, so you can access them from your script:
private readonly IMiniAppContext __context;
public MiniRazorView__[x] (IMiniAppContext context, IServiceProvider serviceProvider, RazorTest.Model.TestModel model) {
__context = context;
__model = model;
TimeService = serviceProvider.GetRequiredService<RazorTest.TimeService>();
}
protected IHttpRequest Request => context.Request;
protected IHttpResponse Response => context.Response;
protected ISession Session => context.Session;
protected ClaimsPrincipal? User => context.User;
we should also support comments using @* *@