Google Analytics API display page views - c#

Using .NET MVC 3, I'd like to display page views on each page of my site. I have google analytics set up.
I'm aware there is an API, but have no idea where to start.
Any pointers for what I need, and more specifically what to be looking at for displaying page views?

Create a file in your Views/Shared folder called _GoogleAnalytics.cshtml (using the underscore in the front is a method of indicating a partial view. It has no effect in MVC, it's just a practice I see done a lot in demo's and screen casts.
Put your google analytics code in it. (make sure to put in your own identifier from Google)
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-########-1']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
Then in your _Layout.cshtml page add this line (assuming you are using Razor)
#Html.RenderPartial("_GoogleAnalytics")
Edit: Just re-read the question, It just occurred to me what you may be looking for is a means to display just the hit counter using data pulled from Google Analytics API?
Which if that's the case I think I missed that part. I've not done this myself but this may be a good start?
http://code.google.com/apis/analytics/docs/mgmt/mgmtFeedReference.html#profileFeed

Related

Internet Explorer redirect on all .Net Core project pages

I'm a .Net Core beginner and look for a solution to protect the application from IE.
I got the following code working in Controller:
string userAgent = Request.Headers["User-Agent"].ToString();
var flagsIE = new [] {"MSIE", "Trident"};
if(flagsIE.Any(userAgent.Contains)){
return RedirectToAction("BadBrowser");
}
Now if someone is trying to visit the page using IE, they get redirected to an info-page asking them to use a modern browser. Instead of adding this code to every single Controller.cs I would like to add it on project level, so that it get's executed independent from the location within of the project.
And, I know that this can be achieved with _Layout.cshtml, my question is:
Where and how would I implement a function to get it executed for all requested views withing the project without adding it every single request within Controller.
Thank you in advance.
As Icepickle suggested, in the comments of my question, I used middleware in Startup.cs and got the desired result:
app.Use(async (context,next) =>
{
string userAgent = context.Request.Headers["User-Agent"].ToString();
var IEkeywords = new [] {"MSIE", "Trident"};
if (IEkeywords.Any(userAgent.Contains)){
context.Response.Redirect("/IE/redirect/badbrowser.html");
return;
}
await next();
});
You can try to add js in _Layout.cshtml to detect the browser is IE:
<script>
var isIE = false || !!document.documentMode;
if (isIE) {
window.location.href = "/Home/ForbidInfo";
}
</script>
Then create a view named ForbidInfo under Home controller which to show the message to user that he cannot use the IE to show views.
(Notes: this view's Layout must be null ,or it will enter an endless loop)
#{
ViewData["Title"] = "ForbidInfo";
Layout = null;
}
<h1>Please use a modern browser!</h1>
After these settings, when you running a view in IE, it will be redirected to the FordidInfo page.
If your page does not use _layout, then you need to add the js on the corresponding view separately to ensure that it will not be displayed in IE.
Never do that. Excluding browsers with redirects, is what lead to massive user agent spoofing. Effectively making that AgentId useless. And the way you wrote it, you may get a lot of false-positives.
It is also a bad idea from the early days of the internet, we are hoping to get rid off:
https://en.wikipedia.org/wiki/User_agent#User_agent_spoofing

How to bundle specific CSS according to browser version?

I'm using MVC4 StyleBundle to bundle up a bunch of CSS. There is one CSS that's only needed for IE 9 or lower.
In my BundleConfig class of RegisterBundles method, I have:
if (HttpContext.Current.Request.Browser.Browser.Trim().ToUpperInvariant().Equals("IE") && HttpContext.Current.Request.Browser.MajorVersion <= 9)
cssBundle.Include("~/Content/ie.css");
But then I got a Request is not available in this context error. Is it not possible to detect browsers during RegisterBundles method?
you can add something like :
<script type="text/javascript">
var domLib = '#System.Web.Optimization.BundleTable.Bundles.ResolveBundleUrl("~/Zepto")';
if (navigator.userAgent.indexOf('MSIE ') > -1) {
domLib = '#System.Web.Optimization.BundleTable.Bundles.ResolveBundleUrl("~/Jquery")';
}
document.write('<script src="' + domLib + '"><\/script>');
</script>
In this example I use the library Zepto, and Jquery if it's Internet Explorer. It works fine for me.
Pierre
Yep Tejs is correct. Bundles are global and cannot vary based on request because they are cached on the server after being referenced for the first time. So the issue with what you are doing above, is that depending on what browser hits the request first, that will populate the cache and determine what all subsequent requests will recieve, regardless of whether they are IE9 or not.

A system that intergates with Tibco spotfire

I want to develop a system that integrates with Tibco Spotfire and is able to Retrieve Visualizations rendered by Spotfire and expose them for WYSIWYG manipulation. Is this possible?
If so someone please offer guidance. I want to use C# and ASP.NET
first load the javascriptapi for handling client interactions
<script type="text/javascript" src="http://domainname/SpotfireWeb/GetJavaScriptApi.ashx?Version=3.1" > </script>
add the code for adding the spotfire template to web page
create a javascript file in your project with the code below:
function addPlayer()
{
var fileInfo = new FileInformation(SpotfireVisualizationPath,SpotfireVisualizationName,SpotfireParameter, '');
var customization = new spotfire.webPlayer.Customization();
customization.showCustomizableHeader = false;
customization.showToolBar = false;
customization.showClose = false;
customization.showTopHeader = false;
if (app != null)
{
app.close();
}
app = new spotfire.webPlayer.Application(SpotfireWebPlayerURL, customization);
app.open(fileInfo.path, 'SpotfireContainer', fileInfo.parameters);
}
The Spotfire Web Player (which I assume you refer to) is not built in this way - in its current implementation it is more like a remote desktop session to the desktop Spotfire application (if you replace the remote desktop technology with html and javascript).
It simply is not built to be able to grab pieces of the UI for reuse in other contexts. The closest you can do is host the entire web player UI in an iframe and use the javascript API for client-side interactions. By creating single-visualization pages and removing all chrome (toolbars etc) you can get to something that appears to be a single visualization on a page, but it's really just a hack.

JavaScript in C# ASP MVC issue

We have a web project that takes data from an MS SQL database and uses the Google Visualisation API to display these charts on the web view.
Recently we have added castle windsor so we can configure the application to different users with an XML file. Before we added this, the view worked fine, using the baked in parameters that were needed for this query. For some reason, when we send in the parameters from the XML files (Running with breakpoints shows that the parameters are being passed to the main controller action for the page) the data isn't being returned. here is some of the code for you.
JavaScript
<script type="text/javascript">
var csvDataUrl = '#Url.Action("TradeValuesDataCsv", "Dashboard")';
var jsonDataUrl = '#Url.Action("TradeValuesDataJson", "Dashboard")';
google.load("visualization", "1", { packages: ['table', 'corechart', 'gauge'] });
google.setOnLoadCallback(drawCharts);
drawCharts();
$("body").on({
ajaxStart: function () {
$(this).addClass("loading");
},
ajaxStop: function () {
$(this).removeClass("loading");
}
});
function drawCharts() {
var queryString = 'platform=' + $('#PlatformDropDownList').val();
queryString += '&startDate=' + $('#startDatePicker').val();
queryString += '&endDate=' + $('#endDatePicker').val();
queryString += '&model=' + $('#ModelDropDownList').val();
queryString += '&eventType=' + '#Model.EventType';
queryString += '&parameterName=' + '#Model.ParameterName';
$.ajax({
type: "POST",
url: jsonDataUrl,
data: queryString,
statusCode: {
200: function (r) {
drawToolbar(queryString);
drawTable(r);
drawChart(r);
},
400: function (r) {
},
500: function (r) {
}
}
});
}
Main controller Method for this page:
public ActionResult ActionResultName(EventTypeParameterNameEditModel model)
{
var viewModel = new EventTypeParameterNameViewModel(_queryMenuSpecific);
viewModel.EventType = model.EventType;
viewModel.ParameterName = model.ParameterName;
PopulateFilters(viewModel);
return this.View(viewModel);
}
Retrieve the JSON Data Controller Method:
public ActionResult ActionResultNameJson(EventTypeParameterNameEditModel filters)
{
List<CustomDataType> results = this.GetTradeValues(filters);
return this.Json(results, JsonRequestBehavior.AllowGet);
}
EDIT I have managed to find a solution, even if it is a rather messy one. I have some filters built into the page that allow the user to filter by device and by OS, and these were being populated on the page load with 'undefined'. I didn't spot this first time round with NHProf Running, but this wasn't happening when the page loaded before we configured the input to be from XML. I will add this as an answer and accept it and close the question. Thanks everyone for your attempts to help. Starting to really like this community. Perfect place to find help as a Graduate Developer.
Yep. I'm not a Razor syntax expert but I think these property references are probably your problem. I suspect razor is going to tend to avoid asserting itself inside strings being used in statements with properties in JS contexts. Or you could try implementing as getter functions which would probably work. Otherwise an # and a . in a string could easily lead to confusing mixups with email addresses when it's not an obvious method call:
queryString += '&eventType=' + '#Model.EventType';
queryString += '&parameterName=' + '#Model.ParameterName';
As a general rule in any server to client-side scenario, my advice is to confine JavaScript direct from the back end to JSON objects only. That way you have more granular control over what's going on on both sides of the http request wall and your client-side devs don't have to figure where stuff is getting built if there's a short-term need to quickly modify. In general, don't build behavioral code with other code if you can avoid it.
I couldn't convince my .net MVC boss at first but he slowly came around to the idea on his own months later.
We also store a URL base path along with some other context-shifting params in a standard JSON object that loads on every page so the JS devs can add these things linked JS files rather than have to work with JS in the HTML (I don't recall why but document.location wasn't always going to work).
Lastly, try to keep the JS out of the HTML. Link it. It seems like a pain from a procedural POV but trust me. It makes life much easier when you are juggling 3 major concerns as one ball each rather than all in the same jumbled HTML/template mess.
It turned out that the problem was not in my Javascript. I have some filters in there that allow the user to filter the results my model and operating system and date and what not. These were being automatically populated on page load with 'undefined' which is not an option in the database. I added something to catch that in the call to the query and it seemed to solve the problem.

How do I configure Google Analytics to seperate Dev/Test and production sites?

I fairly new to Google Analytics. I'm looking for a way to add GA to my ASP.Net (C#) site, but keep the numbers for different environments from getting mixed up.
I'd like to only have to set up the script on my master page once and then use either the full URL of the request or a web.config setting to put each environment into a seperate reporting bin.
-- Edit --
I've attempted to use the suggestion from aj_whiz, but ran into an issue when opening a page with an AJAXControl Toolkit control on it. Here's the code I was trying to use.
<%# Master Language="C#" AutoEventWireup="true" Codebehind="MasterPage2.master.cs" Inherits="TruckMo.MasterPage2" %>
<%# Register Src="LinkMenu.ascx" TagName="LinkMenu" TagPrefix="uc1" %>
TRAC Connect
var _gaq = _gaq || [];
_gaq.push(['_setAccount', '<%=ConfigurationManager.AppSettings["GoogleAnalyticsCode"]%>']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
The error I get is "The Controls collection cannot be modified because the control contains code blocks (i.e. <% ... %>)."
The location is in AjaxControlToolkit.ScriptObjectBuilder.RegisterCssReferences(...)
The line is header.Controls.Add(link);
A quick comment, Google changed the tracking code a few months ago to support asycn updates.
The NEW code is in the header, the OLD code at the bottom of the page. The discussion above is a confusion between the two (top block is the new, and bottom block the old).
Googly Analytics code looks like
<script type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>
<script type="text/javascript">
var pageTracker = _gat._getTracker('<%=ConfigurationManager.AppSettings["GoogleAnalyticsCode"]%>');
pageTracker._initData();
pageTracker._trackPageview();
</script>
you can put the above code in master page and the Google Analytics code in web.config file notice the line
_gat._getTracker('<%=ConfigurationManager.AppSettings["GoogleAnalyticsCode"]%>');
where the anatytics code will be picked up from web.config
The easiest way is to create Dev and Prod profiles. Profiles are a feature that lets you create a view of your Analytics data that only shows traffic where the URL matches a given regular expression. See the documentation here.
Thanks a lot, it worked for me in aspx pages by giving the like this.
Under web.config, <appSettings> ... </appSettings>add:
<add key="GoogleAnalyticsCode" value="**xx-xxxxxxxx-x**"/>
Where xx-xxxxxxxx-x is google analytics code, getting during domain addition
Under aspx master pages only, copy the below code right before the </body> tag:
<script type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>
<script type="text/javascript">
var pageTracker = _gat._getTracker('<%=ConfigurationManager.AppSettings["GoogleAnalyticsCode"]%>');
pageTracker._initData();
pageTracker._trackPageview();
</script>

Categories