diff --git a/src/connections/sources/catalog/libraries/mobile/xamarin/index.md b/src/connections/sources/catalog/libraries/mobile/xamarin/index.md index 00840c753b..e6266027a9 100644 --- a/src/connections/sources/catalog/libraries/mobile/xamarin/index.md +++ b/src/connections/sources/catalog/libraries/mobile/xamarin/index.md @@ -20,7 +20,7 @@ The library issues requests that hit our servers, and then we route your data to **Note:** Since Xamarin requires Segment's library to be portable to different builds, Segment can only enable server-side destinations, as opposed to bundling select native SDKs like we do for iOS and Android. Look for the "Server" icon when selecting destinations. For tools for which we offer both bundled and server-side destinations, like Mixpanel, Amplitude, and Google Analytics, Segment's Xamarin library will only be able to use their server-side functionality. > info "Analytics-CSharp (C#)" -> With Analytics-CSharp, you can add Segment analytics to your C# based app which includes Xamarin. The [Analytics-CSharp library](/docs/connections/sources/catalog/libraries/server/csharp/) is currently in beta and is governed by Segment’s [First Access and Beta terms](https://www.twilio.com/legal/tos){:target="_blank"}. If you'd like to migrate to use Analytics-CSharp, see the [Analytics-CSharp migration guide](/docs/connections/sources/catalog/libraries/server/csharp/migration-guide/). +> With [Analytics-CSharp](/docs/connections/sources/catalog/libraries/server/csharp/), you can add Segment analytics to your C# based app which includes Xamarin. If you'd like to migrate to use Analytics-CSharp, see the [Analytics-CSharp migration guide](/docs/connections/sources/catalog/libraries/server/csharp/migration-guide/). ## Getting Started diff --git a/src/connections/sources/catalog/libraries/server/csharp/index.md b/src/connections/sources/catalog/libraries/server/csharp/index.md index e5fbd0315d..2755346fa1 100644 --- a/src/connections/sources/catalog/libraries/server/csharp/index.md +++ b/src/connections/sources/catalog/libraries/server/csharp/index.md @@ -1,5 +1,5 @@ --- -title: Analytics for CSharp (C#) +title: Analytics-CSharp (C#) strat: csharp id: redirect_from: @@ -9,8 +9,6 @@ redirect_from: With Analytics-CSharp, you can add Segment analytics to your C# based app which includes Unity, Xamarin, .NET. Analytics-CSharp helps you measure your users, product, and business. It unlocks insights into your app's funnel, core business metrics, and whether you have product-market fit. The Analytics-CSharp library is open-source [on GitHub](https://github.com/segmentio/analytics-csharp){:target="_blank"}. -> info "" -> This library is currently in beta and is governed by Segment’s [First Access and Beta terms](https://www.twilio.com/legal/tos){:target="_blank"}. ### Supported platforms These platforms support Analytics-CSharp: @@ -36,12 +34,15 @@ To get started with the Analytics-CSharp library: 1. Create a Source in Segment. 1. Go to **Connections > Sources > Add Source**. 2. Search for *Xamarin, Unity, or .NET* (whichever source you want to use) and click **Add Source**. **Note:** There is no CSharp source. To use Analytics-CSharp, use either Xamarin, Unity, or .NET as your source. -2. Add the Analytics dependency to your project. +2. Add the Analytics dependency to your project. Analytics-CSharp is distributed through NuGet. Check other installation options [here](https://www.nuget.org/packages/Segment.Analytics.CSharp/). - ```git + ``` dotnet add package Segment.Analytics.CSharp --version ``` -
**Note:** Analytics-CSharp is distributed through NuGet. Check out other installation options [here](https://www.nuget.org/packages/Segment.Analytics.CSharp/){:target="_blank"}. For Unity, Analytics-Chsharp is distributed through [OpenUPM](https://openupm.com/packages/com.segment.analytics.csharp/?subPage=readme){:target="_blank"}. + For Unity, Analytics-CSharp is distributed through OpenUPM. Read more about [OpenUPM](https://openupm.com/packages/com.segment.analytics.csharp/?subPage=readme){:target="_blank"}. + ``` + openupm add com.segment.analytics.csharp + ``` 3. Initialize and configure the client. @@ -49,23 +50,24 @@ To get started with the Analytics-CSharp library: // NOTE: to make Analytics stateless/in-memory, // add `InMemoryStorageProvider` to the configuration var configuration = new Configuration("", - flushAt: 1, - flushInterval: 10); + flushAt: 20, + flushInterval: 30); var analytics = new Analytics(configuration); ``` - These are the options you can apply to configure the client: - - Option Name | Description - ----------- | ----------- - `writeKey` *required* | This is your Segment write key. - `apiHost` | The default is set to `api.segment.io/v1`.
This sets a default API Host to which Segment sends events. - `autoAddSegmentDestination` | The default is set to `true`.
This automatically adds the Segment Destination plugin. You can set this to `false` if you want to manually add the Segment Destination plugin. - `defaultSettings` | The default is set to `{}`.
The settings object used as fallback in case of network failure. - `flushAt` | The default is set to `20`.
The count of events at which Segment flushes events. - `flushInterval` | The default is set to `30` seconds.
The interval in seconds at which Segment flushes events. - `exceptionHandler` | Use to set an exception handler to handle errors happened in async methods within the analytics scope. - `storageProvider` | Use to set how you want your data to be stored.
`DefaultStorageProvider` is used by default which stores data to local storage. `InMemoryStorageProvider` is also provided in the library. You can also write your own storage solution by implementing `IStorageProvider` and `IStorage`. +| Option Name | Description | +|-----------------------------|---------------| + | `writeKey` *required* | This is your Segment write key. | +| `flushAt` | The default is set to `20`.
The count of events at which Segment flushes events. | +| `flushInterval` | The default is set to `30` (seconds).
The interval in seconds at which Segment flushes events. | +| `defaultSettings` | The default is set to `{}`.
The settings object used as fallback in case of network failure. | +| `autoAddSegmentDestination` | The default is set to `true`.
This automatically adds the Segment Destination plugin. You can set this to `false` if you want to manually add the Segment Destination plugin. | + | `apiHost` | The default is set to `api.segment.io/v1`.
This sets a default API Host to which Segment sends events. | +| `cdnHost` | The default is set to `cdn-settings.segment.com/v1`.
This sets a default cdnHost to which Segment fetches settings. | +| `analyticsErrorHandler` | The default is set to `null`.
This sets an error handler to handle errors happened in analytics. | + | `storageProvider` | The default is set to `DefaultStorageProvider`.
This sets how you want your data to be stored. `DefaultStorageProvider` is used by default which stores data to local storage. `InMemoryStorageProvider` is also provided in the library. You can also write your own storage solution by implementing `IStorageProvider` and `IStorage`. | +| `httpClientProvider` | The default is set to `DefaultHTTPClientProvider`.
This sets a http client provider for analytics use to do network activities. The default provider uses System.Net.Http for network activities. | +| `flushPolicies` | The default is set to `null`.
This sets custom flush policies to tell analytics when and how to flush. By default, it converts `flushAt` and `flushInterval` to `CountFlushPolicy` and `FrequencyFlushPolicy`. If a value is given, it overwrites `flushAt` and `flushInterval`. | ## Tracking Methods @@ -323,7 +325,216 @@ The `reset` method clears the SDK’s internal stores for the current user and g analytics.Reset() ``` -## Arrays + +## Flush policies +To more granularly control when events are uploaded you can use `FlushPolicies`. + +> warning "" +> `FlushPolicies` overrides any setting on `flushAt` and `flushInterval`, but you can use `CountFlushPolicy` and `FrequencyFlushPolicy` to have the same behavior. + +A Flush Policy defines the strategy for deciding when to flush. This can be on an interval, on a certain time of day, after receiving a certain number of events or even after receiving a particular event. This gives you even more flexibility on when to send an event to Segment. + +To make use of flush policies you can set them in the configuration of the client: +```csharp + var configuration = new Configuration("", + flushPolicies: new List + { + new CountFlushPolicy(), + new FrequencyFlushPolicy(), + new StartupFlushPolicy() + }); + var analytics = new Analytics(configuration); +``` + +That means only the first policy to reach `ShouldFlush` gets to trigger a flush at a time. In the example above either the event count gets to 5 or the timer reaches 500ms, whatever comes first will trigger a flush. + +Segment has several standard FlushPolicies: +- `CountFlushPolicy` triggers whenever a certain number of events is reached +- `FrequencyFlushPolicy` triggers on an interval of milliseconds +- `StartupFlushPolicy` triggers on client startup only + +### Adding or removing policies + +One of the main advantages of FlushPolicies is that you can choose to add and remove policies. This is very powerful when you want to reduce or increase the amount of flushes. + +For example, you might want to disable flushes if you detect the user has no network: +```csharp + // listen to network changes + if (noNetwork) { + // remove all flush policies to avoid flushing + analytics.ClearFlushPolicies(); + + // or disable analytics completely (including store events) + analytics.Enable = false + } + else { + analytics.AddFlushPolicy(new CountFlushPolicy(), new FrequencyFlushPolicy()); + } +``` + +### Create your own flush policies + +You can create a custom FlushPolicy special for your application needs by implementing the `IFlushPolicy` interface. You can also extend the `FlushPolicyBase` class that already creates and handles the `shouldFlush` value reset. + +A `FlushPolicy` only needs to implement two of these methods: +- `Schedule`: Executed when the flush policy is enabled and added to the client. This is a good place to start background operations, make async calls, configure things before execution +- `UpdateState`: Gets called on every event tracked by your client +- `Unschedule`: Called when policy should stop running any scheduled flushes +- `Reset`: Called after a flush is triggered (either by your policy, by another policy or manually) + +Your `FlushPolicy` should also have a `ShouldFlush` observable boolean value. When this is set to true the client attempts to upload events. Each policy should reset this value to `false` according to its own logic. + +```csharp +class FlushOnScreenEventsPolicy : IFlushPolicy +{ + private bool _screenEventsSeen = false; + + public bool ShouldFlush() => _screenEventsSeen; + + public void UpdateState(RawEvent @event) + { + // Only flush when at least a screen even happens + if (@event is ScreenEvent) + { + _screenEventsSeen = true; + } + } + + public void Reset() + { + _screenEventsSeen = false; + } + + public void Schedule(Analytics analytics) {} + + public void Unschedule() {} +} +``` + +## Handling Errors +You can handle analytics client errors through the `analyticsErrorHandler` option. + +The error handler configuration requires an instance that implements `IAnalyticsErrorHandler` which will get called whenever an error happens on the analytics client. It will receive a general `Exception`, but you can check if the exception is a type of `AnalyticsError` and converts to get more info about the error. Checkout [here](https://github.com/segmentio/Analytics-CSharp/blob/main/Analytics-CSharp/Segment/Analytics/Errors.cs#L77) to see a full list of error types that analytics throws. + +You can use this error handling to trigger different behaviours in the client when a problem occurs. For example if the client gets rate limited you could use the error handler to swap flush policies to be less aggressive: + +```csharp +class NetworkErrorHandler : IAnalyticsErrorHandler +{ + private Analytics _analytics; + + public NetworkErrorHandler(Analytics analytics) + { + _analytics = analytics; + } + + public void OnExceptionThrown(Exception e) + { + if (e is AnalyticsError error && error.ErrorType == AnalyticsErrorType.NetworkServerLimited) + { + _analytics.ClearFlushPolicies(); + // Add less persistent flush policies + _analytics.AddFlushPolicy(new CountFlushPolicy(1000), new FrequencyFlushPolicy(60 * 60 * 1000)); + } + } +} +``` + +### Reporting errors from plugins + +Plugins can also report errors to the handler by using the [`.ReportInternalError`](https://github.com/segmentio/Analytics-CSharp/blob/main/Analytics-CSharp/Segment/Analytics/Errors.cs#L54) function of the analytics client, we recommend using the `AnalyticsErrorType.PluginError` for consistency, and attaching the `exception` with the actual exception that was hit: + +```csharp + try + { + // do something; + } + catch (Exception e) + { + this.Analytics.ReportInternalError(AnalyticsErrorType.PluginError, e, "Error from plugin"); + Analytics.Logger.Log(LogLevel.Error, e); + } +``` + +### Listen to Analytics Logs + +Besides error handling, you could also provide a static `ISegmentLogger` to help log and debug as well as error handling. The same log that is reported by `ReportInternalError` is also reported to this static logger. The static logger also receives more errors and exceptions because it does not require an `Analytics` instance available. Thus, it's also a good idea to use the logger as an addition to `IAnalyticsErrorHandler`. +```csharp +Analytics.Logger = new SegmentLogger(); + +class SegmentLogger : ISegmentLogger +{ + public void Log(LogLevel logLevel, Exception exception = null, string message = null) + { + switch (logLevel) + { + case LogLevel.Warning: + case LogLevel.Information: + case LogLevel.Debug: + Console.Out.WriteLine("Message: " + message); + break; + case LogLevel.Critical: + case LogLevel.Trace: + case LogLevel.Error: + Console.Error.WriteLine("Exception: " + exception?.StackTrace); + Console.Error.WriteLine("Message: " + message); + break; + case LogLevel.None: + default: + break; + } + } +} +``` + +## Customize HTTP Client + +The SDK allows you to have full control over the network components. You can easily swap out System.Net with your favorite network library by implementing `IHTTPClientProvider` and extending `HTTPClient`. Take a look at [this example](https://github.com/segmentio/Analytics-CSharp/blob/main/Samples/UnitySample/UnityHTTPClient.cs){:target="_blank"} where the default http client is fully replaced by Unity's `UnityWebRequest`. + +### Proxying HTTP Calls + +You can also redirect the HTTP calls to your own proxy server by implementing `IHTTPClientProvider` and extending `DefaultHTTPClient`: +```csharp +class ProxyHttpClient : DefaultHTTPClient +{ + public ProxyHttpClient(string apiKey, string apiHost = null, string cdnHost = null) : base(apiKey, apiHost, cdnHost) + { + } + + public override string SegmentURL(string host, string path) + { + if (host.Equals(_apiHost)) + { + return "Your proxy api url"; + } + else + { + return "Your proxy cdn url"; + } + } +} + +class ProxyHttpClientProvider : IHTTPClientProvider +{ + public HTTPClient CreateHTTPClient(string apiKey, string apiHost = null, string cdnHost = null) + { + return new ProxyHttpClient(apiKey, apiHost, cdnHost); + } +} +``` + +## Customize Storage + +The SDK also allows you to fully customize your storage strategy. It comes with two standard providers: `DefaultStorageProvider` that stores data to local disk and `InMemoryStorageProvider` that stores data all in memory. You can write up your own provider according to your needs, for example, store data to a database or to your own server directly, by implementing `IStorage` and `IStorageProvider`. Please refer to the implementation of [`Storage`](https://github.com/segmentio/Analytics-CSharp/blob/main/Analytics-CSharp/Segment/Analytics/Utilities/Storage.cs){:target="_blank"} as an example. + +## Json Library + +The SDK supports `.netstandard 1.3` and `.netstandard 2.0` and auto assembles the internal Json library according to the target framework: +* on `.netstandard 1.3`, the SDK uses Newtonsoft Json.NET +* on `.netstandard 2.0`, the SDK uses System.Text.Json + + +### Arrays To send an array as an event property, reference the [GitHub repo](https://github.com/segmentio/Serialization.NET/blob/main/Tests/JsonUtilityTest.cs#L24){:target="_blank"}. Below is an example of code you can implement to send an array of strings: ```c# @@ -335,8 +546,30 @@ JsonObject customerJsonObj = new JsonObject }; ``` + +## Samples + +For sample usages of the SDK in specific platforms, checkout the following: + +| Platform | Sample | +|-------------|----------------| +| Asp.Net | [Set up with dependency injection](https://github.com/segmentio/Analytics-CSharp/tree/main/Samples/AspNetSample){:target="_blank"} | +| Asp.Net MVC | [Set up with dependency injection](https://github.com/segmentio/Analytics-CSharp/blob/main/Samples/AspNetMvcSample){:target="_blank"} | +| Console | [Basic setup](https://github.com/segmentio/Analytics-CSharp/tree/main/Samples/ConsoleSample/Program.cs){:target="_blank"} | +| Unity | [Singleton Analytics](https://github.com/segmentio/Analytics-CSharp/blob/main/Samples/UnitySample/SingletonAnalytics.cs){:target="_blank"} | +| | [Lifecycle plugin](https://github.com/segmentio/Analytics-CSharp/blob/main/Samples/UnitySample/LifecyclePlugin.cs){:target="_blank"} | +| | [Custom HTTPClient](https://github.com/segmentio/Analytics-CSharp/blob/main/Samples/UnitySample/UnityHTTPClient.cs){:target="_blank"} | +| Xamarin | [Basic setup](https://github.com/segmentio/Analytics-CSharp/tree/main/Samples/XamarinSample){:target="_blank"} | +| General | [Custom HTTP client](https://github.com/segmentio/Analytics-CSharp/tree/main/Samples/ConsoleSample/ProxyHttpClient.cs){:target="_blank"} | +| | [Custom Storage](https://github.com/segmentio/Analytics-CSharp/blob/main/Analytics-CSharp/Segment/Analytics/Utilities/Storage.cs#L200{:target="_blank"}) | +| | [Flush Policy](https://github.com/segmentio/Analytics-CSharp/tree/main/Samples/ConsoleSample/FlushOnScreenEventsPolicy.cs){:target="_blank"} | +| | [Custom Logger](https://github.com/segmentio/Analytics-CSharp/tree/main/Samples/ConsoleSample/SegmentLogger.cs){:target="_blank"} | +| | [Custom Error Handler](https://github.com/segmentio/Analytics-CSharp/tree/main/Samples/ConsoleSample/NetworkErrorHandler.cs){:target="_blank"} | + + + ## Compatibility -This library targets `.NET Standard 2.0`. See the [list of compatible platforms](https://docs.microsoft.com/en-us/dotnet/standard/net-standard?tabs=net-standard-2-0){:target="_blank"}. +This library targets `.NET Standard 1.3` and `.NET Standard 2.0`. See the [list of compatible platforms](https://www.nuget.org/packages/Segment.Analytics.CSharp/#supportedframeworks-body-tab){:target="_blank"}. ## Changelog [View the Analytics-CSharp changelog on GitHub](https://github.com/segmentio/analytics-csharp/releases){:target="_blank"}. diff --git a/src/connections/sources/catalog/libraries/server/csharp/migration-guide.md b/src/connections/sources/catalog/libraries/server/csharp/migration-guide.md index a287a60361..09570e4c87 100644 --- a/src/connections/sources/catalog/libraries/server/csharp/migration-guide.md +++ b/src/connections/sources/catalog/libraries/server/csharp/migration-guide.md @@ -1,17 +1,19 @@ --- -title: Analytics for CSharp (C#) Migration Guide +title: Analytics-CSharp (C#) Migration Guide strat: csharp --- -If you’re using a different library, follow the steps below to migrate to the [Analytics-CSharp library](/docs/connections/sources/catalog/libraries/server/csharp/). +If you’re currently using Analytics.NET or Analytics.Xamarin to send data to Segment, please follow the steps below to migrate to the [Analytics-CSharp library](/docs/connections/sources/catalog/libraries/server/csharp/). -> info "" -> This library is currently in beta and is governed by Segment’s [First Access and Beta terms](https://www.twilio.com/legal/tos){:target="_blank"}. +You can update to Analytics-CSharp in 3 easy steps +1. Bundle Analytics-CSharp into your app (and remove your previous SDK) +2. Change the namespaces +3. Advanced: Run Analytics in Synchronous Mode -1. Create a source in Segment. If you want to reuse your current source, skip to step 2. - 1. Go to Connections > Sources > Add Source. - 2. Search for *Xamarin, Unity* or *.NET* and click **Add source**. **Note:** There is no CSharp source. To use Analytics-CSharp, use either Xamarin, Unity, or .NET as your source. -2. Add the Analytics CSharp dependency to your project. + +## Start the Migration + +1. Add the Analytics-CSharp dependency to your project.
Before: ```js @@ -28,116 +30,25 @@ If you’re using a different library, follow the steps below to migrate to the dotnet add package Segment.Analytics.CSharp --version ``` -3. Modify your tracking methods. - - Identify +2. Replace namespaces.
Before: ```c# - Analytics.Client.Identify("019mr8mf4r", new Traits() { - { "name", "#{ user.name }" }, - { "email", "#{ user.email }" }, - { "friends", 29 } - }); + using Segment; + using Segment.Flush; + using Segment.Model; + using Segment.Request; ```
After: ```c# - // compatible with the old way - analytics.Identify("019mr8mf4r", new JsonObject() - { - { "name", "#{ user.name }" }, - { "email", "#{ user.email }" }, - { "friends", 29 } - }); + using Segment.Analytics; + using Segment.Analytics.Compat; ``` - - Track -
Before: - ```c# - Analytics.Client.Track("019mr8mf4r", "Item Purchased", new Properties() { - { "revenue", 39.95 }, - { "shipping", "2-day" } - }); - ``` - -
After: - ```c# - // compatible with the old way - analytics.Track("Item Purchased", new JsonObject() - { - { "revenue", 39.95 }, - { "shipping", "2-day" } - }); - ``` - **Note:** The Analytics-CSharp SDK remembers the identity info from the last identify call, so you don’t have to pass an identity every time. If you still want to identify on every track call, you can achieve it with Segment's plugin system. - - - Page -
Before: - ```c# - Analytics.Client.Page("019mr8mf4r", "Login", new Properties() { - { "path", "/login" }, - { "title", "Initech Login" } - }); - ``` - -
After: - ```c# - // compatible with the old way - analytics.Page("Login", new JsonObject() - { - { "path", "/login" }, - { "title", "Initech Login" } - }); - ``` - - - Screen -
Before: - ```c# - Analytics.Client.Screen("019mr8mf4r", "Register", new Properties() { - { "type", "facebook" } - }); - ``` - -
After: - ```c# - // compatible with the old way - analytics.Screen("Register", new JsonObject() - { - { "type", "facebook" } - }); - ``` - - - Group -
Before: - ```c# - Analytics.Client.Group("userId", "groupId", new Traits() { - { "name", "Initech, Inc." }, - { "website", "http://www.example.com" } - }); - ``` - -
After: - ```c# - // compatible with the old way - analytics.Group("groupId", new JsonObject() - { - { "name", "Initech, Inc." }, - { "website", "http://www.example.com" } - }); - ``` - - - Alias -
Before: - ```c# - Analytics.Client.Alias("previousId", "userId") - ``` - -
After: - ```c# - analytics.Alias("newId"); - ``` - -4. Change your development settings if you would like to make analytics run synchronously for testing purposes. +## Optional Changes + +1. Change your development settings if you would like to make analytics run synchronously for testing purposes.
Before: ```c# @@ -147,15 +58,16 @@ If you’re using a different library, follow the steps below to migrate to the
After: ```c# var configuration = new Configuration("YOUR WRITE KEY", - userSynchronizeDispatcher: true); + useSynchronizeDispatcher: true); var analytics = new Analytics(configuration); ``` -5. Review your anonymous ID settings. +2. Review your anonymous ID settings.
Before: ```c# - Analytics.Initialize("YOUR_WRITE_KEY", new Config().SetAsync(false)); + Analytics.Client.Page(null, "Login", new Properties(), new Options() + .SetAnonymousId("some-id")); ``` The new SDK by default, generates an Anonymous ID for you if you never call `analytics.Identify`. If you've called `Identify` and want to go back to anonymous, try: @@ -163,70 +75,4 @@ If you’re using a different library, follow the steps below to migrate to the
After: ```c# analytics.Reset(); - ``` - -6. Change your nested properties settings. - -
Before: - ```c# - Analytics.Client.Identify("hj2kf92ds212", new Traits() { - { "email", "tom@example.com" }, - { "name", "Tom Smykowski" }, - { "address", new Dict() { - { "street", "123 Fake Street" }, - { "city", "Boston" } - }} - }); - ``` - -
After: - ```c# - // compatbile with the old way - analytics.Identify("hj2kf92ds212", new JsonObject() - { - { "email", "tom@example.com" }, - { "name", "Tom Smykowski" }, - { "address", new JsonObject() { - { "street", "123 Fake Street" }, - { "city", "Boston" } - }} - }); - ``` - - The new SDK internally implements a flexible JSON builder (Serialization.NET), that allows you build a complex JSON payload: - - ```c# - var jsonObject = new JsonObject - { - ["int"] = 1, - ["float"] = 1f, - ["long"] = 1L, - ["double"] = 1.0, - ["string"] = "1", - ["bool"] = true, - ["object"] = new JsonObject - { - ["another object"] = "obj" - }, - ["array"] = new JsonArray - { - 1, 1f, 1L, 1.0, "1", true, new JsonObject - { - ["object in array"] = "obj" - } - } - }; - ``` - -7. Review your Flush settings. - -
Before: - ```c# - Analytics.Client.Flush(); - ``` - -
After: - ```c# - analytics.Flush(); - ``` - + ``` \ No newline at end of file diff --git a/src/connections/sources/catalog/libraries/server/net/index.md b/src/connections/sources/catalog/libraries/server/net/index.md index 9b2f446617..7a185dab1d 100644 --- a/src/connections/sources/catalog/libraries/server/net/index.md +++ b/src/connections/sources/catalog/libraries/server/net/index.md @@ -11,7 +11,7 @@ Segment's .NET library is the best way to integrate analytics into your .NET app 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 our servers. > info "Analytics-CSharp (C#)" -> With Analytics-CSharp, you can add Segment analytics to your C# based app which includes .NET. The [Analytics-CSharp library](/docs/connections/sources/catalog/libraries/server/csharp/) is currently in beta and is governed by Segment’s [First Access and Beta terms](https://www.twilio.com/legal/tos){:target="_blank"}. If you'd like to migrate to use Analytics-CSharp, see the [Analytics-CSharp migration guide](/docs/connections/sources/catalog/libraries/server/csharp/migration-guide/). +> With [Analytics-CSharp](/docs/connections/sources/catalog/libraries/server/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](/docs/connections/sources/catalog/libraries/server/csharp/migration-guide/). ## Getting Started