如何将 MVC 操作和属性重写为 ASP Core MVVM Razor 页面

Posted

技术标签:

【中文标题】如何将 MVC 操作和属性重写为 ASP Core MVVM Razor 页面【英文标题】:How to rewrite MVC Actions & properties to ASP Core MVVM Razor Pages 【发布时间】:2018-02-22 22:47:46 【问题描述】:

在上个月的 ASP CORE 2.0 新版本中,他们引入了 Razor 页面,这让我陷入了困境,因为 ASP CORE 2 Razor 页面中缺少旧控制器和模型 frpm MVC。

我对此page 的理解是,我们在操作/方法之外使用[BindProperty] attribute 获得属性的默认绑定!!!!,这是因为它移动到MVVM framework 而不是MVC框架。

    问题:在尝试重写传统动作时,由于没有控制器,如何将代码移至新的RazorPages MVVM框架,即以及在哪里以及如何绑定属性和动作/处理程序? 由于属性没有在签名中,操作/处理程序如何知道哪些属性是从视图/Razor 页面传递给它的?

什么是 PageModel?

public class CreateModel : PageModel // what is this pagemodel, is it new or the same old model?

    private readonly AppDbContext _db;

    public CreateModel(AppDbContext db)
    
        _db = db;
    

    [BindProperty]
    public Customer Customer  get; set;  // why is the property outside?

    public async Task<IActionResult> OnPostAsync()
    
        if (!ModelState.IsValid)
        
            return Page();
        

        _db.Customers.Add(Customer);
        await _db.SaveChangesAsync();
        return RedirectToPage("/Index");
    

【问题讨论】:

【参考方案1】:

据我了解,Razor 页面几乎可以替代旧的 asp.net 表单,在旧的 asp.net 表单中,您只需拥有一个带有逻辑的页面。有点像php做事的方式。

如果您创建一个页面,比如说Pages/Index2.cshtml,您还应该创建(或者它可以在 Visual Studio 中为您创建)一个名为 Pages/Index2.cshtml.cs 的“代码隐藏”文件。

// The page file

@page
@using RazorPages
@model IndexModel2

<h2>Separate page model</h2>
<p>
    @Model.Message
</p>


// The code-behind file

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

namespace RazorPages

    public class IndexModel2 : PageModel
    
        public string Message  get; private set;  = "PageModel in C#";

        public void OnGet()
        
            Message += $" Server time is  DateTime.Now ";
        
    

您仍然可以拥有模型并在代码隐藏文件中对其进行初始化。但如果你想要控制器,我建议你不要使用剃须刀页面,而只使用经典的 mvc。您可以使用它创建一个新项目,只是不要从模板中选择剃须刀页面。 您当然不需要创建 razor pages 项目。这只是一种选择。我个人并没有真正使用它,因为我认为很容易重复代码,因为每个代码隐藏文件仅对一页 afaik 有效。

什么是 PageModel?

页面模型只是为您的特定页面执行服务器端逻辑的代码隐藏文件。

我不确定你到底要什么,你绑定模型就像任何其他剃须刀页面和代码隐藏类中的属性一样。在我的示例中,模型是代码隐藏文件。

动作/处理程序如何知道哪些属性是从视图/剃刀页面传递给它的?

动作处理程序通过您在 razor 页面中指定它来知道它: &lt;input asp-for="Customer.Name" /&gt;

请在此处阅读有关 Razor 页面的更多信息: https://docs.microsoft.com/en-us/aspnet/core/mvc/razor-pages/?tabs=visual-studio

【讨论】:

感谢您的回复,我想知道这些操作都去哪里了?特别是对于表单提交/Ajax 调用...一切似乎都与 OnPOST 处理程序相关...我是否需要构建自己的自定义路由器...似乎是倒退了一步。想知道为什么我应该转向这个,或者什么时候应该考虑这个模型 @transformer 好吧,每个服务器操作可能最好放在每个页面模型中。由于每个页面都有自己的逻辑,因此您不能像使用控制器那样以简单的方式真正重用逻辑。我认为您应该将 razorpages 用于以前可能使用经典 asp 表单的项目和/或不需要在页面之间共享逻辑的较小项目。当然,您仍然可以创建一些服务类并以相同的方式使用它。但是,如果您不确定为什么要选择 razorpages,我会说使用经典 MVC 而不是 razorpages。 “但是如果你想要控制器,我建议你不要使用 razor 页面”——你可以在 Razor 页面旁边使用控制器。如果我想要不一定与特定页面相关的 API 样式的 URI,我会这样做。如果您真的愿意,您甚至可以将 MVC 视图与 Razor Pages 混合使用。 Razor Pages 与 Web 表单的唯一关系是它们都是 MVVM,它们没有其他 Web 表单包袱(如视图状态、页面生命周期、asp 控件、单一表单限制等)。

以上是关于如何将 MVC 操作和属性重写为 ASP Core MVVM Razor 页面的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET Core Web 应用程序系列- 在ASP.NET Core中使用Autofac替换自带DI进行构造函数和属性的批量依赖注入(MVC当中应用)

asp.net core 系列 5 MVC框架路由(上)

ASP.NET Core Web 应用程序系列- 在ASP.NET Core中使用Autofac替换自带DI进行构造函数和属性的批量依赖注入(MVC当中应用)

ASP.NET MVC Core/6:多个提交按钮

ASP.NET MVC Core/6:多个提交按钮

在 ASP.NET MVC Core 控制器的构造函数中设置 ViewBag 属性