ASP.NET Core之Razor Page相关

cshtml一般是这样:

@page 
@model IndexModel
@{
    ViewData["Title"] = "Home page";
}

<div class="text-center">
    <h1 class="display-4">Welcome</h1>
    <p>Learn about <a href="https://learn.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
</div>

@page是引导性的声明,表明是一个Page页面,并且是默认路由,即以在Pages文件夹的相对位置来进行路由匹配。
后面也可以跟路由参数,如:

@page "/johnyangtest/{id}"
@model RazorTest.Pages.TestModel
@{
    
}
<p>This is Test...,IDD is @Model.IDD</p>

上面 @page后面加\,表明是绝对路径,即不管该cshtml放在哪里,都是访问https://xxxx:xxx/johnyangtest/xx,就访问到这个页面了。

@model是背后的ViewModel数据类
@{}可以写不写入Response的C#代码

@page 
@model IndexModel
@{
    ViewData["Title"] = "Home page";
}
@{
    Console.WriteLine("Hello world johnyang test");//又多写了一个
}
<div class="text-center">
    <h1 class="display-4">Welcome</h1>
    <p>Learn about <a href="https://learn.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
</div>

生成URL

(1)用PageModel自带的Url属性的Page方法(对于MVC,就用其Action()方法),只需要传入相对于Pages的相对文件就行,不论相对文件中的@page后面加没有加特定指定。

@page "/johnyangtestrazor/{id}"
@model RazorTest.Pages.TestModel
@{
    
}
<p>This is Test...,IDD is @Model.IDD</p>

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace RazorTest.Pages
{
    public class TestModel : PageModel
    {
        public int IDD;
        public void OnGet(int id)
        {
            IDD = id;
            var url = Url.Page("Test", new {id=12345});
        }
    }
}

(2)用LinkGenerator来产生URL
LinkGenerator需要提供更多参数来唯一定义需要产生的URL,这使得它更灵活,另外它可以用在程序的任意地方,这一点不同于IUrlHelper(只能用在request的Context中)。

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using System.Runtime.CompilerServices;

namespace RazorTest.Pages
{
    public class TestModel : PageModel
    {
        public int IDD;
        private readonly LinkGenerator _link;
        public TestModel(LinkGenerator linkGenerator)
        {
            _link = linkGenerator;
        }
        public void OnGet(int id)
        {
            IDD = id;
            var url = Url.Page("Test", new {id=12345});
            var url1 = _link.GetPathByPage(HttpContext, "Test");
            var url2 = _link.GetPathByPage("Test");
            var url3 = _link.GetUriByPage("Test", null, null, "https", new HostString("johnyang.site"));
            Console.WriteLine(url);
            Console.WriteLine(url1);
            Console.WriteLine(url2);
            Console.WriteLine(url3);
        }
    }
}


using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using System.Runtime.CompilerServices;

namespace RazorTest.Pages
{
    public class TestModel : PageModel
    {
        public int IDD;
        private readonly LinkGenerator _link;
        public TestModel(LinkGenerator linkGenerator)
        {
            _link = linkGenerator;
        }
        public void OnGet(int id)
        {
            IDD = id;
            var url = Url.Page("Test", new {id=12345});
            var url1 = _link.GetPathByPage(HttpContext, "/Test");//使用当前HttpContext中的参数
            var url2 = _link.GetPathByPage("/Test", values: new {id=345});//自己指定参数
            var url3 = _link.GetUriByPage("/Test", null, values:new{ id=234}, "https", new HostString("johnyang.site"));
            Console.WriteLine(url);
            Console.WriteLine(url1);
            Console.WriteLine(url2);
            Console.WriteLine(url3);
        }
    }
}

Custormize Conventions With Razor Pages

//路由相关设置
builder.Services.Configure<RouteOptions>(o=>
{
    o.LowercaseUrls = true;
    o.LowercaseQueryStrings = true;
    o.AppendTrailingSlash = true;
});
//RazorPage相关设置
builder.Services.AddRazorPages().AddRazorPagesOptions(opt =>
{
    //opt.RootDirectory = "/MyPages";
    //opt.Conventions.AddPageRoute("/Test", "/johnyang-test");
});

AddPageRoute()添加了执行页面的另一个途径,并不是像@model那样,直接替换之前的路径。

下面的demo,给出了添加这样的路径,即统一在原有的URL之前加上"johnyangpage"。

public class PrefixingPageRouteModelConvention : IPageRouteModelConvention
{
    public void Apply(PageRouteModel model)
    {
        var selectors = model.Selectors.Select(selector => new SelectorModel
        {
            AttributeRouteModel=new AttributeRouteModel
            {
                Template=AttributeRouteModel.CombineTemplates("pagejohnyang",selector.AttributeRouteModel!.Template),
            }
        }).ToList();
        foreach(var newSelector in selectors)
        {
            model.Selectors.Add(newSelector);
        }
    }
}

 //RazorPage相关设置
 builder.Services.AddRazorPages().AddRazorPagesOptions(opt =>
 {
     //opt.RootDirectory = "/MyPages";
     //opt.Conventions.AddPageRoute("/Test", "/johnyang-test");
     opt.Conventions.Add(new PrefixingPageRouteModelConvention());
 });

因为是添加,所以之前的路径也可以使用:

几点建议:

* 避免对@page后直接使用绝对路径

* 避免对@page后添加字面量

* 尽可能在@page后面添加路由参数,使得路由具有动态性

* 避免使用`AddPageRoute()`

在Razor Pages中用页面handlers来产生响应

page handler的任务有三个:确认传入的请求是合法的;调用相应的逻辑处理代码;选择合适的返回类型来返回。
page handler一般返回下面三种类型:

  • PageResult,返回HTML
  • Void或Task 同上面
  • RedirectToPageResult 转页面。
    需要注意的是,page handler并不直接产生响应,而是选择响应的类型。
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace RazorTest.Pages
{
    //[IgnoreAntiforgeryToken(Order = 1001)]
    [IgnoreAntiforgeryToken]
    public class TestCModel : PageModel
    {
        public void OnGet()
        {
        }
        public void OnPost()
        {
            Console.WriteLine("This is Post");
        }

        public void OnPostJohnYang()
        {
             Console.WriteLine( "This is Post JohnYang");
        }

    }
}


@page "{handler?}"
@model RazorTest.Pages.TestCModel
@{
}

需要注意的是,这个demo需要忽略CSRF的防护。

posted @ 2024-01-21 10:55  JohnYang819  阅读(40)  评论(0编辑  收藏  举报