无法在 Razor 页面中调用 onPost

Posted

技术标签:

【中文标题】无法在 Razor 页面中调用 onPost【英文标题】:Unable to call onPost in Razor Pages 【发布时间】:2022-01-12 06:40:25 【问题描述】:

我想使用 POST 方法将 JSON 数据发送到剃须刀页面:https://localhost:port/Post 并获得 JSON 输出。

例如:

我想将用户名和电子邮件作为 JSON 传递:

"username":"test","email":"test@mail.com"

到 Post.cshtml 页面的 onPost 方法:https://localhost:44363/Post:

public JsonResult OnPost([FromForm] Dictionary<String, String> FormValues)

    String username = FormValues["username"];
    String email = FormValues["email"];

    Dictionary<String,String> dict = new Dictionary<String, String>();

    dict.Add("username", username);
    dict.Add("email", email);

    return new JsonResult(dict);

我在 WinForms 中使用 HttpClient 调用这个 POST 方法:

HttpClient client = new HttpClient();

Dictionary<String, String> dict1 = new Dictionary<String, String>();

dict1.Add("username", "test");
dict1.Add("email", "test@mail.com");

String JSON = JsonConvert.SerializeObject(dict1);

HttpResponseMessage Result;

Result = client.PostAsync("https://localhost:44363/Post", new StringContent(JSON, Encoding.UTF8, "application/json")).Result;

String json = Result.Content.ReadAsStringAsync().Result;

Dictionary<String, String> dict2 = JsonConvert.DeserializeObject<Dictionary<String, String>>(json);

但我收到bad request 400 错误。

我也试过FromBody 为:public JsonResult OnPost([FromBody] Dictionary&lt;String, String&gt; FormValues)onPost 没有执行。

但是,OnGet 方法运行良好:

public JsonResult OnGet()

    Dictionary<String, String> dict = new Dictionary<String, String>();

    dict.Add("username", "test");
    dict.Add("email", "test@mail.com");

    return new JsonResult(dict);

对于HttpClient

HttpClient client = new HttpClient();

HttpResponseMessage Result;

Result = client.GetAsync("https://localhost:44363/Post").Result;

String json = Result.Content.ReadAsStringAsync().Result;

Dictionary<String, String> dict2 = JsonConvert.DeserializeObject<Dictionary<String, String>>(json);

【问题讨论】:

【参考方案1】:

Razor Pages have request verification enabled by default 中的 POST 处理程序。这是为了防止跨站点请求伪造。通常,建议是在请求中包含验证令牌,但在您的情况下,最简单的解决方案是在 PageModel 级别禁用对令牌的检查:

[IgnoreAntiforgeryToken(Order = 1001)]
public class PostModel : PageModel

   ...

顺便说一句,如果您要发布 JSON,则需要在处理程序参数上使用 FromBody 属性,而不是 FromForm

【讨论】:

谢谢,它现在可以正常工作了,但是还有其他方法吗?而不是删除网站的安全方面? 它只会从特定页面上的 POST 方法中删除,而不是整个网站。理想情况下,您不应该从外部应用程序调用页面处理程序方法。您应该使用 Web API 控制器来提供此类服务,或者如果您的目标是 .NET 6,则使用最少的 API:docs.microsoft.com/en-us/aspnet/core/fundamentals/…。 好的,我同意你的观点。我现在正在尝试将具有 POST 方法项目的 Web API 控制器发布到剃刀页面应用程序的example.com/Post 路径。因此,将有 2 个项目,第一个是 example.com 的 razor 页面,另一个是带有 example.com/Post url 的 POST 控制器的 Web API 项目,它将与外部应用程序连接。这是正确的方法吗?但是将来我想在功能上添加 SignalR,我应该在哪里添加呢?在example.com 的剃须刀页面项目中或在example.com/Post 的Web API 项目中? 对我来说似乎很合理。恐怕对 SignalR 不太熟悉。

以上是关于无法在 Razor 页面中调用 onPost的主要内容,如果未能解决你的问题,请参考以下文章

Razor Pages .NetCore OnPost 处理程序

Razor View 将错误的 Id 传递给 OnPost 方法

在 _Layout 文件中按下按钮时,如何在 Razor 页面中创建 cookie?

Razor Pages OnPost 方法中的 Page() 方法有啥作用?

Asp.Net Core 上的 Razor 页面 - 添加了 Razor 页面但无法让页面显示

无法在 Razor 页面中选择单选按钮