RazorPage:PageModel:从Model到Razor的传值

创建和引入

在创建Razor页面时的时候,如果勾选:
在这里插入图片描述
就可以看到,在.cshtml文件中,有这样的代码:

@model Demo.Pages.RegisterModel

RegisterModel上F12转到定义,可以知道RegisterModel其实是一个类,继承自PageModel

(演示:略)

注意其命名规范:类名同Page名,后加Model后缀

此外,注意:

  • 组合之后的page可以有多个@model声明,但只能有一个@page声明

Handler Methods

PageModel可以自定义的处理HTTP请求。

如果razor页面没有model声明,ASP.NET按默认设置直接输出.cshtml文件编译后的HTML内容;

否则,会进入Handler Mthods

PageModel根据 HTTP请求的方式(request methods)来确定调用方法:On+RequestMethod(),所以除了OnGet()方法,还有OnPost()方法等

OnGet()OnPost()

PageModel可以:按Http请求的Method不同,分别处理。

复习:GetPost

razor页面被添加的时候,其PageModel中就自动包含了一个OnGet()方法,这被称之为handler methods。用于处理HTTP GET请求。

因为在运行时,ASP.NET会在PageModel中选择调用OnGet()/OnPost()方法,所以一个PageModel中:

  • 可以同时有OnGet()OnPost()方法,但
  • 不可以有多个OnGet()方法(或者多个OnPost()方法等),用参数重载区分也不行(会运行时错误)
  • OnGet()OnPost()不用带参数

(演示)

RequestResponse

OnGet()方法中,因为继承了PageModel,所以可以调用PageModel的一些常用属性,如:

  • Request:Http请求相关信息,常用的有:Header/Body、Cookies、Form/Query、Path、Schema
  • Response:返回客户端的相应信息,常用的有:Header/Body、Cookies、StatusCode
  • ViewData:存储页面(View)所需要的数据(Data
  • HttpContext:当前请求的上下文信息,除了RequestResponse,还有Connection、Session、WebSocket等有用信息
  • ……

以及一些方法,比如:RedirectToPage(),用于重定向到某一个页面。

@想一想@:Request对象是怎么生成的?

SampleModel model = new SampleModel();  //反射
model.Request = new HttpRequest{ Header =  }
model.OnGet();

强调:一个注册过程,里面至少是两次请求
在这里插入图片描述
还有可能再加一个重定向(Redirect),后文详述。

其指定的

作为数据容器:在PagePageModel之间传递数据

Razor页面传递数据

方式(一)强类型

通过在Razor页面调用@Model,可以得到PageModel中的公共类成员(通常是属性)

public string Greet { get; } = "Hello, 源栈欢迎您!";
<h4>@Model.Greet</h4>

方式(二)弱类型

另外一种方法是使用ViewData[]

public void OnGet()
{
    ViewData["title"] = "注册";
}
<title>@ViewData["title"]</title>

注意:ViewData[]的优势是方便,但它是Object类型,且Key值没有智能提示,使用时需要格外注意

常见错误:NullReferenceException

public void OnGet()
{
    if (LogOnSuccess())
    {
        //其他代码……
        ViewData["Success"] = true;
    }
}
@if ((bool)ViewData["Success"])
{
    <h3>欧耶!成功登陆</h3>
}
else
{
    <h3 style="color:red;" >登录失败</h3>
}

背后原理

ViewData是哪里蹦出来的?(复习)

所有的页面数据存储在ViewData中,其中又分为两种形式:

  • 索引器:在PageModel.cshtml中都可以读/写(演示:_Layout使用内容页的ViewData["title"]

  • Model属性:
    如果说.cshtml文件标明了@page且指定了@modelViewData.Model就会(通过泛型)被设定为@model指定的实例对象;

     public class Pages_LogOn :
    global::Microsoft.AspNetCore.Mvc.RazorPages.Page {
       public LogOnModel Model => ViewData.Model; } 
    

    否则,ViewData.Model就会被编译成dynamic类型变量(布局页)或页面类型(奇怪?)

    public class Pages_Layout__All :global::Microsoft.AspNetCore.Mvc.Razor.RazorPage<dynamic> 
    
    public class Pages_Index :
    global::Microsoft.AspNetCore.Mvc.RazorPages.Page {
       public Pages_Index Model => ViewData.Model; } 
    

(演示:查看.cshtml编译后文件)

所以,在_Layout中使用内容页的数据,可以通过三种方式实现:

  • ViewData["Title"]:内容页赋值,_Layout直接使用
  • @Model.TitleTitlePageModel属性。因为是dynamic,所以没有智能提示哟
  • PageModel继承

为添加_Layout.cshtml添加一个_LayoutModel类,并在_Layout.cshtml页面引入

public class _LayoutModel : PageModel
{
    public string Title { get; set; }
}
@model Demo.Pages.Shared._LayoutModel

让内容页的Model继承自_LayoutModel,并在其中为Title赋值

public class IndexModel : _LayoutModel
{
    public void OnGet([Bind("invitedBy")]string invitedBy)
    {
        Title = "首页·一起帮";
        //ViewData["title"] = "首页·一起帮";
    }
}

演示:求助列表呈现

  • ProblemRepository.Get()模拟
  • 分页链接(传递和获取)
  • 显示当前第n页

告诉服务器:想要哪一页 pageIndex = 3

服务器再根据每一页呈现的数量 pageSize = 10 进行计算,呈现:21-30 条

计算公式:从(pageIndex-1)*pageSize+1开始,取pageSize

URL:/Article?pageIndex=3

后台OnGet()里面

int pageIndex = Convert.ToInt32(Request.Query["pageIndex"][0]);
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值