-
Notifications
You must be signed in to change notification settings - Fork 73
ASP.NET Core Integration
This page covers the minimal demo API bundled with the repository and a recommended dependency-injection pattern for using DeviceDetector.NET directly in application logic. For logging integration, see the dedicated Serilog.Enrichers.AspNetCore.DeviceDetector page.
HomeController exposes a single GET /Home endpoint that parses the caller's User-Agent and Client Hints and returns the full result as JSON — handy as a quick manual test/demo of what the library reports for your current browser:
[HttpGet]
public object Get()
{
DeviceDetector.SetVersionTruncation(VersionTruncation.VERSION_TRUNCATION_NONE);
var userAgent = Request.Headers.UserAgent;
var headers = Request.Headers.ToDictionary(a => a.Key, a => a.Value.ToArray().FirstOrDefault());
var clientHints = ClientHints.Factory(headers);
var result = DeviceDetector.GetInfoFromUserAgent(userAgent, clientHints);
return result;
}Run it locally to see the shape of ParseResult<DeviceDetectorResult> returned by GetInfoFromUserAgent for any real request hitting your dev machine.
Issue #83 raised a fair complaint: there's no built-in IServiceCollection extension, and the library isn't itself injectable — DeviceDetector is a per-parse object you construct with a User-Agent, not a long-lived service. If what you want is @inject a service and call IsMobile(Request) from a Razor page or controller with no further ceremony, wrap it yourself with a small service like this:
public interface IDeviceDetectionService
{
bool IsMobile(HttpRequest request);
DeviceDetector Detect(HttpRequest request);
}
public class DeviceDetectionService : IDeviceDetectionService
{
public DeviceDetector Detect(HttpRequest request)
{
var headers = request.Headers.ToDictionary(a => a.Key, a => a.Value.ToArray().FirstOrDefault());
var clientHints = ClientHints.Factory(headers);
var dd = new DeviceDetector(request.Headers.UserAgent, clientHints);
dd.Parse();
return dd;
}
public bool IsMobile(HttpRequest request) => Detect(request).IsMobile();
}Register it once, as a singleton — the service itself holds no per-request state, so one instance can safely serve every request:
builder.Services.AddSingleton<IDeviceDetectionService, DeviceDetectionService>();Then, in a Razor page or controller:
@inject IDeviceDetectionService DeviceDetection
@if (DeviceDetection.IsMobile(Context.Request))
{
<p>Mobile layout</p>
}Not by default. new DeviceDetector(...) followed by Parse() already benefits from the process-wide fragment cache described in Caching with zero extra setup — SetCache(new DictionaryCache()) is what DeviceDetector uses internally already; calling it explicitly only matters if you want to swap in a different ICache implementation. Creating a fresh DeviceDetector instance per request is intentional and cheap: instances are lightweight, and the data they end up reusing (regex fragment results) already lives in a shared static cache, not in the instance itself.
If profiling shows parsing itself (not instance allocation) is a bottleneck under load, and you don't need Client Hints for the check in question, swap Detect's body for LRUCachedDeviceDetector.GetDeviceDetector(userAgent) instead of constructing a new instance — see the Caching page for why that trade-off (no Client Hints support) exists and when it's worth it.
- Use the Serilog enricher for anything you want automatically attached to all logs for a request (errors, warnings, audit trails).
- Use
DeviceDetector.GetInfoFromUserAgentdirectly, or the DI wrapper above, when you need the parsed result in application logic, not just in logs (e.g. serving a different response for mobile vs. desktop).
DeviceDetector.NET is a .NET port of matomo-org/device-detector · Licensed under Apache 2.0 · Report an issue