【问题标题】:What is the "url" to ajax-call a C# function in an asp.net core razor pages application在 asp.net 核心剃须刀页面应用程序中,ajax 调用 C# 函数的“url”是什么?
【发布时间】:2019-09-02 22:32:22
【问题描述】:

在 Visual Studio 中 ASP.NET Core Razor Pages 项目的自动生成的 site.js 文件中,我尝试使用 Ajax 调用

    $.ajax
        ({
            type: "POST",
            url: "",
            data: "asdsad",
            dataType: "text",
            success: function (result) {
                alert(result);
            },
            error: function (status, ex) {
                alert("Error Code: Status: " + status + " Ex: " + ex);
            }
        });

一个 C# 函数。我的项目树如下所示:

builder.cshtml.cs 文件也是在我添加 builder.cshtml 页面时由 Visual Studio 自动生成的。在我的builder.cshtml.cs 里面有这个代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace MyProjectName.Pages
{
    public class Index1Model : PageModel
    {
        public string Message { get; set; } = "Initial Request";
        public void OnGet()
        {
            Message = "Test1";
        }

        public void HelloFunc()
        {
            Message = "BuilderJob";
        }
    }
}

我添加了函数HelloFunc()Message 变量。通过ASP.NET Core documentation by Microsoft 后,我不明白从我的Ajax 代码中调用HelloFunc 的“url”是什么。它不是/builder/HelloFunc(不起作用)。如何从我的 Ajax 调用中访问此 HelloFunc

答案是将HelloFunc 更改为OnPostHelloFunc() 并使用此url: /builder?handler=HelloFunc,如果您只是测试而不使用验证令牌,请按照此处test .net core 2 page using Postman return 400 bad request 的说明插入[IgnoreAntiforgeryToken(Order = 1001)]

【问题讨论】:

标签: c# asp.net-core razor .net-core razor-pages


【解决方案1】:

Razor Pages 正在为此使用页面处理程序。因此,如果您想 POST 到您的页面,请创建一个名称为 OnPost{HandlerName}OnPost{HandlerName}Async 的方法(如果它是异步方法)。

例如,如果您有一个表单并想删除某些内容,您需要一个这样的页面处理程序:

public async Task<IActionResult> OnPostDeleteAsync(int id)
{
    var itemToDelete = await _mapRepo.GetByIdAsync(id);
    if (itemToDelete == null)
    {
        //...
    }

    await _mapRepo.Delete(itemToDelete);
    return RedirectToPage("Maps");
}

OnPost 声明,asp.net 核心将侦听 POST 请求,Delete 是名称,而Async 是异步处理程序的命名约定。

在您的表单中,您只需声明一个输入元素,该元素将在 onclick 事件期间调用此处理程序:

<button type="submit" class="btn btn-danger btn-block" asp-page-handler="Delete" asp-route-id="@Model.Id">Delete</button>

用 ajax 做这个:

$.ajax
({
    type: "POST",
    url: "/builder?handler=HelloFunc",
    dataType: "text",
    success: function (result) {
        alert(result);
    },
    error: function (status, ex) {
        alert("Error Code: Status: " + status + " Ex: " + ex);
    }
});

使用处理程序方法:

public void OnPostHelloFunc()
{
    //...
}

这里是命名处理程序的好读物:https://www.learnrazorpages.com/razor-pages/handler-methods

【讨论】:

  • 我不想用表单来做这件事,因为阻止页面刷新真的很复杂。但是,使用 url "/builder?handler=HelloFunc" 并将函数更改为 OnPostHelloFunc,我在 firefox 的控制台中得到 XML Parsing Error: no root element found Location: https://localhost:44388/builder?handler=HelloFunc Line Number 1, Column 1:。错误功能的警报也被抛出,它说Error Code: Status: [object Object] Ex: error
  • 在Hellofunc方法处设置断点,看是否被命中。如果是这样,这很可能是您的 ajax 方法出现错误,需要 xml 响应,但没有收到响应。毕竟一个 void 方法不会返回任何东西。你真的应该返回一个IActionResult
  • 我将OnPostHelloFunc 类型更改为IActionResult,然后返回Content("BuilderJob")。在函数的第一行(即Message = "BuilderJob")我设置了一个断点。断点没有被命中。我在ajax调用中使用这个urlurl: "/builder?handler=HelloFunc"。javascript错误在控制台中是一样的Firefox 以及警报中的
  • 如果我将函数更改为 OnGetHelloFunc 并使用所有其他参数进行 GET ajax 调用,它的工作原理相同(断点被命中,结果为成功),为什么?
  • 显然是因为它需要一个令牌来验证。对于测试,您可以像这样禁用它:stackoverflow.com/questions/47453401/…
【解决方案2】:

请参考这个Razor Pages in ASP.NET Core documentation,这里他们提到了文件名和路径映射及其匹配的url。

例如。

/Pages/Index.cshtml => // 或 /Index

/Pages/Contact.cshtml => /Contact

另一件事是 Razor 页面遵循特定的命名约定。它以“On”为前缀,后跟 HTTP 动词,如 OnGet()OnPost() 等。但是,我们也可以指定自定义名称。例如 -

  • OnGetPatientList()
  • OnPostHelloFunc()

现在,如果我们讨论您的情况,那么您需要在您的 builder.cshtml.cs 文件中进行以下更改。

namespace MyProjectName.Pages
{
    public class Index1Model : PageModel
    {
        public string Message { get; set; } = "Initial Request";
        public void OnGet()
        {
            Message = "Test1";
        }

        public IActionResult OnPostHelloFunc()
        {
            return Content("BuilderJob");
        }
    }
}

你的 ajax 函数看起来像这样 -

$.ajax
({
    type: "POST",
    url: "/builder?handler=HelloFunc",
    dataType: "text",
    beforeSend: function (xhr) {
            xhr.setRequestHeader("XSRF-TOKEN",
                $('input:hidden[name="__RequestVerificationToken"]').val());
    },
    success: function (result) {
        alert(result);
    },
    error: function (status, ex) {
        alert("Error Code: Status: " + status + " Ex: " + ex);
    }
});

【讨论】:

  • 虽然这并没有回答如何访问HelloFunc()(不可能/对吗?),但我想问一下,为什么将函数的类型设置为IActionResult?它不编译:Cannot implicitly convert type 'string' to 'Microsoft.AspNetCore.Mvc.IActionResult'
  • @Tasos:我已经修改了我的答案并进行了更多解释。
猜你喜欢
  • 2021-10-07
  • 2019-06-13
  • 2021-01-05
  • 2020-11-09
  • 2019-01-19
  • 2019-05-29
  • 2018-06-15
  • 1970-01-01
  • 2020-12-08
相关资源
最近更新 更多