.Net Core 3.1 在提交页面之前使用 ajax 调用时无法绑定属性

.Net Core 3.1 fails to bind properties while using ajax call before submitting the page

我正在使用 .net core 3.1 razor 页面。我有一个带有 属性 的页面。我在我的页面中使用 jQuery ajax 调用。有时虽然我的字段已填满,但 属性 在我的 PostAsync 方法中为空。花了很多时间,我在提交之前调用页面中的 $.ajax 函数时发现 MyProperty 为空(未绑定)!是 .net 核心中的错误还是我忘记了一些设置?

MyPage.chtml:

...
<form method="post">
    My Property: <input asp-for="MyProperty" /><br />
    <button id="doAction" type="button">Do some action in server</button><br />
    <button type="submit">Submit</button>
</form>
<script>
   $(document).ready(function() {
        $('#doAction').click(function(){
            $.ajax(
                '/api/myaction/doSomeAction/2',
                {
                    type: 'POST',
                    success: function() { alert('Some action done successfully.'); }
                }
        });
   });
</script>
...

MyPage.chtml.cs:

[BoundProperty]
public string MyProperty { get; set; }
...
public async Task<IActionResult> OnPostAsync()
{
    var temp = MyProperty;
    ...
}

MyAction 控制器class:

[Route( "api/[controller]" )]
[ApiController]
public class MyActionController : Controller
{
   [HttpPost( "doSomeAction/{code?}" )]
   public async Task<dynamic> PostAsync( int code )
   {
        // do some actions...
   }
}

Startup.cs:

public void Configure( IApplicationBuilder app , IWebHostEnvironment env )
{
    ...
    app.UseEndpoints( endpoints =>
        {
            endpoints.MapRazorPages();
            endpoints.MapControllerRoute( "default", "{controller}/{action}/{id?}" );
        } );
    ...
}

场景:

  1. "MyValue" 填写 MyProperty 并提交表格 => MyProperty == "MyValue"(确定)。
  2. "MyValue" 填充 MyProperty;单击 doAction 按钮;然后提交表单 => MyProperty == null(绑定 属性 失败!)

您假设要将数据发送到您的 ajax post 呼叫,

 <script>
       $(document).ready(function() {
       <script>
   $(document).ready(function() {
        $('#doAction').click(function(){
            $.ajax(
                '/api/myaction/doSomeAction/2',
                {
                    type: 'POST',
                    data:$(form).serializeArray();
                    success: function() { alert('Some action done successfully.'); }
                }
        });
   });
</script>

不知道你的具体问题出在哪里,一般情况下不会出现这种错误。您可以在下面看到我的工作示例。

Index.chtml:

@page
@model xxxxx.IndexModel
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@Html.AntiForgeryToken()
@{
    Layout = "_Layout";
}
<form method="post">
    My Property: <input asp-for="MyProperty" /><br />
    <button id="doAction" type="button">Do some action in server</button><br />
    <button type="submit">Submit</button>
</form>
@section scripts{
    <script>
        $(document).ready(function () {
            $('#doAction').click(function () {
                $.ajax(
                    {
                        url: '/api/myaction/doSomeAction/2',
                        type: 'POST',
                        beforeSend: function (xhr) {
                            xhr.setRequestHeader("XSRF-TOKEN",
                                $('input:hidden[name="__RequestVerificationToken"]').val());
                        },
                        success: function () { alert('Some action done successfully.'); }
                    })
            });
        });
    </script>
}

在您的启动中,添加:

//...
services.AddAntiforgery(o => o.HeaderName = "XSRF-TOKEN");

Index.chtml.cs:

    [BindProperty]
    public string MyProperty { get; set; }
    public void OnGet()
    {
    }
    public IActionResult OnPost()
    {
        //...
        return Page();
    }

MyAction 控制器class:

[Route("api/[controller]")]
[ApiController]
public class MyActionController : ControllerBase
{
    [HttpPost("doSomeAction/{code?}")]
    public async Task<dynamic> PostAsync(int code)
    {
        return "Ok";
    }
}

测试结果: