Analytics for .NET

Community ✓
Maintenance x
Flagship x
?

Segment doesn't manage or update community libraries. These libraries are available on GitHub under the MIT License for the open-source community to fork or contribute.


Segment’s .NET library is the best way to integrate analytics into your .NET application or website. It lets you record analytics data from your ASP.NET, C#, F#, and Visual Basic code. The library issues requests that hit Segment’s servers, and then Segment routes your data to any analytics service you enable on our destinations page. This library is open-source, so you can check it out on GitHub.

All of Segment’s server-side libraries are built for high-performance, so you can use them in your web server controller code. This library uses an internal queue to make Identify and Track calls non-blocking and fast. It also batches messages and flushes asynchronously to Segment’s servers.

Analytics-CSharp (C#)

With Analytics-CSharp, you can add Segment analytics to your C# based app which includes .NET. If you’d like to migrate to use Analytics-CSharp, see the Analytics-CSharp migration guide.

Getting Started

Client-side vs Server-side

The best analytics installation combines both client-side and server-side tracking. A client-side analytics.js installation allows you to install A/B testing, heat mapping, session recording, and ad optimization tools. A server-side .NET installation allows you to accurately track events that aren’t available client-side, such as payments. For best practices, check out Segment’s guide to client-side vs. server-side.

Step 1: Add Analytics.js to your ASP.NET Master Page

  1. In your Segment workspace, click Catalog, and search for “Net”.
  2. Click the .Net tile, then click Add Source.
  3. Give the new source a label (which you’ll use to identify it later), and apply any labels such as prod or test.

You will then be presented with an Analytics.js snippet.

Copy the snippet directly into your ASP.NET Site.master.

That snippet will load analytics.js onto the page asynchronously, so it won’t affect your page load speed.

As soon as that snippet is running on your site, you can start turning on any destinations on your Segment destinations page. In fact, if you reload, you can start seeing Page calls in the source debugger.

For more in depth analytics.js information, check out Segment’s analytics.js docs.

Lots of analytics and marketing tools want to know more information about your users, and what they’re doing on your app. In the next section, Segment installs the .NET library and start sending an event every time a new user registers on your site.

Step 2: Install Segment’s .NET Library

Your website will use Segment’s .NET library to Identify and Track users. You can use NuGet to install the library.

Install-Package Analytics -Version <version>

Note: the Analytics package has a dependency on Newton.JSON.

You can also accomplish the same thing in the Visual Studio Tools menu, select Library Package Manager and then click Package Manager Console.

Now the .NET library needs to know which Segment project you want to send data to. You can initialize the library with your Segment source’s writeKey in the Global.asax file. Then you can use the Analytics singleton in any controller you want:

<%@ Application Language="C#" %>
<%@ Import Namespace="ASP.NET_Example" %>
<%@ Import Namespace="System.Web.Optimization" %>
<%@ Import Namespace="System.Web.Routing" %>
<%@ Import Namespace="Segment" %>

<script runat="server">

    void Application_Start(object sender, EventArgs e)
    {
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);
        // this is your project's write key
        Segment.Analytics.Initialize("x24b2rmtvv");
    }

</script>
using Segment;

// initialize the project #{source.owner.login}/#{source.slug}...
Analytics.Initialize("YOUR_WRITE_KEY");

You only need to initialize once at the start of your program. You can then keep using the Analytics singleton anywhere in your code.

The default initialization settings are production-ready and queue messages on another thread before sending any requests. In development you might want to use development settings.

Regional configuration

For Business plans with access to Regional Segment, you can use the host configuration parameter to send data to the desired region:

  1. Oregon (Default) — api.segment.io/
  2. Dublin — events.eu1.segmentapis.com/

Identify

Good to know: For any of the different methods described on this page, you can replace the properties and traits in the code samples with variables that represent the data collected.

If you’re not familiar with the Segment Specs, take a look to understand what the Identify method does.

The Identify call has the following fields:

userId String The ID for this user in your database.
Traits Traits, optional A dictionary of traits you know about the user. Things like: email, name or friends.
options Options, optional A custom object which allows you to set a timestamp, an anonymous cookie id, or enable specific destinations.

