我有一个使用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”,但均无效。有没有更好的方法可以做到这一点,或者我是否缺少简单的东西?
答案 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将失败。