diff --git a/Piwik.Tracker.Samples/Piwik.Tracker.Samples.csproj b/Piwik.Tracker.Samples/Piwik.Tracker.Samples.csproj index 25b8432..11a6a85 100644 --- a/Piwik.Tracker.Samples/Piwik.Tracker.Samples.csproj +++ b/Piwik.Tracker.Samples/Piwik.Tracker.Samples.csproj @@ -1,5 +1,5 @@  - + Debug x86 @@ -10,7 +10,7 @@ Properties Piwik.Tracker.Samples Piwik.Tracker.Samples - v4.0 + v4.5 512 @@ -39,6 +39,7 @@ DEBUG;TRACE prompt 4 + false x86 @@ -48,6 +49,7 @@ TRACE prompt 4 + false true @@ -57,6 +59,7 @@ AnyCPU prompt MinimumRecommendedRules.ruleset + false bin\Release\ @@ -66,10 +69,12 @@ AnyCPU prompt MinimumRecommendedRules.ruleset + false + diff --git a/Piwik.Tracker.Samples/PiwikTrackerSamples.cs b/Piwik.Tracker.Samples/PiwikTrackerSamples.cs index 9a72789..3f55b19 100644 --- a/Piwik.Tracker.Samples/PiwikTrackerSamples.cs +++ b/Piwik.Tracker.Samples/PiwikTrackerSamples.cs @@ -1,17 +1,16 @@ -using System; -using System.Text; -using System.Net; -using System.IO; - -namespace Piwik.Tracker.Samples +namespace Piwik.Tracker.Samples { + using System; using System.Collections.Generic; + using System.Net.Http; + using System.Threading.Tasks; internal class PiwikTrackerSamples { private const string UA = "Firefox"; private static readonly string PiwikBaseUrl = "http://piwik.local"; private static readonly int SiteId = 1; + private static readonly HttpClient HttpClient = new HttpClient(); private static void Main(string[] args) { @@ -60,12 +59,12 @@ private static void Main(string[] args) /// /// Triggers a Goal conversion /// - static private void GoalConversion() + private static async Task GoalConversionAsync() { - var piwikTracker = new PiwikTracker(SiteId, PiwikBaseUrl); + var piwikTracker = new PiwikTracker(HttpClient, SiteId, PiwikBaseUrl); piwikTracker.SetUserAgent(UA); - var response = piwikTracker.DoTrackGoal(1, 42.69F); + var response = await piwikTracker.TrackGoalAsync(1, 42.69F); DisplayDebugInfo(response); } @@ -73,9 +72,9 @@ static private void GoalConversion() /// /// Records 2 page scoped custom variables and 2 visit scoped custom variables /// - static private void RecordCustomVariables() + private static async Task RecordCustomVariablesAsync() { - var piwikTracker = new PiwikTracker(SiteId, PiwikBaseUrl); + var piwikTracker = new PiwikTracker(HttpClient, SiteId, PiwikBaseUrl); piwikTracker.SetUserAgent(UA); piwikTracker.SetCustomVariable(1, "var1", "value1"); @@ -84,7 +83,7 @@ static private void RecordCustomVariables() piwikTracker.SetCustomVariable(1, "pagevar1", "pagevalue1", Scopes.Page); piwikTracker.SetCustomVariable(2, "pagevar2", "pagevalue2", Scopes.Page); - var response = piwikTracker.DoTrackPageView("Document title of current page view"); + var response = await piwikTracker.TrackPageViewAsync("Document title of current page view"); DisplayDebugInfo(response); } @@ -92,15 +91,15 @@ static private void RecordCustomVariables() /// /// Records 2 custom dimensions /// - static private void RecordCustomDimensions() + private static async Task RecordCustomDimensionsAsync() { - var piwikTracker = new PiwikTracker(SiteId, PiwikBaseUrl); + var piwikTracker = new PiwikTracker(HttpClient, SiteId, PiwikBaseUrl); piwikTracker.SetUserAgent(UA); piwikTracker.SetCustomTrackingParameter("dimension1", "value1"); piwikTracker.SetCustomTrackingParameter("dimension2", "value2"); - var response = piwikTracker.DoTrackPageView("Document title of current page view"); + var response = await piwikTracker.TrackPageViewAsync("Document title of current page view"); DisplayDebugInfo(response); } @@ -108,12 +107,12 @@ static private void RecordCustomDimensions() /// /// Records a simple page view with a specified document title /// - static private void RecordSimplePageView() + private static async Task RecordSimplePageViewAsync() { - var piwikTracker = new PiwikTracker(SiteId, PiwikBaseUrl); + var piwikTracker = new PiwikTracker(HttpClient, SiteId, PiwikBaseUrl); piwikTracker.SetUserAgent(UA); - var response = piwikTracker.DoTrackPageView("Document title of current page view"); + var response = await piwikTracker.TrackPageViewAsync("Document title of current page view"); DisplayDebugInfo(response); } @@ -121,9 +120,9 @@ static private void RecordSimplePageView() /// /// Records a simple page view with advanced user, browser and server properties /// - static private void RecordSimplePageViewWithCustomProperties() + private static async Task RecordSimplePageViewWithCustomPropertiesAsync() { - var piwikTracker = new PiwikTracker(SiteId, PiwikBaseUrl); + var piwikTracker = new PiwikTracker(HttpClient, SiteId, PiwikBaseUrl); piwikTracker.SetUserAgent(UA); piwikTracker.SetResolution(1600, 1400); @@ -148,7 +147,7 @@ static private void RecordSimplePageViewWithCustomProperties() piwikTracker.SetUrl("http://piwik-1.5/supernova"); piwikTracker.SetUrlReferrer("http://supernovadirectory.org"); - var response = piwikTracker.DoTrackPageView("Document title of current page view"); + var response = await piwikTracker.TrackPageViewAsync("Document title of current page view"); DisplayDebugInfo(response); } @@ -156,9 +155,9 @@ static private void RecordSimplePageViewWithCustomProperties() /// /// Records a simple page view with custom geo location parameters /// - static private void RecordSimplePageViewWithCustomGeoLocation() + private static async Task RecordSimplePageViewWithCustomGeoLocationAsync() { - var piwikTracker = new PiwikTracker(SiteId, PiwikBaseUrl); + var piwikTracker = new PiwikTracker(HttpClient, SiteId, PiwikBaseUrl); piwikTracker.SetTokenAuth("XYZ"); piwikTracker.SetUserAgent(UA); @@ -169,7 +168,7 @@ static private void RecordSimplePageViewWithCustomGeoLocation() piwikTracker.SetLatitude(48.2F); piwikTracker.SetLongitude(2.1F); - var response = piwikTracker.DoTrackPageView("Document title of current page view"); + var response = await piwikTracker.TrackPageViewAsync("Document title of current page view"); DisplayDebugInfo(response); } @@ -177,14 +176,14 @@ static private void RecordSimplePageViewWithCustomGeoLocation() /// /// Records a simple page view with generation time metric /// - static private void RecordSimplePageViewWithGenerationTime() + private static async Task RecordSimplePageViewWithGenerationTimeAsync() { - var piwikTracker = new PiwikTracker(SiteId, PiwikBaseUrl); + var piwikTracker = new PiwikTracker(HttpClient, SiteId, PiwikBaseUrl); piwikTracker.SetUserAgent(UA); piwikTracker.SetGenerationTime(10000); - var response = piwikTracker.DoTrackPageView("Document title of current page view"); + var response = await piwikTracker.TrackPageViewAsync("Document title of current page view"); DisplayDebugInfo(response); } @@ -192,9 +191,9 @@ static private void RecordSimplePageViewWithGenerationTime() /// /// Triggers a Goal conversion with advanced attribution properties /// - static private void GoalConversionWithAttributionInfo() + private static async Task GoalConversionWithAttributionInfoAsync() { - var piwikTracker = new PiwikTracker(SiteId, PiwikBaseUrl); + var piwikTracker = new PiwikTracker(HttpClient, SiteId, PiwikBaseUrl); piwikTracker.SetUserAgent(UA); var attributionInfo = new AttributionInfo(); @@ -206,7 +205,7 @@ static private void GoalConversionWithAttributionInfo() piwikTracker.SetAttributionInfo(attributionInfo); - var response = piwikTracker.DoTrackGoal(1, 42.69F); + var response = await piwikTracker.TrackGoalAsync(1, 42.69F); DisplayDebugInfo(response); } @@ -214,12 +213,12 @@ static private void GoalConversionWithAttributionInfo() /// /// Records a clicked link /// - static private void TrackLink() + private static async Task TrackLinkAsync() { - var piwikTracker = new PiwikTracker(SiteId, PiwikBaseUrl); + var piwikTracker = new PiwikTracker(HttpClient, SiteId, PiwikBaseUrl); piwikTracker.SetUserAgent(UA); - var response = piwikTracker.DoTrackAction("http://dev.piwik.org/svn", ActionType.Link); + var response = await piwikTracker.TrackActionAsync("http://dev.piwik.org/svn", ActionType.Link); DisplayDebugInfo(response); } @@ -227,12 +226,12 @@ static private void TrackLink() /// /// Records a file download /// - static private void TrackDownload() + private static async Task TrackDownloadAsync() { - var piwikTracker = new PiwikTracker(SiteId, PiwikBaseUrl); + var piwikTracker = new PiwikTracker(HttpClient, SiteId, PiwikBaseUrl); piwikTracker.SetUserAgent(UA); - var response = piwikTracker.DoTrackAction("http://piwik.org/path/again/latest.zip", ActionType.Download); + var response = await piwikTracker.TrackActionAsync("http://piwik.org/path/again/latest.zip", ActionType.Download); DisplayDebugInfo(response); } @@ -240,50 +239,50 @@ static private void TrackDownload() /// /// Records a category page view /// - static private void ECommerceCategoryView() + private static async Task ECommerceCategoryViewAsync() { - var piwikTracker = new PiwikTracker(SiteId, PiwikBaseUrl); + var piwikTracker = new PiwikTracker(HttpClient, SiteId, PiwikBaseUrl); piwikTracker.SetUserAgent(UA); piwikTracker.SetEcommerceView("", "", new List { "Electronics & Cameras" }); - var response = piwikTracker.DoTrackPageView("Looking at Electronics & Cameras page with a page level custom variable"); + var response = await piwikTracker.TrackPageViewAsync("Looking at Electronics & Cameras page with a page level custom variable"); DisplayDebugInfo(response); } /// /// Records a product view /// - static private void ECommerceView() + private static async Task ECommerceViewAsync() { - var piwikTracker = new PiwikTracker(SiteId, PiwikBaseUrl); + var piwikTracker = new PiwikTracker(HttpClient, SiteId, PiwikBaseUrl); piwikTracker.SetUserAgent(UA); piwikTracker.SetEcommerceView("SKU2", "PRODUCT name", new List { "Electronics & Cameras", "Clothes" }); - var response = piwikTracker.DoTrackPageView("incredible title!"); + var response = await piwikTracker.TrackPageViewAsync("incredible title!"); DisplayDebugInfo(response); } /// /// Records a product view which doesn't belong to a category /// - static private void ECommerceViewWithoutCategory() + private static async Task ECommerceViewWithoutCategoryAsync() { - var piwikTracker = new PiwikTracker(SiteId, PiwikBaseUrl); + var piwikTracker = new PiwikTracker(HttpClient, SiteId, PiwikBaseUrl); piwikTracker.SetUserAgent(UA); piwikTracker.SetEcommerceView("SKU VERY nice indeed", "PRODUCT name"); - var response = piwikTracker.DoTrackPageView("another incredible title!"); + var response = await piwikTracker.TrackPageViewAsync("another incredible title!"); DisplayDebugInfo(response); } /// /// Update an eCommerce Cart with one product /// - static private void UpdateECommerceCartWithOneProduct() + private static async Task UpdateECommerceCartWithOneProductAsync() { - var piwikTracker = new PiwikTracker(SiteId, PiwikBaseUrl); + var piwikTracker = new PiwikTracker(HttpClient, SiteId, PiwikBaseUrl); piwikTracker.SetUserAgent(UA); piwikTracker.AddEcommerceItem( @@ -293,7 +292,7 @@ static private void UpdateECommerceCartWithOneProduct() 2 ); - var response = piwikTracker.DoTrackEcommerceCartUpdate(1000.4); + var response = await piwikTracker.TrackEcommerceCartUpdateAsync(1000.4); DisplayDebugInfo(response); } @@ -301,25 +300,25 @@ static private void UpdateECommerceCartWithOneProduct() /// /// Update an eCommerce Cart with one product /// - static private void UpdateECommerceCartWithOneProductSKUOnly() + private static async Task UpdateECommerceCartWithOneProductSKUOnlyAsync() { - var piwikTracker = new PiwikTracker(SiteId, PiwikBaseUrl); + var piwikTracker = new PiwikTracker(HttpClient, SiteId, PiwikBaseUrl); piwikTracker.SetUserAgent(UA); piwikTracker.AddEcommerceItem( "SKU VERY nice indeed" ); - var response = piwikTracker.DoTrackEcommerceCartUpdate(1000.2); + var response = await piwikTracker.TrackEcommerceCartUpdateAsync(1000.2); DisplayDebugInfo(response); } /// /// Update an eCommerce Cart with multiple products /// - static private void UpdateECommerceCartWithMultipleProducts() + private static async Task UpdateECommerceCartWithMultipleProductsAsync() { - var piwikTracker = new PiwikTracker(SiteId, PiwikBaseUrl); + var piwikTracker = new PiwikTracker(HttpClient, SiteId, PiwikBaseUrl); piwikTracker.SetUserAgent(UA); piwikTracker.AddEcommerceItem( @@ -346,7 +345,7 @@ static private void UpdateECommerceCartWithMultipleProducts() 20 ); - var response = piwikTracker.DoTrackEcommerceCartUpdate(1000); + var response = await piwikTracker.TrackEcommerceCartUpdateAsync(1000); DisplayDebugInfo(response); } @@ -354,9 +353,9 @@ static private void UpdateECommerceCartWithMultipleProducts() /// /// Registers 2 eCommerce orders /// - static private void RecordTwoECommerceOrders() + private static async Task RecordTwoECommerceOrdersAsync() { - var piwikTracker = new PiwikTracker(SiteId, PiwikBaseUrl); + var piwikTracker = new PiwikTracker(HttpClient, SiteId, PiwikBaseUrl); piwikTracker.SetUserAgent(UA); // First order @@ -378,7 +377,7 @@ static private void RecordTwoECommerceOrders() ); var response = - piwikTracker.DoTrackEcommerceOrder( + await piwikTracker.TrackEcommerceOrderAsync( "137nsjusG 1094", 1111.11, 1000, @@ -399,7 +398,7 @@ static private void RecordTwoECommerceOrders() 1 ); - response = piwikTracker.DoTrackEcommerceOrder( + response = await piwikTracker.TrackEcommerceOrderAsync( "1037Bjusu4s3894", 2000, 1500, @@ -411,9 +410,9 @@ static private void RecordTwoECommerceOrders() DisplayDebugInfo(response); } - static private void RecordECommerceOrder() + private static async Task RecordECommerceOrderAsync() { - var piwikTracker = new PiwikTracker(SiteId, PiwikBaseUrl); + var piwikTracker = new PiwikTracker(HttpClient, SiteId, PiwikBaseUrl); piwikTracker.SetUserAgent(UA); piwikTracker.AddEcommerceItem( @@ -433,7 +432,7 @@ static private void RecordECommerceOrder() ); var response = - piwikTracker.DoTrackEcommerceOrder( + await piwikTracker.TrackEcommerceOrderAsync( "133nsjusu 1094", 1111.11, 1000, @@ -445,42 +444,42 @@ static private void RecordECommerceOrder() DisplayDebugInfo(response); } - private static void BulkTrackTwoRequests() + private static async Task BulkTrackTwoRequestsAsync() { - var piwikTracker = new PiwikTracker(SiteId, PiwikBaseUrl); + var piwikTracker = new PiwikTracker(HttpClient, SiteId, PiwikBaseUrl); piwikTracker.SetUserAgent(UA); piwikTracker.SetTokenAuth("YOUR TOKEN"); piwikTracker.EnableBulkTracking(); - piwikTracker.DoTrackPageView("Tracking Request 1"); - piwikTracker.DoTrackPageView("Tracking Request 2"); + await piwikTracker.TrackPageViewAsync("Tracking Request 1"); + await piwikTracker.TrackPageViewAsync("Tracking Request 2"); - DisplayDebugInfo(piwikTracker.DoBulkTrack()); + DisplayDebugInfo(await piwikTracker.BulkTrackAsync()); } - static private void TrackSiteSearch() + private static async Task TrackSiteSearchAsync() { - var piwikTracker = new PiwikTracker(SiteId, PiwikBaseUrl); + var piwikTracker = new PiwikTracker(HttpClient, SiteId, PiwikBaseUrl); piwikTracker.SetUserAgent(UA); - var response = piwikTracker.DoTrackSiteSearch("keyword1", "category2", 0); + var response = await piwikTracker.TrackSiteSearchAsync("keyword1", "category2", 0); DisplayDebugInfo(response); } - static private void TrackSongPlayback() + private static async Task TrackSongPlaybackAsync() { - var piwikTracker = new PiwikTracker(SiteId, PiwikBaseUrl); + var piwikTracker = new PiwikTracker(HttpClient, SiteId, PiwikBaseUrl); piwikTracker.SetUserAgent(UA); - var response = piwikTracker.DoTrackEvent("music", "play", "Eye Of The Tiger"); + var response = await piwikTracker.TrackEventAsync("music", "play", "Eye Of The Tiger"); DisplayDebugInfo(response); } - static private void DisplayDebugInfo(TrackingResponse response) + private static void DisplayDebugInfo(TrackingResponse response) { Console.WriteLine("DEBUG_LAST_REQUESTED_URL :"); Console.WriteLine(response.RequestedUrl); diff --git a/Piwik.Tracker.Samples/app.config b/Piwik.Tracker.Samples/app.config index cb2586b..b7a7ef1 100644 --- a/Piwik.Tracker.Samples/app.config +++ b/Piwik.Tracker.Samples/app.config @@ -1,3 +1,3 @@ - + diff --git a/Piwik.Tracker.Tests/PiwikTrackerWithMockedServerTests.cs b/Piwik.Tracker.Tests/PiwikTrackerWithMockedServerTests.cs index eb83c91..ee1dc65 100644 --- a/Piwik.Tracker.Tests/PiwikTrackerWithMockedServerTests.cs +++ b/Piwik.Tracker.Tests/PiwikTrackerWithMockedServerTests.cs @@ -57,12 +57,12 @@ public void SetUpTest() [Test] [TestCase("myPage")] [TestCase("myPage/?Ü&")] - public void DoTrackPageView_Test(string documentTitle) + public async Task TrackPageView_Test(string documentTitle) { //Arrange var retrieveRequest = CreateAllGetOkRequestBehavior(); //Act - var actual = _sut.DoTrackPageView(documentTitle); + var actual = await _sut.TrackPageViewAsync(documentTitle); //Assert var actualRequest = retrieveRequest(); Assert.That(actual.HttpStatusCode, Is.EqualTo(HttpStatusCode.OK)); @@ -79,7 +79,7 @@ public void DoTrackPageView_Test(string documentTitle) [TestCase("myCategory", "myAction", "myName", "myValue")] [TestCase("myCategory", "myAction", "myName", "")] [TestCase("myCategory", "myAction", "", "myValue")] - public void DoTrackEvent_Test(string category, string action, string name, string value) + public async Task TrackEvent_Test(string category, string action, string name, string value) { //Arrange var retrieveRequest = CreateAllGetOkRequestBehavior(); @@ -91,7 +91,7 @@ public void DoTrackEvent_Test(string category, string action, string name, strin {"e_a", action}, }; //Act - var actual = _sut.DoTrackEvent(category, action, name, value); + var actual = await _sut.TrackEventAsync(category, action, name, value); //Assert var actualRequest = retrieveRequest(); Assert.That(actual.HttpStatusCode, Is.EqualTo(HttpStatusCode.OK)); @@ -112,7 +112,7 @@ public void DoTrackEvent_Test(string category, string action, string name, strin [TestCase("myCn", "mycp", "myct")] [TestCase("myCn", null, "myct")] [TestCase("myCn", "mycp", null)] - public void DoTrackContentImpression_Test(string contentName, string contentPiece, string contentTarget) + public async Task TrackContentImpression_Test(string contentName, string contentPiece, string contentTarget) { //Arrange var retrieveRequest = CreateAllGetOkRequestBehavior(); @@ -123,7 +123,7 @@ public void DoTrackContentImpression_Test(string contentName, string contentPiec { "c_n", contentName }, }; //Act - var actual = _sut.DoTrackContentImpression(contentName, contentPiece, contentTarget); + var actual = await _sut.TrackContentImpressionAsync(contentName, contentPiece, contentTarget); //Assert var actualRequest = retrieveRequest(); Assert.That(actual.HttpStatusCode, Is.EqualTo(HttpStatusCode.OK)); @@ -144,7 +144,7 @@ public void DoTrackContentImpression_Test(string contentName, string contentPiec [TestCase("myInteraction", "myCn", "mycp", "myct")] [TestCase("myInteraction", "myCn", null, "myct")] [TestCase("myInteraction", "myCn", "mycp", null)] - public void DoTrackContentInteraction_Test(string interaction, string contentName, string contentPiece, string contentTarget) + public async Task TrackContentInteraction_Test(string interaction, string contentName, string contentPiece, string contentTarget) { //Arrange var retrieveRequest = CreateAllGetOkRequestBehavior(); @@ -156,7 +156,7 @@ public void DoTrackContentInteraction_Test(string interaction, string contentNam { "c_i", interaction }, }; //Act - var actual = _sut.DoTrackContentInteraction(interaction, contentName, contentPiece, contentTarget); + var actual = await _sut.TrackContentInteractionAsync(interaction, contentName, contentPiece, contentTarget); //Assert var actualRequest = retrieveRequest(); Assert.That(actual.HttpStatusCode, Is.EqualTo(HttpStatusCode.OK)); @@ -177,7 +177,7 @@ public void DoTrackContentInteraction_Test(string interaction, string contentNam [TestCase("myKey", "myCat", 0)] [TestCase("myKey", null, 1)] [TestCase("myKey", "myCat", null)] - public void DoTrackSiteSearch_Test(string keyword, string category, int? countResults) + public async Task TrackSiteSearch_Test(string keyword, string category, int? countResults) { //Arrange var retrieveRequest = CreateAllGetOkRequestBehavior(); @@ -188,7 +188,7 @@ public void DoTrackSiteSearch_Test(string keyword, string category, int? countRe { "search", keyword }, }; //Act - var actual = _sut.DoTrackSiteSearch(keyword, category, countResults); + var actual = await _sut.TrackSiteSearchAsync(keyword, category, countResults); //Assert var actualRequest = retrieveRequest(); Assert.That(actual.HttpStatusCode, Is.EqualTo(HttpStatusCode.OK)); @@ -209,7 +209,7 @@ public void DoTrackSiteSearch_Test(string keyword, string category, int? countRe [TestCase(1, 0.789f)] [TestCase(1, 0f)] [TestCase(120, 3655.55f)] - public void DoTrackGoal_Test(int idGoal, float revenue) + public async Task TrackGoal_Test(int idGoal, float revenue) { //Arrange var retrieveRequest = CreateAllGetOkRequestBehavior(); @@ -220,7 +220,7 @@ public void DoTrackGoal_Test(int idGoal, float revenue) { "idgoal", idGoal.ToString() }, }; //Act - var actual = _sut.DoTrackGoal(idGoal, revenue); + var actual = await _sut.TrackGoalAsync(idGoal, revenue); //Assert var actualRequest = retrieveRequest(); Assert.That(actual.HttpStatusCode, Is.EqualTo(HttpStatusCode.OK)); @@ -235,12 +235,12 @@ public void DoTrackGoal_Test(int idGoal, float revenue) [Test] [TestCase("https://myUrl.com/action?test=1&x=5", ActionType.Download)] [TestCase("", ActionType.Link)] - public void DoTrackAction_Test(string actionUrl, ActionType actionType) + public async Task TrackAction_Test(string actionUrl, ActionType actionType) { //Arrange var retrieveRequest = CreateAllGetOkRequestBehavior(); //Act - var actual = _sut.DoTrackAction(actionUrl, actionType); + var actual = await _sut.TrackActionAsync(actionUrl, actionType); //Assert var actualRequest = retrieveRequest(); Assert.That(actual.HttpStatusCode, Is.EqualTo(HttpStatusCode.OK)); @@ -257,12 +257,12 @@ public void DoTrackAction_Test(string actionUrl, ActionType actionType) [Test] [TestCase(1)] [TestCase(33465236365.4346)] - public void DoTrackEcommerceCartUpdate_Test(double grandTotal) + public async Task TrackEcommerceCartUpdate_Test(double grandTotal) { //Arrange var retrieveRequest = CreateAllGetOkRequestBehavior(); //Act - var actual = _sut.DoTrackEcommerceCartUpdate(grandTotal); + var actual = await _sut.TrackEcommerceCartUpdateAsync(grandTotal); //Assert var actualRequest = retrieveRequest(); Assert.That(actual.HttpStatusCode, Is.EqualTo(HttpStatusCode.OK)); @@ -280,7 +280,7 @@ public void DoTrackEcommerceCartUpdate_Test(double grandTotal) [Test] [TestCase("mytoken")] [TestCase("")] - public async Task DoBulkTrack_Test(string token) + public async Task BulkTrack_Test(string token) { //Arrange var retrieveRequest = CreateAllPostOkRequestBehavior(); @@ -296,11 +296,11 @@ public async Task DoBulkTrack_Test(string token) } for (int i = 0; i < numberOfRequests; i++) { - _sut.DoTrackPageView("Page" + i); + await _sut.TrackPageViewAsync("Page" + i); } var expectedUrls = _sut.GetStoredTrackingActions(); Assert.That(_sut.GetStoredTrackingActions().Length, Is.EqualTo(numberOfRequests)); - var actual = _sut.DoBulkTrack(); + var actual = await _sut.BulkTrackAsync(); Assert.That(_sut.GetStoredTrackingActions().Length, Is.EqualTo(0)); //Assert var actualRequest = retrieveRequest(); @@ -324,12 +324,12 @@ public async Task DoBulkTrack_Test(string token) [Test] [TestCase("sfaf&&Ä5", 32.32, 16.1667, 432.244, 234.324, 65.553)] - public void DoTrackEcommerceOrder_Test(string orderId, double grandTotal, double subTotal, double tax, double shipping, double discount) + public async Task TrackEcommerceOrder_Test(string orderId, double grandTotal, double subTotal, double tax, double shipping, double discount) { //Arrange var retrieveRequest = CreateAllGetOkRequestBehavior(); //Act - var actual = _sut.DoTrackEcommerceOrder(orderId, grandTotal, subTotal, tax, shipping, discount); + var actual = await _sut.TrackEcommerceOrderAsync(orderId, grandTotal, subTotal, tax, shipping, discount); //Assert var actualRequest = retrieveRequest(); Assert.That(actual.HttpStatusCode, Is.EqualTo(HttpStatusCode.OK)); @@ -350,12 +350,12 @@ public void DoTrackEcommerceOrder_Test(string orderId, double grandTotal, double } [Test] - public void DoPing_Test() + public async Task Ping_Test() { //Arrange var retrieveRequest = CreateAllGetOkRequestBehavior(); //Act - var actual = _sut.DoPing(); + var actual = await _sut.PingAsync(); //Assert var actualRequest = retrieveRequest(); Assert.That(actual.HttpStatusCode, Is.EqualTo(HttpStatusCode.OK)); diff --git a/Piwik.Tracker.Tests/packages.config b/Piwik.Tracker.Tests/packages.config index b3ebe61..5bf32f5 100644 --- a/Piwik.Tracker.Tests/packages.config +++ b/Piwik.Tracker.Tests/packages.config @@ -11,7 +11,7 @@ - + \ No newline at end of file diff --git a/Piwik.Tracker.Web.Samples/Piwik.Tracker.Web.Samples.csproj b/Piwik.Tracker.Web.Samples/Piwik.Tracker.Web.Samples.csproj index 146e03b..6a98217 100644 --- a/Piwik.Tracker.Web.Samples/Piwik.Tracker.Web.Samples.csproj +++ b/Piwik.Tracker.Web.Samples/Piwik.Tracker.Web.Samples.csproj @@ -1,5 +1,5 @@  - + Debug @@ -13,7 +13,7 @@ Properties Piwik WebTrackerTest - v4.0 + v4.5 false @@ -24,6 +24,8 @@ + + true @@ -33,6 +35,7 @@ DEBUG;TRACE prompt 4 + false pdbonly @@ -41,17 +44,17 @@ TRACE prompt 4 + false - - - + + @@ -59,6 +62,7 @@ + @@ -106,6 +110,7 @@ JavascriptGoalTracking.aspx + VisitorIdServerRead.aspx ASPXCodeBehind diff --git a/Piwik.Tracker.Web.Samples/Piwik.Tracker.Web.Samples.csproj.user b/Piwik.Tracker.Web.Samples/Piwik.Tracker.Web.Samples.csproj.user index b8e4aa5..ebd95e3 100644 --- a/Piwik.Tracker.Web.Samples/Piwik.Tracker.Web.Samples.csproj.user +++ b/Piwik.Tracker.Web.Samples/Piwik.Tracker.Web.Samples.csproj.user @@ -1,5 +1,8 @@  + + false + diff --git a/Piwik.Tracker.Web.Samples/Web.config b/Piwik.Tracker.Web.Samples/Web.config index 529f13a..226c874 100644 --- a/Piwik.Tracker.Web.Samples/Web.config +++ b/Piwik.Tracker.Web.Samples/Web.config @@ -1,11 +1,16 @@  - - - - - - - - + + + + + + + + + + + + + \ No newline at end of file diff --git a/Piwik.Tracker.Web.Samples/samples/AttributionInfoServerRead.aspx b/Piwik.Tracker.Web.Samples/samples/AttributionInfoServerRead.aspx index 6ab1def..c79a504 100644 --- a/Piwik.Tracker.Web.Samples/samples/AttributionInfoServerRead.aspx +++ b/Piwik.Tracker.Web.Samples/samples/AttributionInfoServerRead.aspx @@ -12,7 +12,7 @@ If a tracking request has been sent via javascript, this method will output the <% var PiwikBaseUrl = ConfigurationSettings.AppSettings["PiwikURL"]; - var piwikTracker = new PiwikTracker(1, PiwikBaseUrl); + var piwikTracker = new PiwikTracker(Piwik.Tracker.Web.Samples.Singleton.HttpClient, 1, PiwikBaseUrl); piwikTracker.EnableCookies(); var attributionInfo = piwikTracker.GetAttributionInfo(); diff --git a/Piwik.Tracker.Web.Samples/samples/ServerSideDeleteCookies.aspx b/Piwik.Tracker.Web.Samples/samples/ServerSideDeleteCookies.aspx index 33cf1dd..9a31111 100644 --- a/Piwik.Tracker.Web.Samples/samples/ServerSideDeleteCookies.aspx +++ b/Piwik.Tracker.Web.Samples/samples/ServerSideDeleteCookies.aspx @@ -8,7 +8,7 @@ This page deletes all first party Piwik cookies using the Server Side Tracking A <% var PiwikBaseUrl = ConfigurationSettings.AppSettings["PiwikURL"]; - var piwikTracker = new PiwikTracker(1, PiwikBaseUrl); + var piwikTracker = new PiwikTracker(Piwik.Tracker.Web.Samples.Singleton.HttpClient, 1, PiwikBaseUrl); piwikTracker.DeleteCookies(); %> diff --git a/Piwik.Tracker.Web.Samples/samples/ServerSideGoalTracking.aspx b/Piwik.Tracker.Web.Samples/samples/ServerSideGoalTracking.aspx index 2b6f1fe..4b366e9 100644 --- a/Piwik.Tracker.Web.Samples/samples/ServerSideGoalTracking.aspx +++ b/Piwik.Tracker.Web.Samples/samples/ServerSideGoalTracking.aspx @@ -1,35 +1,43 @@ -<%@ Page Language="C#" %> +<%@ Page Language="C#" Async="true" %> +<%@ Import Namespace="System.Threading.Tasks" %> <%@ Import Namespace="Piwik.Tracker" %> -<%@ Import Namespace="System.Net" %> -<%@ Import Namespace="System.IO" %> -This page tracks a goal conversion with the Server Side tracking API and displays the response. -
-
+ - this.Response.Write(response.HttpStatusCode); -%> -
+
+ This page tracks a goal conversion with the Server Side tracking API and displays the response. +
+
+ +
-Back \ No newline at end of file + Back + diff --git a/Piwik.Tracker.Web.Samples/samples/Singleton.cs b/Piwik.Tracker.Web.Samples/samples/Singleton.cs new file mode 100644 index 0000000..3950902 --- /dev/null +++ b/Piwik.Tracker.Web.Samples/samples/Singleton.cs @@ -0,0 +1,9 @@ +namespace Piwik.Tracker.Web.Samples +{ + using System.Net.Http; + + public class Singleton + { + public static readonly HttpClient HttpClient = new HttpClient(); + } +} \ No newline at end of file diff --git a/Piwik.Tracker.Web.Samples/samples/VisitScopedCustomVariableServerRead.aspx b/Piwik.Tracker.Web.Samples/samples/VisitScopedCustomVariableServerRead.aspx index b84e2bc..9309e8c 100644 --- a/Piwik.Tracker.Web.Samples/samples/VisitScopedCustomVariableServerRead.aspx +++ b/Piwik.Tracker.Web.Samples/samples/VisitScopedCustomVariableServerRead.aspx @@ -8,7 +8,7 @@ This page displays visit scoped custom variables (index 1 & 2) using the Server <% var PiwikBaseUrl = ConfigurationSettings.AppSettings["PiwikURL"]; - var piwikTracker = new PiwikTracker(1, PiwikBaseUrl); + var piwikTracker = new PiwikTracker(Piwik.Tracker.Web.Samples.Singleton.HttpClient, 1, PiwikBaseUrl); piwikTracker.EnableCookies(); var customVar1 = piwikTracker.GetCustomVariable(1); diff --git a/Piwik.Tracker.Web.Samples/samples/VisitorIdServerRead.aspx b/Piwik.Tracker.Web.Samples/samples/VisitorIdServerRead.aspx index e060381..0f554f0 100644 --- a/Piwik.Tracker.Web.Samples/samples/VisitorIdServerRead.aspx +++ b/Piwik.Tracker.Web.Samples/samples/VisitorIdServerRead.aspx @@ -18,7 +18,7 @@ It is also possible to override the id using "piwikTracker.setVisitorId()"
<% var PiwikBaseUrl = ConfigurationSettings.AppSettings["PiwikURL"]; - var piwikTracker = new PiwikTracker(1, PiwikBaseUrl); + var piwikTracker = new PiwikTracker(Piwik.Tracker.Web.Samples.Singleton.HttpClient, 1, PiwikBaseUrl); piwikTracker.EnableCookies(); this.Response.Write(piwikTracker.GetVisitorId()); diff --git a/Piwik.Tracker/Piwik.Tracker.csproj b/Piwik.Tracker/Piwik.Tracker.csproj index 062c0d9..a7286df 100644 --- a/Piwik.Tracker/Piwik.Tracker.csproj +++ b/Piwik.Tracker/Piwik.Tracker.csproj @@ -1,5 +1,5 @@  - + Debug AnyCPU @@ -10,8 +10,9 @@ Properties Piwik.Tracker Piwik.Tracker - v4.0 + v4.5 512 + true @@ -22,6 +23,7 @@ prompt 4 bin\Debug\Piwik.Tracker.xml + false pdbonly @@ -31,10 +33,12 @@ prompt 4 bin\Release\Piwik.Tracker.XML + false + @@ -55,11 +59,11 @@ - \ No newline at end of file diff --git a/Piwik.Tracker/PiwikTracker.cs b/Piwik.Tracker/PiwikTracker.cs index 7c0e41d..d37f20c 100644 --- a/Piwik.Tracker/PiwikTracker.cs +++ b/Piwik.Tracker/PiwikTracker.cs @@ -11,15 +11,16 @@ namespace Piwik.Tracker { - using System.IO; using System; using System.Collections.Generic; - using System.Linq; - using System.Net; using System.Globalization; + using System.Linq; + using System.Net.Http; + using System.Net.Http.Headers; + using System.Text.RegularExpressions; + using System.Threading.Tasks; using System.Web; using System.Web.Script.Serialization; - using System.Text.RegularExpressions; /// /// PiwikTracker implements the Piwik Tracking Web API. @@ -141,6 +142,10 @@ public class PiwikTracker // Life of the session cookie (in sec) private const int ConfigReferralCookieTimeout = 15768000; // 6 months + // Singleton HttpClient when caller doesn't provide one + private static readonly Lazy HttpClient = new Lazy(); + + private readonly HttpClient _httpClient; private string _debugAppendUrl; private string _userAgent; private DateTimeOffset _localTime = DateTimeOffset.MinValue; @@ -196,13 +201,40 @@ public class PiwikTracker /// /// Id site to be tracked /// "http://example.org/piwik/" or "http://piwik.example.org/". If set, will overwrite PiwikTracker.URL + /// + /// This constructor initalizes an HttpClient with the default settings. + /// If you are using HttpClient in your application, or need to configure RequestTimeout, Proxy etc, + /// use the constructor that accepts HttpClient as a parameter and pass in your configured HttpClient. + /// /// apiUrl must not be null or empty public PiwikTracker(int idSite, string apiUrl) + : this(HttpClient.Value, idSite, apiUrl) + { + } + + /// + /// Builds a PiwikTracker object, used to track visits, pages and Goal conversions + /// for a specific website, by using the Piwik Tracking API. + /// If the tracker is used within a web page or web controller, the following information are pre-initialised : + /// URL Referrer, current page URL, remote IP, Accept-Language HTTP header and User-Agent HTTP header. + /// + /// A singleton HttpClient that is used throughout your application. See HttpClient class remarks + /// Id site to be tracked + /// "http://example.org/piwik/" or "http://piwik.example.org/". If set, will overwrite PiwikTracker.URL + /// apiUrl must not be null or empty + public PiwikTracker(HttpClient httpClient, int idSite, string apiUrl) { if (string.IsNullOrEmpty(apiUrl)) { - throw new ArgumentException("Piwik api url must not be emty or null.", nameof(apiUrl)); + throw new ArgumentException("Piwik api url must not be empty or null.", nameof(apiUrl)); } + + if (httpClient == null) + { + throw new ArgumentNullException(nameof(httpClient), $"Initialize a single instance of HttpClient in your application and pass that instance to the {nameof(httpClient)} parameter."); + } + + _httpClient = httpClient; PiwikBaseUrl = FixPiwikBaseUrl(apiUrl); IdSite = idSite; @@ -229,17 +261,6 @@ public PiwikTracker(int idSite, string apiUrl) /// public int IdSite { get; } - /// - /// Gets or sets the maximum number of seconds the tracker will spend waiting for a response - /// from Piwik. Defaults to 600 seconds. - /// - public TimeSpan RequestTimeout { get; set; } = TimeSpan.FromSeconds(600); - - /// - /// Gets or sets the proxy used for web-requests, or null if no proxy is used. - /// - public IWebProxy Proxy { get; set; } - /// /// By default, Piwik expects utf-8 encoded values, for example /// for the page URL parameter values, Page Title, etc. @@ -395,7 +416,7 @@ public string GetCustomTrackingParameter(string trackingApiParameter) } /// - /// Gets the stored tracking actions, that have been stored for bulkRequest , . + /// Gets the stored tracking actions, that have been stored for bulkRequest , . /// /// public string[] GetStoredTrackingActions() @@ -585,10 +606,10 @@ protected string GetCookieName(string cookieName) /// /// Page title as it will appear in the Actions > Page titles report /// HTTP Response from the server or null if using bulk requests. - public TrackingResponse DoTrackPageView(string documentTitle = null) + public Task TrackPageViewAsync(string documentTitle = null) { string url = GetUrlTrackPageView(documentTitle); - return SendRequest(url); + return SendRequestAsync(url); } /// @@ -599,10 +620,10 @@ public TrackingResponse DoTrackPageView(string documentTitle = null) /// (optional) The Event's object Name (a particular Movie name, or Song name, or File name...) /// (optional) The Event's value /// HTTP Response from the server or null if using bulk requests. - public TrackingResponse DoTrackEvent(string category, string action, string name = "", string value = "") + public Task TrackEventAsync(string category, string action, string name = "", string value = "") { var url = GetUrlTrackEvent(category, action, name, value); - return SendRequest(url); + return SendRequestAsync(url); } /// @@ -612,10 +633,10 @@ public TrackingResponse DoTrackEvent(string category, string action, string name /// The actual content. For instance the path to an image, video, audio, any text /// (optional) The target of the content. For instance the URL of a landing page. /// HTTP Response from the server or null if using bulk requests. - public TrackingResponse DoTrackContentImpression(string contentName, string contentPiece = "Unknown", string contentTarget = null) + public Task TrackContentImpressionAsync(string contentName, string contentPiece = "Unknown", string contentTarget = null) { var url = GetUrlTrackContentImpression(contentName, contentPiece, contentTarget); - return SendRequest(url); + return SendRequestAsync(url); } /// @@ -627,10 +648,10 @@ public TrackingResponse DoTrackContentImpression(string contentName, string cont /// The actual content. For instance the path to an image, video, audio, any text /// (optional) The target the content leading to when an interaction occurs. For instance the URL of a landing page. /// HTTP Response from the server or null if using bulk requests. - public TrackingResponse DoTrackContentInteraction(string interaction, string contentName, string contentPiece = "Unknown", string contentTarget = null) + public Task TrackContentInteractionAsync(string interaction, string contentName, string contentPiece = "Unknown", string contentTarget = null) { var url = GetUrlTrackContentInteraction(interaction, contentName, contentPiece, contentTarget); - return SendRequest(url); + return SendRequestAsync(url); } /// @@ -641,10 +662,10 @@ public TrackingResponse DoTrackContentInteraction(string interaction, string con /// (optional) Search engine category if applicable /// (optional) results displayed on the search result page. Used to track "zero result" keywords. /// HTTP Response from the server or null if using bulk requests. - public TrackingResponse DoTrackSiteSearch(string keyword, string category = "", int? countResults = null) + public Task TrackSiteSearchAsync(string keyword, string category = "", int? countResults = null) { var url = GetUrlTrackSiteSearch(keyword, category, countResults); - return SendRequest(url); + return SendRequestAsync(url); } /// @@ -653,10 +674,10 @@ public TrackingResponse DoTrackSiteSearch(string keyword, string category = "", /// Id Goal to record a conversion /// Revenue for this conversion /// HTTP Response from the server or null if using bulk requests. - public TrackingResponse DoTrackGoal(int idGoal, float revenue = 0) + public Task TrackGoalAsync(int idGoal, float revenue = 0) { string url = GetUrlTrackGoal(idGoal, revenue); - return SendRequest(url); + return SendRequestAsync(url); } /// @@ -665,11 +686,11 @@ public TrackingResponse DoTrackGoal(int idGoal, float revenue = 0) /// URL of the download or outlink /// Type of the action: 'download' or 'link' /// HTTP Response from the server or null if using bulk requests. - public TrackingResponse DoTrackAction(string actionUrl, ActionType actionType) + public Task TrackActionAsync(string actionUrl, ActionType actionType) { // Referrer could be udpated to be the current URL temporarily (to mimic JS behavior) string url = GetUrlTrackAction(actionUrl, actionType); - return SendRequest(url); + return SendRequestAsync(url); } /// @@ -707,10 +728,10 @@ public void AddEcommerceItem(string sku, string name = "", List categori /// /// Cart grandTotal (typically the sum of all items' prices) /// HTTP Response from the server or null if using bulk requests. - public TrackingResponse DoTrackEcommerceCartUpdate(double grandTotal) + public Task TrackEcommerceCartUpdateAsync(double grandTotal) { string url = GetUrlTrackEcommerceCartUpdate(grandTotal); - return SendRequest(url); + return SendRequestAsync(url); } /// @@ -721,11 +742,11 @@ public TrackingResponse DoTrackEcommerceCartUpdate(double grandTotal) /// Response /// /// Error: you must call the function DoTrackPageView or DoTrackGoal from this class, before calling this method DoBulkTrack() - public TrackingResponse DoBulkTrack() + public async Task BulkTrackAsync() { if (!_storedTrackingActions.Any()) { - throw new InvalidOperationException("Error: you must call the function DoTrackPageView or DoTrackGoal from this class, before calling this method DoBulkTrack()"); + throw new InvalidOperationException($"Error: you must call the function {nameof(TrackPageViewAsync)} or {nameof(TrackGoalAsync)} from this class, before calling this method DoBulkTrack()"); } var data = new Dictionary(); @@ -738,7 +759,7 @@ public TrackingResponse DoBulkTrack() } var postData = new JavaScriptSerializer().Serialize(data); - var response = SendRequest(PiwikBaseUrl, "POST", postData, true); + var response = await SendRequestAsync(PiwikBaseUrl, "POST", postData, true).ConfigureAwait(false); _storedTrackingActions = new List(); @@ -759,10 +780,10 @@ public TrackingResponse DoBulkTrack() /// Shipping amount for this order /// Discounted amount in this order /// HTTP Response from the server or null if using bulk requests. - public TrackingResponse DoTrackEcommerceOrder(string orderId, double grandTotal, double subTotal = 0, double tax = 0, double shipping = 0, double discount = 0) + public Task TrackEcommerceOrderAsync(string orderId, double grandTotal, double subTotal = 0, double tax = 0, double shipping = 0, double discount = 0) { string url = GetUrlTrackEcommerceOrder(orderId, grandTotal, subTotal, tax, shipping, discount); - return SendRequest(url); + return SendRequestAsync(url); } /// @@ -773,11 +794,11 @@ public TrackingResponse DoTrackEcommerceOrder(string orderId, double grandTotal, /// ping requests will create a new visit using the last action in the last known visit. /// /// HTTP Response from the server or null if using bulk requests. - public TrackingResponse DoPing() + public Task PingAsync() { var url = GetRequest(IdSite); url += "&ping=1"; - return SendRequest(url); + return SendRequestAsync(url); } /// @@ -915,7 +936,7 @@ protected internal string GetUrlTrackEcommerce(double grandTotal, double subTota /// /// Builds URL to track a page view. /// - /// + /// /// Page view name as it will appear in Piwik reports /// URL to piwik.php with all parameters set to track the pageview public string GetUrlTrackPageView(string documentTitle = "") @@ -945,7 +966,7 @@ public string GetUrlTrackPageView(string documentTitle = "") /// or /// You must specify an Event action (click, view, add...). - action /// - /// + /// public string GetUrlTrackEvent(string category, string action, string name = "", string value = "") { if (string.IsNullOrWhiteSpace(category)) @@ -982,7 +1003,7 @@ public string GetUrlTrackEvent(string category, string action, string name = "", /// URL to piwik.php with all parameters set to track the pageview /// /// You must specify a content name - contentName - /// + /// public string GetUrlTrackContentImpression(string contentName, string contentPiece, string contentTarget) { if (string.IsNullOrWhiteSpace(contentName)) @@ -1020,7 +1041,7 @@ public string GetUrlTrackContentImpression(string contentName, string contentPie /// or /// You must specify a content name - contentName /// - /// + /// public string GetUrlTrackContentInteraction(string interaction, string contentName, string contentPiece, string contentTarget) { if (string.IsNullOrWhiteSpace(interaction)) @@ -1056,7 +1077,7 @@ public string GetUrlTrackContentInteraction(string interaction, string contentNa /// The category. /// The count results. /// - /// + /// public string GetUrlTrackSiteSearch(string keyword, string category, int? countResults) { var url = GetRequest(IdSite); @@ -1075,7 +1096,7 @@ public string GetUrlTrackSiteSearch(string keyword, string category, int? countR /// /// Builds URL to track a goal with idGoal and revenue. /// - /// + /// /// Id Goal to record a conversion /// Revenue for this conversion /// URL to piwik.php with all parameters set to track the goal conversion @@ -1093,7 +1114,7 @@ public string GetUrlTrackGoal(int idGoal, float revenue = 0) /// /// Builds URL to track a new action. /// - /// + /// /// URL of the download or outlink /// Type of the action: 'download' or 'link' /// URL to piwik.php with all parameters set to track an action @@ -1421,7 +1442,7 @@ public void DisableCookieSupport() _configCookiesDisabled = true; } - private TrackingResponse SendRequest(string url, string method = "GET", string data = null, bool force = false) + private async Task SendRequestAsync(string url, string method = "GET", string data = null, bool force = false) { // if doing a bulk request, store the url if (_doBulkRequests && !force) @@ -1440,27 +1461,30 @@ private TrackingResponse SendRequest(string url, string method = "GET", string d return null; } - var request = (HttpWebRequest)WebRequest.Create(url); - request.Method = method; - request.UserAgent = _userAgent; - request.Headers.Add("Accept-Language", _acceptLanguage); - request.Timeout = (int)RequestTimeout.TotalMilliseconds; - if (Proxy != null) + var request = new HttpRequestMessage { - request.Proxy = Proxy; + RequestUri = new Uri(url, UriKind.Absolute), + Method = new HttpMethod(method) + }; + if (!string.IsNullOrEmpty(_userAgent)) + { + request.Headers.TryAddWithoutValidation("User-Agent", _userAgent); + } + + if (!string.IsNullOrEmpty(_acceptLanguage)) + { + request.Headers.AcceptLanguage.Add(new StringWithQualityHeaderValue(_acceptLanguage)); } if (!string.IsNullOrEmpty(data)) { - request.ContentType = "application/json"; - using (var streamWriter = new StreamWriter(request.GetRequestStream())) - { - streamWriter.Write(data); - } + request.Content = new StringContent(data); + request.Content.Headers.ContentType.MediaType = "application/json"; } - using (var result = (HttpWebResponse)request.GetResponse()) + + using (var response = await _httpClient.SendAsync(request).ConfigureAwait(false)) { - return new TrackingResponse { HttpStatusCode = result.StatusCode, RequestedUrl = url }; + return new TrackingResponse { HttpStatusCode = response.StatusCode, RequestedUrl = url }; } } @@ -1724,7 +1748,9 @@ protected Dictionary GetCustomVariablesFromCookie() { return new Dictionary(); } - return new JavaScriptSerializer().Deserialize>(HttpUtility.UrlDecode(cookie.Value ?? string.Empty)); + + return new JavaScriptSerializer().Deserialize>(HttpUtility.UrlDecode(cookie.Value ?? string.Empty)) ?? + new Dictionary(); } private string FormatDateValue(DateTimeOffset date)