I have an internal ASP.NET Core application using Razor Pages and I would like to track who and when the application is accessed. I have a SQL table to store the values I collect. My Razor Page (partial) code is this:
<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# code behind is this:
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
_context.tracking.Add(tracking);
await _context.SaveChangesAsync();
return Page();
}
This results in an infinite loop where the form is submitted and the page is reloaded and the form is submitted and the page reloaded......
I have tried using "onunload" and "onbeforeunload" and neither work. Is there a better way to do this or am I missing something simple?
You're getting into a loop because you're POSTing and returning the page again. Fire and forget the request with JavaScript to an API controller. Presumably, you have a class like this:
public class Tracking
{
public string Name { get; set; }
public DateTime Time { get; set; }
}
So we'll make use of that in the following controller:
[Route("api/[controller]")]
[ApiController]
public class TrackingController : ControllerBase
{
[HttpPost]
public IActionResult Index([FromBody] Tracking tracking)
{
return NoContent();
}
}
Underneath your page, in the .cshtml
file, add:
@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>
}
If you've not setup controllers in your project yet, you'll need to call
services.AddControllers();
in Startup.ConfigureServices()
and modify app.UseEndpoints()
in the same file to something like:
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
// Your current routes.
});
otherwise it won't find the controller.
One other thing: DateTime.Now
won't be a valid JSON date, so you should either get the date on the client-side, or look at serialising it to the hidden field first. If you don't do that, the POST will fail.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.