Connect to Google Analytics from Silverlight - c#

I created a simple SL 4 app to connect to Google Analytics but I keep getting the following exception:
{System.Security.SecurityException: Security error.
at System.Net.Browser.BrowserHttpWebRequest.InternalEndGetResponse(IAsyncResult asyncResult)
at System.Net.Browser.BrowserHttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
at GoogleAnalytics.Silverlight.MainPage.<>c__DisplayClass4.<GetResponseCallback>b__3()}
I think it has something to do with xss but I'm not sure how to get around that. The following code works fine in a console app but doesn't in SL.
The UI has a textblock control, here's the code:
private byte[] _data;
public MainPage()
{
InitializeComponent();
this.Loaded += new RoutedEventHandler(MainPage_Loaded);
}
private void MainPage_Loaded(object sender, RoutedEventArgs e)
{
string requestData = "Email=email#gmail.com" +
"&Passwd=password" +
"&source=Test-App" +
"&accountType=GOOGLE" +
"&service=analytics";
_data = Encoding.UTF8.GetBytes(requestData);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(new Uri("https://www.google.com/accounts/ClientLogin", UriKind.Absolute));
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = _data.Length;
request.BeginGetRequestStream(GetRequestStreamCallback, request);
}
private void GetRequestStreamCallback(IAsyncResult asynchronousResult)
{
this.Dispatcher.BeginInvoke(() =>
{
try
{
HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
Stream stream = request.EndGetRequestStream(asynchronousResult);
stream.Write(_data, 0, _data.Length);
stream.Close();
request.BeginGetResponse(GetResponseCallback, request);
}
catch (Exception e)
{
textBlock.Text = e.ToString();
}
});
}
private void GetResponseCallback(IAsyncResult asynchronousResult)
{
this.Dispatcher.BeginInvoke(() =>
{
try
{
HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);
Stream stream = response.GetResponseStream();
StreamReader streamReader = new StreamReader(stream, Encoding.UTF8);
textBlock.Text = streamReader.ReadToEnd().Split(new string[] { "Auth=" }, StringSplitOptions.None)[1];
streamReader.Close();
response.Close();
}
catch (Exception e)
{
textBlock.Text = e.ToString();
}
});
}
Update: fixed a typo.
Thanks

Just some tipps, i haven't tested your code yet, but they might help.
Use a WebClient for Web requests, it's much less and cleaner code... You will find examples on MSDN <- this link also contains almost all interesting topics on Silverlight Web/http/https requests and security - a must read in your scenario
Problems might occur if you're testing from a wrong environment like testing the Silverlight object from a local file url (web Url starting with file:///...). Create a Web-Project in your service, configure the Silverlight Project to run in that created Web project under the Test Web Server or the local IIS
I know, no code examples just links or tipps, they might help you though.
Best regards
UPDATE
What exactly are you trying to do? If you want to track, I've seen a few ready solutions for silverlight, for example Silverlight Analytics or Tracking Silverlight. Here is another known solution.

Silverlight cannot connect to GA services, I either have to use a service or JavaScript then pass the data to Silverlight.

Related

HttpWebResponse Returns 404 Error When Page Exists

I'm trying to write a small desktop application that will monitor a website through their API. I've never really done much work with APIs or WebRequests, so I'm unsure as to how to proceed with this error. After generating a requests, I try to GET the response from the page, but this returns a 404 error, even though if I navigate to the same URL in my browser it works fine. I have no idea how to get around this, and the research I've done on people who had the same problem hasn't helped me to understand it. Could someone explain to me what is happening at a basic level? My code has been posted below:
private void Window_Loaded(object sender, RoutedEventArgs e)
{
string sURL;
sURL = #"https://habitrpg.com/api/v1/user";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(sURL);
HttpWebResponse response = null;
try
{
response = (HttpWebResponse)request.GetResponse();
}
catch (Exception ex)
{
resultText.Text = "Oh no!";
}
Stream receiveStream = response.GetResponseStream();
StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8);
string responseData = readStream.ReadToEnd();
}
You should ignore https certificate, look at this question:
How do I use WebRequest to access an SSL encrypted site using https?

http post request crashing