An example call would look like:

Analytics.Client.Identify("019mr8mf4r", new Traits() {
    { "name", "#{ user.name }" },
    { "email", "#{ user.email }" },
    { "friends", 29 }
});

Track

If you’re not familiar with the Segment Spec, take a look to understand what the Track method does.

The Track call has the following fields:

userId String The ID for this user in your database.
event String The name of the event you’re tracking. Segment recommends human-readable names like Song Played or Status Updated.
properties Properties, optional A dictionary of properties for the event. If the event was Product Added to cart, it might have properties like price or product.
options Options, optional A custom object which allows you to set a timestamp, an anonymous cookie id, or enable specific destinations.

An example call would look like:

Analytics.Client.Track("019mr8mf4r", "Item Purchased", new Properties() {
    { "revenue", 39.95 },
    { "shipping", "2-day" }
});

Page

If you’re not familiar with the Segment Specs, take a look to understand what the Page method does.

The Page call has the following fields:

userId String The ID for this user in your database.
name String The webpage name you’re tracking. Segment recommends human-readable names like Login or Register.
category String The webpage category. If you’re making a news app, the category could be Sports.
properties Properties, optional A dictionary of properties for the webpage visit. If the event was Login, it might have properties like path or title.
options Options, optional A custom object which allows you to set a timestamp, an anonymous cookie id, or enable specific destinations.

Example Page call:

Analytics.Client.Page("019mr8mf4r", "Login", new Properties() {
    { "path", "/login" },
    { "title", "Initech Login" }
});

Screen

If you’re not familiar with the Segment Specs, take a look to understand what the Screen method does.

The Screen call has the following fields:

userId String The ID for this user in your database.
name String The screen name you’re tracking. Segment recommends human-readable names like Login or Register.
category String The screen category. If you’re making a news app, the category could be Sports.
properties Properties, optional A dictionary of properties for the screen view. If the screen is Restaurant Reviews, it might have properties like reviewCount or restaurantName.
options Options, optional A custom object which allows you to set a timestamp, an anonymous cookie id, or enable specific destinations.

Example Screen call:

Analytics.Client.Screen("019mr8mf4r", "Register", new Properties() {
    { "type", "facebook" }
});

Group

If you’re not familiar with the Segment Specs, take a look to understand what the Group method does.

The Group call has the following fields:

userId String The ID for this user in your database.
groupId String The ID for this group in your database.
traits Traits, optional A dictionary of traits you know about the group. Things like: ma,e or website.
options Options, optional A custom object which allows you to set a timestamp, an anonymous cookie id, or enable specific destinations.

Example Group call:

Analytics.Client.Group("userId", "groupId", new Traits() {
    { "name", "Initech, Inc." },
    { "website", "http://www.example.com" }
});

Alias

If you’re not familiar with the Segment Specs, take a look to understand what the Alias method does.

The Alias call has the following fields:

previousId String The previousId for this user.
userId String The ID for this user in your database.

Example Alias call:

Analytics.Client.Alias("previousId", "userId")

Here’s a full example of how you might use the Alias call:

// the anonymous user does actions ...
Analytics.Client.Track("anonymous_user", "Anonymous Event");
// the anonymous user signs up and is aliased
Analytics.Client.Alias("anonymous_user", "identified@example.com");
// the identified user is identified
Analytics.Client.Identify("identified@example.com", new Traits() { plan: "Free" });
// the identified user does actions ...
Analytics.Client.Track("identified@example.com", "Identified Action");

Development Settings

You can use this initialization during development while testing the library. SetAsync(false) will make sure the library makes a request to Segment’s servers every time it’s called.

Analytics.Initialize("YOUR_WRITE_KEY", new Config().SetAsync(false));

Don’t forget to set async back to true for production, so that you can advantage of asynchronous flushing on a different thread.

Historical Import

You can import historical data by adding the timestamp argument to any of your method calls. This can be helpful if you’ve just switched to Segment.

Historical imports can only be done into destinations that can accept historical timestamped data. Most analytics tools like Mixpanel, Amplitude, Kissmetrics, etc. can handle that type of data just fine. One common destination that does not accept historical data is Google Analytics since their API cannot accept historical data.

Note: If you’re tracking things that are happening right now, leave out the timestamp and Segment’s servers will timestamp the requests for you.

Analytics.Client.Track("sadi89e2jd", "Workout Logged", new Properties() {
    { "distance", "10 miles" },
    { "city", "Boston" },
}, new Options()
    .SetTimestamp(new DateTime(2010, 1, 18))
);

Selecting Destinations

The Alias, Group, Identify, Page, and Track calls can all be passed an object of options that lets you turn certain destinations on or off. By default all destinations are enabled.

You can specify which analytics destinations you want each action to go to.

Analytics.Client.Identify("hj2kf92ds212", new Traits() {
    { "email", "tom@example.com" },
    { "name", "Tom Smykowski" },
}, new Options()
    .SetIntegration("all", false)
    .SetIntegration("Kissmetrics", true)
);

In this case, you’re specifying that you want this identify to only go to Kissmetrics. "all", false says that no destination should be enabled unless otherwise specified, and { "Kissmetrics", true } turns on Kissmetrics.

Destination flags are case sensitive and match the destination’s name in the docs (for example, “AdLearn Open Platform”, “awe.sm”, or “MailChimp”).

Note:

  • Business Tier users can filter Track calls right from the Segment UI on your source schema page. Segment recommends using the UI if possible since it’s a much simpler way of managing your filters and can be updated with no code changes on your side.

  • If you are on a grandfathered plan, events sent server-side that are filtered through the Segment dashboard still count towards your API usage.

Context

If you’re running a web server, you might want to send context variables such as userAgent or ip with your page or screen calls. You can do so by setting the Context in the Options object.

Analytics.Client.Page("019mr8mf4r", "Login", new Properties() {
    { "path", "/login" },
    { "title", "Initech Login" }
}, new Options()
    .SetContext (new Context () {
        { "userAgent", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36"},
        { "ip", "12.212.12.49" },
        { "language", "en-us" },
        { "Google Analytics", new Dict() {
          { "clientId", User.ClientId }
          }
        }
}));

Anonymous ID

All libraries require all messages to have either a userId or anonymousId. If you would like to use an anonymousId, which you should for anonymous users, you can pass it in with options.

Analytics.Client.Page(null, "Login", new Properties(), new Options()
    .SetAnonymousId("some-id"));

Nested Properties

You can provide nested properties, like so:

Analytics.Client.Identify("hj2kf92ds212", new Traits() {
    { "email", "tom@example.com" },
    { "name", "Tom Smykowski" },
    { "address", new Dict() {
        { "street", "123 Fake Street" },
        { "city", "Boston" }
    }}
});

Batching

Segment’s libraries are built to support high performance environments. That means it is safe to use Analytics.NET on a web server that’s serving hundreds of requests per second.

By default (in async mode), this library starts a single separate thread on initialization, and flushes all messages on that thread. That means every method you call does not result in an HTTP request, but is queued in memory instead. Messages are flushed in batch in the background, which allows for much faster operation.

There is a maximum of 500KB per batch request and 32KB per call.

HTTP Tracking API limits

Segment's HTTP Tracking API accepts batch requests up to 500KB. To avoid errors in event creation, ensure that individual event payload sizes remain below 32KB.

How do I turn batching off?

Sometimes you might not want batching (for example, when debugging, or in short-lived programs). You can turn off batching by setting the async argument to false, and your requests will always be sent in a blocking manner.

Analytics.Initialize("YOUR_WRITE_KEY", new Config().SetAsync(false));

What happens if there are just too many messages?

If the module detects that it can’t flush faster than it’s receiving messages, it’ll simply stop accepting messages. This means your program will never crash because of a backing up analytics queue. The maximum size of the queue defaults to 10000, and here’s how you can change it:

Analytics.Initialize("YOUR_WRITE_KEY", new Config().SetMaxQueueSize(10000));

How do I flush right now?!

You can also flush on demand. For example, at the end of your program, you’ll want to flush to make sure there’s nothing left in the queue. Just call the Flush method:

Analytics.Client.Flush();

This method will block until all messages are flushed.

How do I dispose of the flushing thread at the end of my program?

The Analytics client implements the IDisposable interface, and will turn off its flushing thread when you call Dispose.

Analytics.Client.Dispose();

Configuration

If you hate defaults, than you’ll love how configurable the Analytics.NET is. Check out these gizmos:

Analytics.Initialize("YOUR_WRITE_KEY", new Config()
    .SetAsync(true)
    .SetTimeout(TimeSpan.FromSeconds(10))
    .SetHost("https://events.eu1.segmentapis.com")
    .SetMaxQueueSize(10000));));
async boolean true to flush on a different thread, false to flush immediately on the same thread.
timeout TimeSpan The amount of time to wait before calling the HTTP request a timeout.
host string The API host server address - can be set with the EU endpoint “https://events.eu1.segmentapis.com” instead of default server “https://api.segment.io”
maxQueueSize int The maximum number of messages to allow into the queue before no new message are accepted.

Multiple Clients

Different parts of your app may require different Segment. In that case, you can initialize different Analytics.Client instances instead of using the singleton.

Client client = new Client("YOUR_WRITE_KEY", new Config()
    .SetAsync(false)
    .SetTimeout(TimeSpan.FromSeconds(10))
    .SetMaxQueueSize(10000));

client.Track(...);

Troubleshooting

The following tips often help resolve common issues.

No events in my debugger

  1. Double check that you’ve followed all the steps in the Quickstart.

  2. Make sure that you’re calling a Segment API method once the library is successfully installed—identify, track, etc.

  3. Make sure your application isn’t shutting down before the Analytics.Client local queue events are pushed to Segment. You can manually call Analytics.Client.Flush() to ensure the queue is fully processed before shutdown.

Other common errors

If you are experiencing data loss from your .NET source, you may be experiencing one or more of the following common errors:

  • Payload is too large: If you attempt to send events larger than 32KB per normal API request or batches of events larger than 500KB per request, Segment’s tracking API responds with 400 Bad Request. Try sending smaller events (or smaller batches) to correct this error.

  • Identifier is not present: Segment’s tracking API requires that each payload has a userId and/or anonymousId. If you send events without either the userId or anonymousId, Segment’s tracking API responds with an no_user_anon_id error. Check the event payload and client instrumentation for more details.

  • Track event is missing name: All Track events to Segment must have a name in string format.

  • Event dropped during deduplication: Segment automatically adds a messageId field to all payloads and uses this value to deduplicate events. If you’re manually setting a messageId value, ensure that each event has a unique value.

  • Incorrect credentials: Double check your credentials for your downstream destination(s).

  • Destination incompatibility: Make sure that the destination you are troubleshooting can accept server-side API calls. You can see compatibility information on the Destination comparison by category page and in the documentation for your specific destination.

  • Destination-specific requirements: Check out the destination’s documentation to see if there are other requirements for using the method and destination that you’re trying to get working.

Logging

Analytics.NET has detailed logging, which you can enable by attaching your own handler, like so:

using Segment;

Logger.Handlers += LoggingHandler;

static void LoggingHandler(Logger.Level level, string message, IDictionary<string, object> args)
{
      if (args != null)
      {
           foreach (string key in args.Keys)
           {
                 message += String.Format(" {0}: {1},", "" + key, "" + args[key]);
           }
      }
      Console.WriteLine(String.Format("[Analytics] [{0}] {1}", level, message));
}

Note: the logger requires a minimum version of .NET Core 2.1.

Json.NET

Analytics.NET uses Json.NET to serialize JSON payloads. If you have an older version of Json.NET in your build path, Analytics.NET could create incomplete JSON payloads, which can cause strange API responses. If you’re seeing issues, try updating Json.NET.

Mono

Analytics.NET has been tested and works in Mono.

.NET Core

Analytics.NET has been tested and works with .NET Core 3.1 and 3.4.2 beta.

This page was last modified: 30 May 2024



Get started with Segment

Segment is the easiest way to integrate your websites & mobile apps data to over 300 analytics and growth tools.
or
Create free account