You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core 3.1中Razor Page Handler的Ajax POST请求返回400错误

问题分析与解决方案

核心问题:400错误根源是缺少CSRF防伪造令牌

Razor Pages默认强制启用防伪造验证,所有POST请求必须携带__RequestVerificationToken,否则会直接返回400错误。你的Ajax请求未包含该令牌,这是触发错误的主要原因。

分步解决

1. 给Ajax请求添加CSRF令牌

有两种实现方式:

方式一:通过请求头传递令牌

先在页面(比如_Layout.cshtml)中添加隐藏令牌字段:

@Html.AntiForgeryToken()

修改site.js中的Ajax请求,增加请求头携带令牌:

function updateStudent(id) {
    if (id != null && id != '') {
        // 获取页面中的防伪造令牌
        const token = $('input[name="__RequestVerificationToken"]').val();
        $.ajax({
            type: "POST",
            url: "/Index?Handler=UpdateStudent",
            headers: {
                "RequestVerificationToken": token
            },
            data: { id: id },
            success: function (result) {
            },
            error: function (response) { // 注意原代码里的failure是错误写法,jQuery Ajax用error
                console.log(response);
            }
        });
    }
}

方式二:将令牌包含在请求数据中

同样先确保页面有@Html.AntiForgeryToken(),然后修改data参数:

data: { 
    id: id,
    __RequestVerificationToken: $('input[name="__RequestVerificationToken"]').val()
},

2. 修正PageModel中的代码错误

你的OnGet方法是void类型,却尝试return _studentService.GetStudents();,这会直接编译报错。调整代码如下:

[Authorize]
[AuthorizeForScopes(ScopeKeySection = "DownstreamApi:Scopes")]
public class IndexModel : PageModel
{
    private readonly IStudentService _studentService;

    // 注入服务(确保你已经注册了IStudentService)
    public IndexModel(IStudentService studentService)
    {
        _studentService = studentService;
    }

    public void OnGet()
    {
        // 如果需要将学生列表存入Session供_Layout使用
        var students = _studentService.GetStudents();
        HttpContext.Session.SetObject("StudentList", students);
    }

    public IActionResult OnPostUpdateStudent(string id)
    {
         HttpContext.Session.SetString("SelectedStudent", id);
         return new JsonResult(new { success = true }); // 返回响应,方便前端处理结果
    }
}

3. 确保Session功能已正确配置

在Startup.cs中必须添加Session的配置,否则Session无法正常使用:

public void ConfigureServices(IServiceCollection services)
{
    // 添加Session服务
    services.AddSession(options =>
    {
        options.IdleTimeout = TimeSpan.FromMinutes(30);
        options.Cookie.HttpOnly = true;
        options.Cookie.IsEssential = true;
    });

    services.AddRazorPages();
    // 其他服务注册代码...
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    // 其他中间件(如异常处理、静态文件)...

    // 必须在UseRouting之后、UseEndpoints之前添加UseSession
    app.UseSession();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
    });
}

4. 修正JavaScript方法名大小写问题

HTML中调用的UpdateAll和JS中定义的updateAll大小写不一致,会导致函数未定义,统一为小写:

<select onchange="updateAll(this)" asp-items="studentList" class="form-control">

5. 确认Session扩展方法存在

你的代码中用到了GetObject扩展方法从Session读取对象,如果项目中没有实现,需要添加以下代码:

public static class SessionExtensions
{
    public static void SetObject<T>(this ISession session, string key, T value)
    {
        session.SetString(key, JsonSerializer.Serialize(value));
    }

    public static T GetObject<T>(this ISession session, string key)
    {
        var value = session.GetString(key);
        return value == null ? default : JsonSerializer.Deserialize<T>(value);
    }
}

内容的提问来源于stack exchange,提问作者Yzak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 04:05:17