MortenMoulder
MortenMoulder

Reputation: 6648

Saving all GET/page requests to database in Blazor

I'm looking for a way to integrate my own kind of "Google Analytics" logging into my Blazor application. What I would normally do if this was a .NET Core application, is that I would write some JavaScript that calls a controller endpoint, which then adds it to the database at some point. If I do that, the application won't halt or wait for the database request, because the frontend sent the call.

I'm not sure how I would do that in Blazor. I've looked at overriding the OnAfterRender method:

protected override void OnAfterRender(bool firstRender)
{
    if (firstRender)
    {
        
    }
}

And then placed that in my MainLayout.razor file. That could work, however, firstRender is only true if I refresh the page (F5). OnAfterRender gets called every time, but on a single page load, I've seen it hit it a couple of times in the same page render.

Say I want to log every request - how would I go about that? I don't want the page load to wait for the database request, because that could easily be done in the background. If anything, adding every "request model" to a static/singleton list, which gets saved to the database every x seconds.

Upvotes: 0

Views: 334

Answers (1)

MrC aka Shaun Curtis
MrC aka Shaun Curtis

Reputation: 30001

Add an Analytics service

    public class AnalyticsService
    {
        private string _currentUrl = string.Empty;

        public void PostURL(string url)
        {
            if (!this._currentUrl.Equals(url))
            {
                _currentUrl = url;
                PostToAnalytics();
            }
        }

        private async void PostToAnalytics()
        {
            //  use httpClient to post data
            // await HttpClient.PostAsync()
            // emulated post
            await Task.Delay(100);
            Debug.WriteLine($"Analytics - {_currentUrl}");
        }
    }

Register it as Scoped in the Services Container.

Create an AnalyticsControl component.

    public class AnalyticsControl : ComponentBase
    {
        [Inject] private AnalyticsService analyticsService { get; set; }

        [Inject] private NavigationManager navManager { get; set; }

        protected override void OnParametersSet()
        {
            this.analyticsService.PostURL(navManager.Uri);
            base.OnParametersSet();
        }
    }

Update "MainLayout" and any other layouts.

@inherits LayoutComponentBase

<div class="page">
    <div class="sidebar">
        <NavMenu />
    </div>

    <div class="main">
        <div class="top-row px-4">
            <a href="https://learn.microsoft.com/aspnet/" target="_blank">About</a>
        </div>

        <div class="content px-4">
            @Body
        </div>
    </div>
</div>
<AnalyticsControl Counter="counter"/>

@code {

    int counter = 0;

        protected override void OnParametersSet()
        {
        counter++;
        }
}

The incrementing counter is just a mechanism to force a SetParametersAsync cycle on the AnalyticsControl. At the moment it just yields with a delay and logs the event to the output. You should use the HttpClient to post whatever data you want to to the controller.

Upvotes: 2

Related Questions