使用 POST 方法创建最简单的 ASP.NET Core 表单
最近我需要创建一个简单的页面,供用户提交 HTML 表单。Azure 应用程序的其他部分运行在Azure 无服务器函数、逻辑应用和认知服务上,但对于认知服务,我希望用户能够点击链接,在 Web 浏览器(可能是移动设备)中打开页面,在表单中输入密码,然后通过 POST 请求提交到 SSL 加密页面。我考虑过编写一个小型 Xamarin 应用,并通过 POST 请求将表单提交到 Azure 函数。另一种方案是使用静态 HTML 页面,并使用 JavaScript 通过 POST 请求将表单提交到该 Azure 函数。我并不排除将来使用这两种方案的可能性。
但与此同时,我想尝试一个简单的Razor 页面(CSHTML),该页面会向用户呈现一个 HTML 表单,并通过 HTTPS 的 POST 请求将此表单提交给自己。
此示例的源代码在此处。
带有模型的 Razor 页面真的很酷
我喜欢不使用 MVC 的超简洁ASP.NET Core网站。别误会,MVC对于企业级 Web 应用程序来说非常棒,因为可测试性和可维护性至关重要。但 MVC 也带来了很多额外的开销。如果你使用下面红色圆圈标记的模板创建一个“空”的 ASP.NET Core MVC 网站,最终会得到一大堆文件(CSHTML 页面、控制器、设置类、JavaScript、CSS 等)。即使是一个空的 ASP.NET Core MVC 网站也包含 38 个文件(!)。
Visual Studio 中的 ASP.NET Core Razor 和 ASP.NET Core MVC 模板
另一种选择是仅使用 Razor 页面创建 ASP.NET Core Web 应用程序。在这种应用程序中,您可以移除控制器,并在附加到 CSHTML Razor 页面的PageModel实例中处理代码。这无疑更简单,事实上,我的个人网站就是以这种方式实现的。然而,即使您使用上面橙色圆圈标记的模板以这种方式创建一个“空”Web 应用程序,最终仍然会生成大量文件,并且需要删除其中大部分。这很麻烦,所以我更喜欢从一个“真正空”的模板开始,例如上图中蓝色标记的模板。
虽然我在本示例中使用的是 Visual Studio,但您也可以使用命令行创建 ASP.NET Core 应用程序,
dotnet new语法如下所示。
从零开始
让我们从头开始,使用Empty上面显示的 Web 应用程序模板。为此,请在 Visual Studio 2017 中,首先选择“文件”>“新建”>“项目”。
开始之前,您必须确保已在Visual Studio 安装程序中安装了 .NET Core 工作负载。您可以随时从“开始”菜单运行 Visual Studio 安装程序,并检查是否已选中以下工作负载。
.NET Core 工作负载
下一步,您需要选择如下所示的“空 Web 应用程序”。您可以默认启用 HTTPS,这通常是一个好主意。在本示例中,我们不会使用身份验证,因此您可以将此选项保留为默认值No Authentication。然后单击“确定”。
配置 Razor 页面
接下来,我们将配置应用程序以提供 Razor 页面。为此,即使我们不会在这里使用完整的 MVC 功能,我们仍然需要让应用程序使用 MVC 服务。
- 在 Visual Studio 中打开Startup.cs 文件。
- 按如下方式修改该
ConfigureServices方法:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
}
Configure按如下方式修改方法:
public void Configure(
IApplicationBuilder app,
IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseMvc();
}
创建 Razor 页面
通过这种配置,应用程序将在名为 `<route_name>` 的文件夹中查找 Razor (CSHTML) 页面Pages,并将请求定向到与路由(URL)对应的页面。在本例中,为了尽可能简化操作,我们将使用默认路由并创建一个名为`Index.cshtml`的页面。
- 右键单击项目,
Add然后New Folder从上下文菜单中选择。 - 给这个新文件夹命名
Pages。 - 右键单击文件夹,然后从上下文菜单中
Pages选择。AddRazor Page - 在
Add scaffold对话框中,按Add。 - 在
Add Razor Page对话框中输入名称,Index并确保Generate PageModel class已选中该名称。 - 取消选中
Use a layout page,然后按Add。
此步骤可能需要一些时间,因为需要安装一些 NuGet 包才能使 ASP.NET Core 应用程序、路由和 Razor 页面正常工作。
测试 GET 方法
默认情况下,该页面配置为接收 GET 请求。我们现在就来测试一下。
- 打开 Index.cshtml 页面(位于 Pages 文件夹中)。
- 请注意指令的存在
@model。该指令指示 ASP.NET 使用Index.cshtml.csIndexModel中的类来处理调用。
您还可以直接在 Index.cshtml 页面中添加代码,与 HTML 标记并列显示。这非常方便,但也可能导致代码混乱不堪,难以测试。因此,除了布局代码(例如
for用于创建列表的循环等)之外,不建议这样做。
- 打开Index.cshtml.cs文件。该文件位于解决方案资源管理器中的 Index.cshtml 页面内。
- 在 OnGet 方法中设置断点。
- 以调试模式运行应用程序。这将启动 IIS Express 并
localhost在您常用的 Web 浏览器中打开一个 URL,例如https://localhost:44367/。 - 注意,断点已被触发。
在该方法中,您可以访问所有常见的 ASP.NET 对象,例如HttpRequest实例(在Request属性中)等。
设置 POST 功能
就像我们可以GET在方法中处理调用一样OnGet,我们也会POST在方法中处理调用OnPost。不过,正如我们稍后会看到的,这需要一些额外的配置。首先,让我们准备一个 HTML 表单,它会将一个文本字段提交到 IndexModel 类。
- 在类
IndexModel中string,添加一个名为 的类型为 的属性Message。
public string Message
{
get;
set;
}
- 按如下方式修改该
OnGet方法:
public void OnGet()
{
Message = "Enter your message here";
}
- 仍然在 IndexModel 类中,添加一个名为以下方法的
OnPost:
public void OnPost()
{
Message = Request.Form[nameof(Message)];
}
- 在方法内部设置断点
OnPost。 - 在编辑器中打开Index.cshtml 文件。
- 按如下方式编辑
body:
<body>
<form method="post">
<input asp-for="Message" />
<br />
<input type="submit" />
</form>
</body>
- 再次以调试模式运行应用程序。该
OnGet方法将像之前一样被调用,您应该会看到一个带有空输入字段的 HTML 表单。
此时,如果您像我一样,原本期望输入字段会用Message属性的内容进行初始化(因为有这个asp-for属性),您可能会感到惊讶。但让我们继续测试,看看还有哪些问题。
- 在字段中输入任意文本,然后按提交按钮。
此时,浏览器中会显示 HTTP 错误 400(错误请求)。
修复错误请求 400
快速的在线搜索显示,问题出在缺少防伪令牌上。防伪令牌是 ASP.NET 为防止跨站请求伪造 (CSRF) 攻击而采取的一项安全措施。简而言之,该令牌的作用是证明请求确实来自表单的原始网站。
那么我们如何获取令牌呢?这就需要用到一个名为Microsoft.AspNetCore.Mvc.TagHelpers`<namespace>` 的命名空间了。将其添加到 CSHTML 页面中,即可自动在 HTML 表单中生成防伪令牌,并创建与我们添加到表单中的属性相对asp-for应的 HTML 属性。
@page
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@model TestPostWithRazor.Pages.IndexModel
@{
Layout = null;
}
- 再次以调试模式运行应用程序。
- 在您的网页浏览器中,页面加载完毕后,您应该可以看到表单已按预期初始化:
- 在页面上的任意位置单击鼠标右键,然后选择“显示
View page source”。您应该会看到由 ASP.NET 应用程序生成的以下 HTML 代码:
<body>
<form method="post">
<input type="text" id="Message" name="Message" value="Enter your message here" />
<br />
<input type="submit" />
<input name="__RequestVerificationToken" type="hidden" value="[Some token]" /></form>
</body>
- 修改文本字段的内容,然后单击“提交”按钮。此时,
OnPost方法中的断点应该会被触发,并且字段的内容将被赋值给Message相应的属性。
结论
此示例的源代码在此处。
有时候,简单才是王道。在这个例子中,我们学习了如何创建一个包含 Razor 页面(以及相应的 `<script>` 标签PageModel)的空 ASP.NET Core 应用程序,以及如何配置该应用程序来处理简单的 ` <script>`GET和POST`<script>` 方法。这是一种替代方案,可以取代其他机制,例如纯客户端 JavaScript 页面与无服务器 Azure 函数通信。虽然这里介绍的解决方案并非无服务器方案,但如果您已经在 Azure 中拥有应用服务计划,并且支持 Windows 或 Linux 系统,则可以利用 ASP.NET Core 的跨平台特性来使用它。
希望这段代码对某些人有用。
祝您编程愉快!
洛朗
文章来源:https://dev.to/azure/creating-the-simplest-possible-aspnet-core-form-with-a-post-method-416g





