在页面加载时自动发布表单(剃刀页面)

时间:2020-10-02 18:26:37

标签: c# razor

我有一个使用Razor Pages的内部ASP.NET Core应用程序,我想跟踪谁和何时访问该应用程序。我有一个SQL表来存储我收集的值。我的Razor Page(部分)代码是这样的:

<form method="post" name="track" id="track">
    <input type="hidden" asp-for="tracking.Name" value="@User.Identity.Name" />
    <input type="hidden" asp-for="tracking.Time" value="@DateTime.Now" />
</form>

后面的C#代码是:

public async Task<IActionResult> OnPostAsync()
    {
            if (!ModelState.IsValid)
        {
            return Page();
        }
        _context.tracking.Add(tracking);
        await _context.SaveChangesAsync();

        return Page();
    }

这将导致无限循环,在此循环中,提交表单并重新加载页面,提交表单并重新加载页面……

我尝试使用“ onunload”和“ onbeforeunload”,但均无效。有没有更好的方法可以做到这一点,或者我是否缺少简单的东西?

1 个答案:

答案 0 :(得分:0)

由于进入POST并再次返回页面,您陷入了循环。使用JavaScript触发并忘记对API控制器的请求。大概您有一个这样的类:

public class Tracking
{
    public string Name { get; set; }
    public DateTime Time { get; set; }
}

因此,我们将在以下控制器中使用它:

[Route("api/[controller]")]
[ApiController]
public class TrackingController : ControllerBase
{
    [HttpPost]
    public IActionResult Index([FromBody] Tracking tracking)
    {
        return NoContent();
    }
}

在页面下方的.cshtml文件中,添加:

@section Scripts {
    <script type="text/javascript">
        $(function () {
            // Notice the underscores.
            var data = {
                "name": $("#Tracking_Name").val(),
                "time": $("#Tracking_Time").val()
            };

            $.ajax({
                type: "POST",
                url: "/api/tracking",
                data: JSON.stringify(data),
                contentType: "application/json"
            });
        });
    </script>
}

如果您尚未在项目中设置控制器,则需要调用

services.AddControllers();
Startup.ConfigureServices()

并将同一文件中的app.UseEndpoints()修改为:

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllers();
    // Your current routes.
});

否则它将找不到控制器。

另一件事:DateTime.Now不是有效的JSON日期,因此您应该在客户端获取日期,或者首先考虑将其序列化到隐藏字段。如果不这样做,则POST将失败。