• Asp.net core 学习笔记 Razor Page


    更新 : 2021-06-24

    binding property 是不区分大小写的

    比如这样

    [BindProperty]
    public LoginDto LoginDto { get; set; } = null!;
    
    [BindProperty]
    public LoginDto LoginDTO { get; set; } = null!;

    前端全部小写, 上面 2 个 property 依然会 binding 到哦

    <form method="post">
        Name:
        <input name="logindto.username" /><br>
        Password:
        <input name="logindto.password" type="password" />
        <br>
        <input type="submit" />
    </form>

    更新: 2021-06-15

    razor page 返回 400, 500 page

    refer: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/error-handling?view=aspnetcore-5.0

    app.UseStaticFiles();
    app.UseStatusCodePagesWithReExecute("/error/{0}"); // must before UseRouting
    app.UseRouting();
    app.UseRequestLocalization();

    一般上是这样配置, 当 static files 或 routing match 不到的时候就会拦截到. 

    然后它就 clear 掉 response

    set Feature IStatusCodeReExecuteFeature

    换掉 path 在执行一次. 

    我的需求比较特别,因为我有做 amp, 如果用户访问的是 /amp 界面, 那么我得带它到 amp/error/404, 如果不是 amp 则是去 /error/404

    如果是用 mvc 就比较容易, 带去同一个 controller 然后 render 不同 view 就可以了。

    这就是 razor page 不好的地方了, 因为它是基于 page. 先找到 page 然后去弄 model, mvc 是先做 controller 才做 view, 顺序不太一样. 

    mvc = route -> controller (.cs) -> view (.cshtml)

    razor page = route -> page (.cshtml) -> model (.cs)

    所以我需要可以依据当前 request 判断是不是 amp 然后才去 change path. 

    当然这种鸟需求,它肯定是没有接口的了. 

    幸好可以直接抄源码来改, 维护幸苦一点而已. 还好啦.
     
    500 internal error page 当然也是同一个问题咯. 
    if (env.IsDevelopment())
    {
        // var db = serviceProvider.GetService<ApplicationDbContext>()!;
        // db.Database.Migrate();
        // app.UseDeveloperExceptionPage();
        app.UseDeveloperExceptionPage();
        app.UseMigrationsEndPoint();
    }
    else
    {
        // app.UseExceptionHandler("/error/500");
        app.UseExceptionHandler("/error/500");
        app.UseHttpsAndWww();
    }
    
    app.UseResponseCompression();
    app.UseStaticFiles();

    有 2 个地方源码要抄来改

    https://github.com/dotnet/aspnetcore/blob/main/src/Middleware/Diagnostics/src/ExceptionHandler/ExceptionHandlerExtensions.cs

    https://github.com/dotnet/aspnetcore/blob/main/src/Middleware/Diagnostics/src/ExceptionHandler/ExceptionHandlerMiddleware.cs

    改的地方很少而已,就是针对 reset request.path 的部分就 ok 了

    更新:

    get query string 

    public void OnGet(int id)
    {
    
    
    }

    如果我们只是写了这个, 那么 url 是 ?id=5 的时候 id = 5, 没有 id 的时候, id = 0 

    不管有没有 query param 都会匹配进入到这个 page 

    id 的大小写不重要

    另一种写法是用 binding, 效果是一样的

    [BindProperty(SupportsGet = true)]
    public int Id { get; set; }
    
    public void OnGet()
    {
    
    
    }

    那么如果是希望一定要有 query param id 才匹配的到 page 的话,那么需要在 route 写匹配比如 

     或者

    更新 : 2019-06-15 

    目前 razor page 在做 multiple form in one page 的时候有个大局限

    就是无法使用多个 BindProperty 

    一旦多个,那么任何一个 form 提交都会把所有 model 进行 valid 

    那就坏掉了

    refer : 

    https://stackoverflow.com/questions/48516547/how-to-implement-two-forms-with-separate-bindproperties-in-razor-pages

    https://stackoverflow.com/questions/54068385/razor-pages-model-validation-fails-due-to-multiple-objects-sharing-parameters

    没有去找 github issue 以后才看看吧。

    目前的做法就不要使用 BindProperty, 代价就是前端无法用 c# binding form. 

    更新 2019-04-27 

    最近做了更多的 research 发现微软视乎有意发展 razor page.

    razor page 的定位是 mvvm, 现在还有个叫 blazor 的东西, 类似用 c# + razor = react 的概念

    从前就觉得 react 的 jsx 和 razor 差不多嘛.. 估计微软会往哪里走. 

    好处应该挺多的,毕竟就目前的技术来看,如果要搞个体验好的电商项目,没有用前端框架是不行的. 

    如果后端框架可以支持更多交互体验,把实现都封装起来, 一定有些项目是非常适合的. 

    所以现在开始认真学 razor page 咯. 

    razor page 其实没有什么特别神奇的功能, 只是调用起来不一样而已. 

    首先, 它是用来处理 page 的, 就是那种返回 html 的 page. 

    wei api 不算, 返回 file 也不在它的管辖内.

    1. router 

    mvc <a asp-controller asp-action> 

    razor page <a asp-page asp-handler > , asp-page="Folder/File" 它是按路径的

    2. action binding 

    mvc [FromBody] [FromQuery]

    razor page 用的是 [BindProperty] , string value 匹配的是 query string 

    public class InputModel
    {
        public string code { get; set; }
    }
    
    [BindProperty]
    public InputModel data { get; set; }
    
    public void OnPost(string value)
    {
    
    }
    
    public void OnPostEdit(string value)
    {
    
    }

    refer : 

    https://www.twilio.com/blog/introduction-asp-net-core-razor-pages

    https://www.mikesdotnetting.com/article/327/customising-routing-conventions-in-razor-pages

    razor page vs MVC 

    通常我们都是拿这 2 者做比较.

    mvc 的做法是

    route 匹配 controller action (一个 controller action 可以对多个 route template)

    由 action 方法的 parameter 接受 inputModel 然后返回 view model


    razor page 的做法是

    route 匹配一个文件 cshtml 文件. (一个文件也可以对多个 route template, 要在 startup 弄)

    这个文件有一个 .cs 对应, 你可以把它看成 controller

    它不用 parameter 来接受 inputModel 而是用自身属性 + attribute [BindProperty] 来表示.

    然后它本身的属性就是 viewmodel 了.

    多个 action 的做法是通过 onPostAbcHandler onPostxyzHandler 来实现的.

    玩玩了一下,觉得也没有特别高明之处. 尤其我的需求是要语言,需要一个文件对应多个 route template,这点并不给力.

    比较厉害的地方应该只有一个,就是 folder 结构可以喜欢怎样开就怎样开吧. 这点我觉得比 mvc + ViewLocationExpanders 还要好一点点啦.

    [BindProperty]
    public LoginDto LoginDto { getset; } = null!;

    [BindProperty]
    public LoginDto LoginDTO { getset; } = null!;
  • 相关阅读:
    [Delphi]ListView基本用法大全
    Delphi 数据类型列表
    什么是堆、栈?
    使用钩子函数[1]
    邻道干扰
    内存管理[1]
    c#中复制类提示“Resource”参数不支持重复项的解决办法
    转帖:IE对话框showModalDialog(模态)和showModelessDialog
    今日工作心得:一段用于验证的jQuery代码
    每个开发人员现在应该下载的十种必备工具
  • 原文地址:https://www.cnblogs.com/keatkeat/p/10770046.html
Copyright © 2020-2023  润新知