I'm trying to excecute some post request, I censored the site because it has some sensitive data.. Well here's the code:
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://www.someaddress.com");
// Add your data
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
nameValuePairs.add(new BasicNameValuePair("sdata", ""));
try {
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs,HTTP.UTF_8));
Log.d("MyTag", "works till here.");
try {
HttpResponse response = httpclient.execute(httppost);
// String responseBody = EntityUtils.toString(response.getEntity());
// Log.d("MyTag", responseBody);
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
It crashes on that line:
HttpResponse response = httpclient.execute(httppost);
Here's the logcat which really says nothing to me:
http://pastebin.com/F0YAiNLD
What could be the problem? Why is it crashing?
I'm trying to translate this C# code to JAVA. The C# code works but the JAVA code isn't.
Here's the C# code:
System.Text.UTF8Encoding encoding=new System.Text.UTF8Encoding();
string pData = "";
byte[] sdata = encoding.GetBytes(pData);
HttpWebRequest request = new HttpWebRequest(new Uri("http://www.someaddress.com"));
request.ContentType="application/x-www-form-urlencoded";
request.ContentLength = sdata.Length;
Stream nStream=request.GetRequestStream();
nStream.Write(sdata,0,sdata.Length);
nStream.Close();
HttpWebResponse response =
(HttpWebResponse) request.GetResponse();
I'm not an Android developer but a simple Google search for "Android NetworkOnMainThreadException" shows that this exception is thrown when you attempt to do network actions on the main event thread (the name is pretty self-descriptive), and that instead you should be making these type of network calls on a background thread.
Typically in GUI apps it is a bad idea to do work in the main thread that can block (such as a network HTTP call) since it will block the main animation loop.

Sending a http request in C# and catching network issues

I previously had a small VBScript that would test if a specific website was accessible by sending a GET request. The script itself was extremely simple and did everything I needed:
Function GETRequest(URL) 'Sends a GET http request to a specific URL
Dim objHttpRequest
Set objHttpRequest = CreateObject("MSXML2.XMLHTTP.3.0")
objHttpRequest.Open "GET", URL, False
On Error Resume Next 'Error checking in case access is denied
objHttpRequest.Send
GETRequest = objHttpRequest.Status
End Function
I now want to include this sort of functionality in an expanded C# application. However I've been unable to get the same results my previous script provided.
Using code similar to what I've posted below sort of gets me a proper result, but fails to run if my network connection has failed.
public static void GETRequest()
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://url");
request.Method = "GET";
HttpStatusCode status;
HttpWebResponse response;
try
{
response = (HttpWebResponse)request.GetResponse();
status = response.StatusCode;
Console.WriteLine((int)response.StatusCode);
Console.WriteLine(status);
}
catch (WebException e)
{
status = ((HttpWebResponse)e.Response).StatusCode;
Console.WriteLine(status);
}
}
But as I said, I need to know if the site is accessible, not matter the reason: the portal could be down, or the problem might reside on the side of the PC that's trying to access it. Either way: I don't care.
When I used MSXML2.XMLHTTP.3.0 in the script I was able to get values ranging from 12000 to 12156 if I was having network problems. I would like to have the same functionality in my C# app, that way I could at least write a minimum of information to a log and let the computer act accordingly. Any ideas?
A direct translation of your code would be something like this:
static void GetStatusCode(string url)
{
dynamic httpRequest = Activator.CreateInstance(Type.GetTypeFromProgID("MSXML2.XMLHTTP.3.0"));
httpRequest.Open("GET", url, false);
try { httpRequest.Send(); }
catch { }
finally { Console.WriteLine(httpRequest.Status); }
}
It's as small and simple as your VBScript script, and uses the same COM object to send the request.
This code happily gives me error code like 12029 ERROR_WINHTTP_CANNOT_CONNECT or 12007 ERROR_WINHTTP_NAME_NOT_RESOLVED etc.
If the code is failing only when you don't have an available network connection, you can use GetIsNetworkAvailable() before executing your code. This method will return a boolean indicating if a network connection is available or not. If it returns false, you could execute an early return / notify the user, and if not, continue.
System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable()
using the code you provided above:
public static void GETRequest()
{
if (!System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable())
return; //or alert the user there is no connection
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://url");
request.Method = "GET";
HttpStatusCode status;
HttpWebResponse response;
try
{
response = (HttpWebResponse)request.GetResponse();
status = response.StatusCode;
Console.WriteLine((int)response.StatusCode);
Console.WriteLine(status);
}
catch (WebException e)
{
status = ((HttpWebResponse)e.Response).StatusCode;
Console.WriteLine(status);
}
}
This should work for you, i've used it many times before, cut it down a bit for your needs: -
private static string GetStatusCode(string url)
{
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
req.Method = WebRequestMethods.Http.Get;
req.ProtocolVersion = HttpVersion.Version11;
req.UserAgent = "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)";
try
{
HttpWebResponse response = (HttpWebResponse)req.GetResponse();
StringBuilder sb = new StringBuilder();
foreach (string header in response.Headers)
{
sb.AppendLine(string.Format("{0}: {1}", header, response.GetResponseHeader(header)));
}
return string.Format("Response Status Code: {0}\nServer:{1}\nProtocol: {2}\nRequest Method: {3}\n\n***Headers***\n\n{4}", response.StatusCode,response.Server, response.ProtocolVersion, response.Method, sb);
}
catch (Exception e)
{
return string.Format("Error: {0}", e.ToString());
}
}
Feel free to ignore the section that gets the headers

Obtaining a string from a JSON GET Request

I am developing an application for the Windows Phone 7. I am making a GET request to a JSON service. The return type of the request is an object.
My question is, how do I create a string from the information in the object. The code below is what I am using to make the request and process the response.
HttpWebRequest carRequest = (HttpWebRequest)WebRequest.Create(carUrl);
carRequest.Method = "GET";
carRequest.BeginGetResponse(new AsyncCallback(ProcessResponse), carRequest);
private void ProcessResponse(IAsyncResult asyncResult)
{
HttpWebRequest request = (HttpWebRequest)asyncResult.AsyncState;
WebResponse response = (HttpWebResponse)request.EndGetResponse(asyncResult);
StreamReader sr = new StreamReader(response.GetResponseStream());
Car.car = (Car)JsonConvert.DeserializeObject(sr.ReadToEnd(), typeof(Car));
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
NavigationService.Navigate(new Uri("/SearchResults.xaml", UriKind.Relative));
});
}
Why not use a WebClient?
private void DownloadString()
{
var wc = new WebClient();
wc.DownloadStringCompleted += MyHandler;
wc.DownloadStringAsync(carUrl);
}
void MyHandler(object sender, DownloadStringCompletedEventArgs e)
{
var result = e.Result;
}
Note that this is a general solution for downloading a string. If you are resolving JSON, then use one of the methods included in JSON.Net for this kind of interaction.
Also note that you may want to stash your result object somewhere so it can be accessed on your search result page, or do the downloading/deserialising there.
You should be able to use the JsonConvert.SerializeObject as detailed below :-
http://james.newtonking.com/projects/json/help/SerializingJSON.html

Web Requests in C# for SilverLight 2.0

I have been using the following code to obtain a simple web response from Apache 2.2 in SilverLight to no avail.
private void bDoIt_Click(object sender, RoutedEventArgs e)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(new Uri("/silverlight/TestPage2.html"));
request.Method = "POST";
request.ContentType = "text/xml";
request.BeginGetRequestStream(new AsyncCallback(RequestProceed), request);
}
private void RequestProceed(IAsyncResult asuncResult)
{
HttpWebRequest request = (HttpWebRequest)asuncResult.AsyncState;
StreamWriter postDataWriter = new StreamWriter(request.EndGetRequestStream(asuncResult));
postDataWriter.Close();
request.BeginGetResponse(new AsyncCallback(ResponceProceed), request);
}
private void ResponceProceed(IAsyncResult asuncResult)
{
HttpWebRequest request = (HttpWebRequest)asuncResult.AsyncState;
HttpWebResponse responce = (HttpWebResponse)request.EndGetResponse(asuncResult);
StreamReader responceReader = new StreamReader(responce.GetResponseStream());
string responceString = responceReader.ReadToEnd();
txtData.Text = responceString;
}
Does anyone no a better method of doing this?
Have you tried WebClient? This exists on silverlight, and might make life easier. Presumably you'd want UploadStringAsync.
Also - I believe you need to use and absolute url; if you don't want to hard code (quite reasonably), you can get your host from:
string url = App.Current.Host.Source.AbsoluteUri;
Then use string / etc methods to make the correct "http://yoursite/whatever/your.page";
Note that silverlight only allows (IIRC) connections to the host site.
You can do the BeginGetResponse call as the first call in your sample test case, the BeginGetRequestStream call is only needed if you are intending to pass some POST data to the requested page.

Categories