【翻译】介绍 ASP.NET Core 中的 Razor Pages
介绍 ASP.NET Core 中的 Razor Pages
原文地址:Introduction to Razor Pages in ASP.NET Core 译文地址:介绍 asp.net core 中的 Razor Pages 翻译:ganqiyin
Razor Pages 是 ASP.NET Core MVC 的一个新功能,可以让基于页面的编程方案更容易,更高效。
如果您正在寻找使用 Model-View-Controller 的教程,请参阅ASP.NET Core MVC入门。
使用 ASP.NET Core 2.0 的前提条件
安装 .NET Core 2.0.0 或更高版本.
如果您使用 Visual Studio 工具, 请安装具有以下工作组件的 Visual Studio 15.3 或更高版本:
- ASP.NET and web development
- .NET Core cross-platform development
创建一个Razor Pages项目
Visual Studio
有关如何使用Visual Studio创建 Razor Pages 项目的详细说明,请参阅“ Razor Pages入门”。
Visual Studio for Mac
从命令行运行 dotnet new razor
。
从 Visual Studio for Mac 打开生成的 .csproj 文件。
Visual Studio Code
从命令行运行 dotnet new razor
。
.NET Core CLI
从命令行运行 dotnet new razor
。
Razor Pages
Razor Pages 在 Startup.cs 启用:
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
// Includes support for Razor Pages and controllers.
services.AddMvc();
} public void Configure(IApplicationBuilder app)
{
app.UseMvc();
}
}
研究一个基础页面:
@page <h1>Hello, world!</h1>
<h2>The time on the server is @DateTime.Now</h2>
前面的代码看起来很像Razor视图文件。 @page
指令使它与众不同. @page
让文件变成一个 MVC action - 这意味着它可以直接处理请求,而无需通过控制器。 @page
必须是页面上的第一个Razor指令。 @page
会影响其他Razor结构的行为。 @functions 指令启用 function-level 内容。
以下两个文件中显示了一个类似的页面,其中 PageModel
位于单独的文件中。 Pages/Index2.cshtml 文件:
@page
@using RazorPages
@model IndexModel2 <h2>Separate page model</h2>
<p>
@Model.Message
</p>
Pages/Index2.cshtml.cs '代码后置' 文件:
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 }";
}
}
}
根据约定, PageModel
class 文件与附加了 .cs 的 Razor Page 文件具有相同名称。例如, 代码前置的 Razor Page 是 Pages/Index2.cshtml。 那么包含 PageModel
class 的代码后置文件名称就是 Pages/Index2.cshtml.cs。
对于简单的页面来说, PageModel
class 与 Razor 标记混合使用是很好的选择. 对于更复杂的代码来说, 最好的做法是保持页面与代码分离.
网页路径到页面的关联由页面在文件系统中的位置确定。 下表显示了Razor Page路径和匹配的URL:
文件名称和路径 | 匹配的 URL |
---|---|
/Pages/Index.cshtml | / or /Index |
/Pages/Contact.cshtml | /Contact |
/Pages/Store/Contact.cshtml | /Store/Contact |
/Pages/Store/Index.cshtml | /Store or /Store/Index |
备注:
- 默认情况下,运行时会在Pages文件夹中查找Razor Pages文件。
- 当URL不包含页面时,
Index
是默认页面。
写一个基础的 form
Razor Pages 功能旨在使与Web浏览器一起使用的常见模式变得容易(Razor Pages features are designed to make common patterns used with web browsers easy)。 Model 绑定, Tag Helpers, and HTML helpers 都可以使用 Razor Page 中的默认属性让它们一起工作 。 研究一个实现了基础的“联系我们” form 的页面的 Contact
模型:
对于本文档中的示例, DbContext
在 Startup.cs 文件中初始化。
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using RazorPagesContacts.Data; namespace RazorPagesContacts
{
public class Startup
{
public IHostingEnvironment HostingEnvironment { get; } public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<AppDbContext>(options =>
options.UseInMemoryDatabase("name"));
services.AddMvc();
} public void Configure(IApplicationBuilder app)
{
app.UseMvc();
}
}
}
数据模型:
using System.ComponentModel.DataAnnotations; namespace RazorPagesContacts.Data
{
public class Customer
{
public int Id { get; set; } [Required, StringLength(100)]
public string Name { get; set; }
}
}
Pages/Create.cshtml 视图文件:
@page
@model RazorPagesContacts.Pages.CreateModel
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers <html>
<body>
<p>
Enter your name.
</p>
<div asp-validation-summary="All"></div>
<form method="POST">
<div>Name: <input asp-for="Customer.Name" /></div>
<input type="submit" />
</form>
</body>
</html>
Pages/Create.cshtml.cs 视图文件的后置代码文件:
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using RazorPagesContacts.Data; namespace RazorPagesContacts.Pages
{
public class CreateModel : PageModel
{
private readonly AppDbContext _db; public CreateModel(AppDbContext db)
{
_db = db;
} [BindProperty]
public Customer Customer { get; set; } public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
} _db.Customers.Add(Customer);
await _db.SaveChangesAsync();
return RedirectToPage("/Index");
}
}
}
根据约定, PageModel
class 被称为 <PageName>Model
与该页面在同一个命名空间中。在页面中使用 @functions
定义处理程序和使用 PageModel
class 不需要太多的改变。
使用 PageModel
后置代码文件支持单元测试, 但要求您编写一个含有显示的构造函数的类。 没有 PageModel
后置代码文件的页面支持运行时编译,这在开发中可能是一个优势.
该页面包含一个在 POST
请求(用户提交表单时)上运行的 OnPostAsync
方法。 您可以为任何 HTTP 请求添加方法。 最常见的处理方法有:
OnGet
初始化页面所需要的状态. OnGet 示例。OnPost
处理表单提交。
Async
命名后缀是可选的,但通常用于标识异步方法。 前面示例中的 OnPostAsync
代码通常是写在一个 Controller 中。 上述代码是一个典型的 Razor Pages 代码。 大多数 MVC 原始预防,如 model 绑定, 验证, 和 Action 结果都是共享的。
前面的 OnPostAsync
方法:
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
} _db.Customers.Add(Customer);
await _db.SaveChangesAsync();
return RedirectToPage("/Index");
}
OnPostAsync
的基本流程:
检查验证错误。
- 如果没有错误,保存数据并重定向。
- 如果有错误, 再次显示该页面,并且在页面上显示错误信息。 客户端验证与传统的ASP.NET Core MVC应用程序相同。 大多数情况下,都是在客户端校验错误,并且不会提交给服务器。
单输入的数据校验通过后, OnPostAsync
方法会调用 RedirectToPage
帮助方法来返回一个 RedirectToPageResult
实例. RedirectToPage
是一个新的 action 结果, 类似于 RedirectToAction
或 RedirectToRoute
,但是它是为 pages 定制的。 在上面的示例中, 它重定向到根目录 Index 页面 (/Index
). RedirectToPage
在 页面的URL生成(URL generation for Pages) 部分中有详细说明。
当提交的表单具有验证错误(传递给服务器)时,OnPostAsync
方法会调用 Page
方法. Page
返回一个 PageResult
实例。 返回 Page
类似于在 controllers 中执行返回 View
方法。 PageResult
是处理程序方法的默认 返回类型。一个返回 void
来呈现页面的方法。
自定义
属性使用 [BindProperty]
特性来处理 model 绑定。
public class CreateModel : PageModel
{
private readonly AppDbContext _db; public CreateModel(AppDbContext db)
{
_db = db;
} [BindProperty]
public Customer Customer { get; set; } public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
} _db.Customers.Add(Customer);
await _db.SaveChangesAsync();
return RedirectToPage("/Index");
}
}
通常情况下,Razor Pages 仅在 non-GET 方法中使用属性绑定。 属性绑定可以减少您编写的代码量。绑定通过使用相同的属性来呈现表单字段 (<input asp-for="Customer.Name" />
) 和接受输入,所以可以减少代码量。
主页 (Index.cshtml):
@page
@model RazorPagesContacts.Pages.IndexModel
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers <h1>Contacts</h1>
<form method="post">
<table class="table">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
</tr>
</thead>
<tbody>
@foreach (var contact in Model.Customers)
{
<tr>
<td>@contact.Id</td>
<td>@contact.Name</td>
<td>
<a asp-page="./Edit" asp-route-id="@contact.Id">edit</a>
<button type="submit" asp-page-handler="delete"
asp-route-id="@contact.Id">delete</button>
</td>
</tr>
}
</tbody>
</table> <a asp-page="./Create">Create</a>
</form>
后置代码文件 Index.cshtml.cs :
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using RazorPagesContacts.Data;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore; namespace RazorPagesContacts.Pages
{
public class IndexModel : PageModel
{
private readonly AppDbContext _db; public IndexModel(AppDbContext db)
{
_db = db;
} public IList<Customer> Customers { get; private set; } public async Task OnGetAsync()
{
Customers = await _db.Customers.AsNoTracking().ToListAsync();
} public async Task<IActionResult> OnPostDeleteAsync(int id)
{
var contact = await _db.Customers.FindAsync(id); if (contact != null)
{
_db.Customers.Remove(contact);
await _db.SaveChangesAsync();
} return RedirectToPage();
}
}
}
Index.cshtml 文件包含一下标记,用于为每个节点创建一个编辑链接:
<a asp-page="./Edit" asp-route-id="@contact.Id">edit</a>
Anchor Tag Helper(锚标记辅助) 使用 asp-route-{value} 属性来生成一个可以跳转到编辑页面的链接。 该链接包含 contact ID 路由数据。 例如, http://localhost:5000/Edit/1
.
Pages/Edit.cshtml 文件:
@page "{id:int}"
@model RazorPagesContacts.Pages.EditModel
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers @{
ViewData["Title"] = "Edit Customer";
} <h1>Edit Customer - @Model.Customer.Id</h1>
<form method="post">
<div asp-validation-summary="All"></div>
<input asp-for="Customer.Id" type="hidden" />
<div>
<label asp-for="Customer.Name"></label>
<div>
<input asp-for="Customer.Name" />
<span asp-validation-for="Customer.Name" ></span>
</div>
</div> <div>
<button type="submit">Save</button>
</div>
</form>
第一行包含 @page "{id:int}"
指令。 路由约束 "{id:int}"
告诉页面接受对包含 int
路由数据的页面的请求。 如果对页面的请求不包含可转换为 int
的路由数据,则运行时返回HTTP 404(未找到)错误。
Pages/Edit.cshtml.cs 文件:
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using RazorPagesContacts.Data; namespace RazorPagesContacts.Pages
{
public class EditModel : PageModel
{
private readonly AppDbContext _db; public EditModel(AppDbContext db)
{
_db = db;
} [BindProperty]
public Customer Customer { get; set; } public async Task<IActionResult> OnGetAsync(int id)
{
Customer = await _db.Customers.FindAsync(id); if (Customer == null)
{
return RedirectToPage("/Index");
} return Page();
} public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
} _db.Attach(Customer).State = EntityState.Modified; try
{
await _db.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
throw new Exception($"Customer {Customer.Id} not found!");
} return RedirectToPage("/Index");
}
}
}
XSRF/CSRF and Razor Pages
您不必为防伪验证编写任何代码。 Razor Pages自动包含防伪令牌生成和验证。
在 Razor Pages 中使用 Layouts, partials, templates, and Tag Helpers
所有适用于页面上工作的 Razor 视图引擎的功能: Layouts,partials,templates,Tag Helpers,_ViewStart.cshtml, _ViewImports.cshtml 的工作方式与传统Razor视图相同。
让我们通过其中的一些特性来梳理一下该页面吧。
添加一个 布局(layout)页面 Pages/_Layout.cshtml:
<!DOCTYPE html>
<html>
<head>
<title>Razor Pages Sample</title>
</head>
<body>
<a asp-page="/Index">Home</a>
@RenderBody()
<a asp-page="/Customers/Create">Create</a> <br />
</body>
</html>
布局:
- 控制每个页面的布局(PS:代码重用) (除非不使用布局页)。
- 导入 HTML 结构,如 JavaScript 和 CSS 样式。
更多信息请查看 layout page。
在 Pages/_ViewStart.cshtml 中设置 Layout 属性:
@{
Layout = "_Layout";
}
注意: 布局位于 Pages 文件夹中。分层查找其他视图页面 (layouts, templates, partials) 的起点是当前页面所在的文件夹。在 Pages 文件夹中的布局页可以被位于 Pages 文件夹下的任意 Razor 页面使用。
我们建议您不要把布局文件放在 Views/Shared 文件夹下。 Views/Shared 是一个 MVC 视图模式。 Razor Pages 依赖于文件夹层次结构,而不是路径约定。
来自 Razor 页面的视图查找包括 Pages 文件夹。您使用MVC控制器和常规Razor视图的布局,模板和部分视图可以正常工作(View search from a Razor Page includes the Pages folder. The layouts, templates, and partials you're using with MVC controllers and conventional Razor views just work.)。
添加一个 Pages/_ViewImports.cshtml 文件:
@namespace RazorPagesContacts.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@namespace
将在本教程的后面介绍。 @addTagHelper
指令将内置的 built-in Tag Helpers 引入 Pages 文件夹中的所有页面。
当 @namespace
指令在页面上显式使用时:
@page
@namespace RazorPagesIntro.Pages.Customers @model NameSpaceModel <h2>Name space</h2>
<p>
@Model.Message
</p>
该指令用于在当前页面中设置命名空间(namespace) 。 @model
伪指令可以不用包含命名空间。
当 @namespace
指令包含在 _ViewImports.cshtml 中时, @namespace
指令指定的命名空间为需要导入有相同命名空间的页面提供了生成命名空间的前缀。 生成命名空间 (后缀部分) 的其余部分则在包含了 _ViewImports.cshtml 文件的文件夹中的页面中。
例如, Pages/Customers/Edit.cshtml.cs 代码后置文件中显示的设置了命名空间:
namespace RazorPagesContacts.Pages
{
public class EditModel : PageModel
{
private readonly AppDbContext _db; public EditModel(AppDbContext db)
{
_db = db;
} // Code removed for brevity.
Pages/_ViewImports.cshtml 文件设置以下命名空间:
@namespace RazorPagesContacts.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
Pages/Customers/Edit.cshtml Razor 页面中引用的命名空间与代码后置文件中的命名空间相同。 @namespace
指令被设计成能同时在 C# 项目类中和页面代码后置文件中使用,而不需要使用 @using
指令。
注意: @namespace
同样适用于常规 Razor 视图。
原始的 Pages/Create.cshtml 视图文件:
@page
@model RazorPagesContacts.Pages.CreateModel
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers <html>
<body>
<p>
Enter your name.
</p>
<div asp-validation-summary="All"></div>
<form method="POST">
<div>Name: <input asp-for="Customer.Name" /></div>
<input type="submit" />
</form>
</body>
</html>
更新后的页面:
The Pages/Create.cshtml view file:
@page
@model CreateModel <html>
<body>
<p>
Enter your name.
</p>
<div asp-validation-summary="All"></div>
<form method="POST">
<div>Name: <input asp-for="Customer.Name" /></div>
<input type="submit" />
</form>
</body>
</html>
Razor Pages 项目示例 包含配置客户端验证的钩子 Pages/_ValidationScriptsPartial.cshtml。
生成 URL 路径
Create
页面中使用 RedirectToPage
来跳转上一页:
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
} _db.Customers.Add(Customer);
await _db.SaveChangesAsync();
return RedirectToPage("/Index");
}
这款应用有以下“文件/文件夹”结构
/Pages
Index.cshtml
/Customer
- Create.cshtml
- Edit.cshtml
- Index.cshtml
成功后,Pages/Customers/Create.cshtml 和 Pages/Customers/Edit.cshtml 页跳转到 Pages/Index.cshtml 页。 /Index
是跳转到前一页的 URI 的一部分。 /Index
可用于生成 Pages/Index.cshtml 页面的 URI。例如:
Url.Page("/Index", ...)
<a asp-page="/Index">My Index Page</a>
RedirectToPage("/Index")
页面名称是从 /Pages 根文件夹(包括 前导 /
,例如 /Index
)到页面的路径。上述示例展示了更灵活的URL生成功能,而不仅仅是对URL进行硬编码。使用路由 生成URL,并可以根据自定义的路由在目标路径中生成和编码参数。
支持相对名称生成页面的 URL 。 下表展示了在 Pages/Customers/Create.cshtml 中调用 RedirectToPage
方法生成跳转到不同 Index 页面的方式(使用了不同的参数):
RedirectToPage(x) | Page |
---|---|
RedirectToPage("/Index") | Pages/Index |
RedirectToPage("./Index"); | Pages/Customers/Index |
RedirectToPage("../Index") | Pages/Index |
RedirectToPage("Index") | Pages/Customers/Index |
RedirectToPage("Index")
, RedirectToPage("./Index")
, 和 RedirectToPage("../Index")
都使用了 相对名称。 RedirectToPage
的参数表示 参考 当前页面的路径计算得到目标页面的名称。 <!-- 评论:原始提供的字符串与当前页面的页面名称组合以计算目标页面的名称。 -- 页面名称,而不是页面路径 -->
构建具有复杂结构的站点时,相对名称链接很有用。 如果使用相对名称在文件夹中的页面之间链接,则可以重命名该文件夹。 所有链接仍然有效(因为它们不包括文件夹名称)。
TempData
ASP.NET Core 公开了 controller 上的 TempData 属性。 此属性存储数据,直到它被读取。Keep
和 Peek
方法可用于在不删除数据的情况下检查数据。当数据被多个请求需要的时候, TempData
对重定向很有用。
[TempData]
在 ASP.NET Core 2.0 中是一个新的属性,且 controllers 和 pages 都支持这个属性。
以下代码就是使用 TempData
来传递 Message
的值。
public class CreateDotModel : PageModel
{
private readonly AppDbContext _db; public CreateDotModel(AppDbContext db)
{
_db = db;
} [TempData]
public string Message { get; set; } [BindProperty]
public Customer Customer { get; set; } public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
} _db.Customers.Add(Customer);
await _db.SaveChangesAsync();
Message = $"Customer {Customer.Name} added";
return RedirectToPage("./Index");
}
}
以下在 Pages/Customers/Index.cshtml 文件中的标记显示了使用 TempData
存储的 Message
的值。
<h3>Msg: @Model.Message</h3>
Pages/Customers/Index.cshtml.cs 后置代码文件将 [TempData]
属性应用到 Message
属性。
[TempData]
public string Message { get; set; }
更多信息请查看 TempData 。
Multiple handlers per page
以下页面使用 asp-page-handler
Tag Helper 为页面生成两个处理程序标记:
@page
@model CreateFATHModel <html>
<body>
<p>
Enter your name.
</p>
<div asp-validation-summary="All"></div>
<form method="POST">
<div>Name: <input asp-for="Customer.Name" /></div>
<input type="submit" asp-page-handler="JoinList" value="Join" />
<input type="submit" asp-page-handler="JoinListUC" value="JOIN UC" />
</form>
</body>
</html>
上述示例中的表单有两个提交按钮,每个都使用 FormActionTagHelper
提交到一个不同的 URL。asp-page-handler
属性跟随着 asp-page
。asp-page-handler
生成页面需要提交的方法事件的 URL。 没有提到 asp-page
是因为示例是链接到当前页面的。
后置代码文件:
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using RazorPagesContacts.Data; namespace RazorPagesContacts.Pages.Customers
{
public class CreateFATHModel : PageModel
{
private readonly AppDbContext _db; public CreateFATHModel(AppDbContext db)
{
_db = db;
} [BindProperty]
public Customer Customer { get; set; } public async Task<IActionResult> OnPostJoinListAsync()
{
if (!ModelState.IsValid)
{
return Page();
} _db.Customers.Add(Customer);
await _db.SaveChangesAsync();
return RedirectToPage("/Index");
} public async Task<IActionResult> OnPostJoinListUCAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
Customer.Name = Customer.Name?.ToUpper();
return await OnPostJoinListAsync();
}
}
}
上诉代码使用了 named handler methods. Named handler methods 是通过在 On<HTTP Verb>
和 Async
(如果存在) 之间的文本创建的。 在前面的示例中, 页面方法是 OnPostJoinListAsync 和 OnPostJoinListUCAsync。移除 OnPost 和 Async 后,处理程式的名字是 JoinList
和 JoinListUC
。
<input type="submit" asp-page-handler="JoinList" value="Join" />
<input type="submit" asp-page-handler="JoinListUC" value="JOIN UC" />
使用上述代码,提交到 OnPostJoinListAsync
的 URL 是 http://localhost:5000/Customers/CreateFATH?handler=JoinList
. 提交到 OnPostJoinListUCAsync
的 URL 是 http://localhost:5000/Customers/CreateFATH?handler=JoinListUC
.
自定义路由
如果您不喜欢 URL 中的查询字符串 ?handler=JoinList
,则可以更改路由以将处理名称加入到 URL 中。您可以通过在 @page
指令之后添加用双引号括起来的路由模板来自定义路由。
@page "{handler?}"
@model CreateRouteModel <html>
<body>
<p>
Enter your name.
</p>
<div asp-validation-summary="All"></div>
<form method="POST">
<div>Name: <input asp-for="Customer.Name" /></div>
<input type="submit" asp-page-handler="JoinList" value="Join" />
<input type="submit" asp-page-handler="JoinListUC" value="JOIN UC" />
</form>
</body>
</html>
前面的路由将处理名称放入 URL 中,用于替代查询字符串。那 ?
后面的 handler
意味着 route 参数时时可选的。
您可以使用 @page
将额外的部分和参数添加到页面的路由中。无论页面的默认路由附加了什么,都不支持使用绝对或虚拟路径来更改页面的路由(比如 "~/Some/Other/Path"
) 。
配置和设置
需要配置高级选项,请在 MVC 构建器上使用扩展方法AddRazorPagesOptions
:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc()
.AddRazorPagesOptions(options =>
{
options.RootDirectory = "/MyPages";
options.Conventions.AuthorizeFolder("/MyPages/Admin");
});
}
目前,您可以使用 RazorPagesOptions
设置页面的根目录,或为页面添加应用程序模型约定。 我们希望今后能够实现更多的扩展性。
要预编译视图,请参阅 Razor view compilation 视图编译。
请参阅 ASP.NET Core 的 Razor Pages 入门。
【翻译】介绍 ASP.NET Core 中的 Razor Pages的更多相关文章
- 1.ASP.NET Core 中向 Razor Pages 应用添加模型
右键单击“RazorPagesMovie”项目 >“添加” > “新建文件夹”. 将文件夹命名为“Models”.右键单击“Models”文件夹. 选择“添加” > “类”. 将类命 ...
- ASP.NET Core 中的 Razor 页面介绍
标题:ASP.NET Core 中的 Razor 页面介绍 地址:https://docs.microsoft.com/zh-cn/aspnet/core/razor-pages/index?view ...
- ASP.NET Core中使用Razor视图引擎渲染视图为字符串
一.前言 在有些项目需求上或许需要根据模板生产静态页面,那么你一样可以用Razor语法去直接解析你的页面从而把解析的页面生成静态页,这样的使用场景很多,不限于生成静态页面,视图引擎为我们提供了模型到视 ...
- 【翻译】asp.net core中使用MediatR
这篇文章来自:https://ardalis.com/using-mediatr-in-aspnet-core-apps 本文作为翻译,有一些单词翻译成中文可能会有一些误解(对于读者)或者错误(对于作 ...
- 【翻译】asp.net core中使用FluentValidation来进行模型验证
asp.net core中使用FluentValidation FluentValidation 可以集成到asp.net core中.一旦启用,MVC会在通过模型绑定将参数传入控制器的方法上时使用F ...
- asp.net core中的razor页面
Razor 页面(Razor Pages)是 ASP.NET Core 2.0 中新增的一种Web页面模型,相对MVC形式更加简单易用,可以说是一个服务端的MVVM模型,本文简单的介绍一下它的用法. ...
- ASP.NET Core中使用Razor视图引擎渲染视图为字符串(转)
一.视图渲染说明 在有些项目需求上或许需要根据模板生产静态页面,那么你一样可以用Razor语法去直接解析你的页面从而把解析的页面生成静态页,这样的使用场景很多,不限于生成静态页面,视图引擎为我们提供了 ...
- ASP.NET CORE RAZOR :将文件上传至 ASP.NET Core 中的 Razor 页面
本部分演示使用 Razor 页面上传文件. 本教程中的 Razor 页面 Movie 示例应用使用简单的模型绑定上传文件,非常适合上传小型文件. 有关流式传输大文件的信息,请参阅通过流式传输上传大文件 ...
- ASP.NET Core 中的 Razor 文件编译
asp .net core mvc 3.0 在编译的时候做了一些改变,有些view视图更改需要重新编译,你也可以配置运行时编译,不用每次更改都去重新生成,具体代码如下,从官方文档看到,做个记录. Ra ...
随机推荐
- Web中的中文参数乱码
中文参数乱码 1 get方式传参,中文乱码 修改tomcat中的配置server.xml 在修改端口的标签中添加属性URIEncoding="XXX&quo ...
- 微信小程序流量主如何开通
2018年7月09日,微信小程序流量主全面开通,开通条件如下: 累计独立访客(UV)不低于1000 # 一共一千个人访问你的小程序就可以申请(不限时间) 有严重违规记录的小程序不予申 ...
- python中and,or
在很多逻辑语句中,常常会出现and,or这两个逻辑运算符. 下面直接上代码 print(0 or None) #None ''' or比较运算符: 当or旁两边都是真的话,那么会取第一个值 当or两边 ...
- ab工具测试 swoole 和 ngixn+php-fpm 的并发对比
测试样例: 执行的一条sql记录的1w次插入分两组: 一组用nginx+pfm 来执行, 一组用swoole 来执行 公平性保证前提: @1.为了保证公平性, 在nginx里把 access_log, ...
- 构建高可靠hadoop集群之4-保全模式
本文主要翻译自http://hadoop.apache.org/docs/r2.8.0/hadoop-project-dist/hadoop-common/SecureMode.html 译注:之所以 ...
- (第04节)集成SpringMVC框架
在上一节的基础上集成spring_mvc 首先添加依赖文件 <properties> <javax.servlet.version>4.0.0</javax.servle ...
- Java中Redis缓存
1:安装 安装可分为单机版redis 和集群版redis 安装比较简单,自行百度即可 2:集成 pom文件中加入jedis 依赖,spring创建redis的application-resid配置, ...
- node 写api几个简单的问题
最近出了一直在做无聊的管理后台,还抽空做了我公司的计费终端,前端vue,后端node,代码层面没啥太多的东西.由于自己node版本是8.0.0,node自身是不支持import和export的,要想基 ...
- Spark-源码-TaskScheduler初始化过程, ClientActor向Master发送注册任务信息过程
Spark版本 1.3 Spark源码 Spark.createTaskScheduler TaskScheduler初始化过程 1.// SparkContext中 /** * Create a t ...
- scala成长之路(1)基本语法和数据类型
scala作为JVM上的Lisp,是一种geek类型的编程语言,也一直是我等java程序员眼中的梦寐以求的一门技能,遂下定决心花一段时间好好学习scala.第一天学习,主要介绍与java在编程上的主要 ...