简体   繁体   中英

Auto post a form on page load (Razor Pages)

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM