I need to get the free Google charts working over SSL without any security errors. I am using c# and asp.net.
As Google charts does not support SSL by default, I am looking for a robust method of using there charts but ensuring my user doesn't get any security warnings over their browser.
One thought was to use a handler to call the charts api and then generate the output my site needs.
Similar to Pants are optional blog post. I haven't been able to get this example working at this stage.
Any suggestions, or samples are welcome.
Thanks
the Google Charts API is now available over HTTPS at via https at chart.googleapis.com.
Source: http://www.imperialviolet.org/2010/11/29/charthttps.html
We do this automatically in the NetQuarry Platform - it's pretty simple, although you do force the image to come through your site vs. charts.google.com, making your browser run the request through a single connection.
Since a chart is just a link to an image, what we do is to build the link to the chart (a much more complex process, obviously), then add the whole link to the query string on an internal handler (handler.ashx?req=chart& ). So the new link looks like this:
handler.ashx?act=chrt&req=chart&cht=p3&chs=450x170&chd=s:HAR9GBA&chl=New|In%20Progress|Responded|Won't%20Respond|On%20Hold|Future|Review|&chg=20,20,1,5&chg=10,25,1,5&chco=0A477D
Then, we simply download the image data and write it back as the response.
Here's the code:
Blockquote
private void GoogleChart(HttpContext cxt)
{
const string csPrefix = "?act=chrt&req=chart&";
HttpRequest req = cxt.Request;
HttpResponse rsp = cxt.Response;
string sUrl = cxt.Request.RawUrl;
int nStart = sUrl.IndexOf(csPrefix, StringComparison.OrdinalIgnoreCase);
rsp.Clear();
if (nStart > 0)
{
sUrl = "http://chart.apis.google.com/chart?" + sUrl.Substring(nStart + csPrefix.Length);
System.Net.WebClient wc = new System.Net.WebClient();
byte[] buffer = wc.DownloadData(sUrl);
cxt.Response.ClearContent();
cxt.Response.ClearHeaders();
cxt.Response.ContentType = "application/octet-stream";
cxt.Response.AppendHeader("content-length", buffer.Length.ToString());
cxt.Response.BinaryWrite(buffer);
}
}
I Have a partial solution that has one issue.
here is the link to my new post asking for help with a specific problem regarding my solution
My Attempt at a SSL handler
Related
Just finished an automatic newsletter-subscriber module written in C#. Now I have to translate it in PHP so I can use it with my wordpress sites as well. I'm not that good in PHP as most of the time I'm writting .NET MVC applications. In C# I came up with the following solution:
// Code below runs each time a user submits the newsletter form
using (var client = new WebClient()) {
var MyValues = new NameValueCollection();
MyValues["list"] = "123456789";
MyValues["boolean"] = "true";
MyValues["name"] = model.NameSec;
MyValues["email"] = model.EmailSec;
var MyResponse = client.UploadValues("http://www.XXXXXX.com/subscribe", MyValues);
var MyValue = Encoding.Default.GetString(MyResponse);
if (MyValue.Equals("true")) {
// All correct
}
else {
// Oops, smth went wrong
}
}
Now I'm looking for a similar method as WebClient.UploadValues but for PHP. Could you please give me some guidance?
WebClient.UploadValues() is making a POST request to your URI. To achieve the same in PHP, you should look into Curl. There are plenty of examples available and a number of questions that already address the topic.
This is probably the best answer with source code/examples.
I am trying to upload an image to Twitter using Twitter API Version 1.1 and the update_with_media.json method.
https://dev.twitter.com/docs/api/1.1/post/statuses/update_with_media
This is the code I have so far, yet despite numerous variations I can not get a successful upload.
public TwitterResponse UpdateStatus(string message, String fileName, String contentType, byte[] image)
{
RestClient client = new RestClient
{
Authority = TwitterConstants.Authority,
VersionPath = TwitterConstants.Version
};
message = HttpUtility.HtmlEncode(message);
client.AddHeader("content-type", "multipart/form-data");
client.AddField("status", message);
client.AddField("media[]", Convert.ToBase64String(image) + ";filename=" + fileName + ";type=" + contentType);
RestRequest request = new RestRequest
{
Credentials = this.Credentials,
Path = "statuses/update_with_media.json",
Method = Hammock.Web.WebMethod.Post
};
return new TwitterResponse(client.Request(request));
}
I am using Hammock to perform these requests.
Just to rule out possible other issues, I can successfully post a status update to Twitter using the update.json method.
I have also tried using the client.AddFile method and using Fiddler it looks like everything is in place. But the error message I keep getting back is
{"errors":[{"code":195,"message":"Missing or invalid url parameter"}]}
Instead of using native Twitter API, you can use TweeterSharp plugin available at Nuget.
Sample with description is written at this article by me Post message with image on twitter using C#
In particular this is the code snippet
using (var stream = new FileStream(imagePath, FileMode.Open))
{
var result = service.SendTweetWithMedia(new SendTweetWithMediaOptions
{
Status = message,
Images = new Dictionary<string, Stream> { { "john", stream } }
});
lblResult.Text = result.Text.ToString();
}
The complete demo is downloadable attached with the article, feel free to download.
Thanks
I've never used Hammock or or c#, but I know that we had a similar issue...
Our core twitter library worked for everything, but we couldn't get image uploads to work. It turns out that the OAuth library that our twitter lib depended on didn't calculate the signature properly when posting files. We had to update our oauth to get it work.
In our case the exact code we were trying to use worked fine once I substituted an updated OAuth.
If you are using an older version of OAuth, I would suggest looking for a more recent version, and pulling together a quick script to try with that.
Regarding that error message, it may be more of a red herring than a valid message - especially because it's not even listed on their error page:
https://dev.twitter.com/docs/error-codes-responses
I previously found the this article about how to submit google docs forms via C#.
It seems that, since that was written, the method has broken, however.
If I use the actual online form, it updates immediately (without refreshing even). But if I use this method, it returns success, but no data ever shows up.
Anyone know how to do this now?
Change formkey string and try this:
string formkey = <your form key>;
WebClient wc = new WebClient();
var keyval = new NameValueCollection();
keyval.Add("entry.0.single", "aaa");
keyval.Add("entry.1.single", "bbb");
Uri uri = new Uri("https://spreadsheets.google.com/spreadsheet/formResponse?formkey="+formkey);
wc.UploadValuesAsync(uri, "POST", keyval, Guid.NewGuid().ToString());
This is not a hack, as your linked (broken?) solution is, so a little heavier. But Google provides an API for Google Docs.
the provided link is updated.
however as google is moving from google docs to google drive, you need to make some modification to adapt to changes.
i build mini Question Answering System in C#. I need retrieve document by google Search.
What is google tools name, i can use it in my project?
Thanks
One possibility is to set up a custom Google search engine. Then you also need to create a developer key, which I believe is done under the console.
After setting that up, you can make REST style call with code such as the following, which retrieves the results as JSON:
WebClient w = new WebClient();
string result;
string uri;
string googleAPIKey = "your developer key";
string googleEngineID = "your search engine id";
string template = "https://www.googleapis.com/customsearch/v1?key={0}&cx={1}&q={2}&start={3}&alt=json";
int startIndex = 1;
int gathered = 0;
uri = String.Format(template, googleAPIKey, googleEngineID, "yoursearchstring", startIndex);
result = w.DownloadString(uri);
For extracting the information from the JSON results, you can use something like Json.NET. It makes it extremely easy to read the information:
JObject o = JObject.Parse(result);
Then you can directly access the desired information with a single line of code.
One important piece of information is that the search API free usage is extremely limited (100 requests per day). So for a real-world application it would probably be necessary to pay for the search. But depending on how you use it, maybe 100 requests per day is sufficient. I wrote a little mashup using the Google search API to search for Stackoverflow site information of interest and then used the StackExchange API to retrieve the information. For that personal use, it works very well.
I've never used it before (and it's alpha), but take a look at Google APIs for .NET Framework library.
I'm wanting to copy an already existing Google Docs Spreadsheet to a new Google Docs spreadsheet. I dont think the v2.0 .NET API can handle it natively (or if so I can't find the class/method), however It looks like the v3.0 protocol can but I'm not sure how to implement this in the current framework or even if it is possible with the current .net api. eg. ~DocumentsFeed.copy() (pseudo code).
Exporting to a temp excel file then uploading with a new name is not possible either as some of the complex formulas get messed up in the conversion process.
I am a bit of a .NET noob so any info would be greatly appreciated eg. How would I go about doing this in .NET if I could only use the v3 protocol (ajax etc) and not the .NET API.
Thanks
EDIT: (final class thanks to #langsamu for his help!)
using System;
using Google.GData.Documents;
using Google.GData.Client;
using Google.GData.Extensions;
public class GoogleDocument
{
private DocumentsService ds;
private String username;
private String password;
public GoogleDocument(String username, String password)
{
this.ds = new DocumentsService("doc service name");
this.username = username;
this.password = password;
this.ds.setUserCredentials(username, password);
this.ds.QueryClientLoginToken();
}
public void copyDocument(String oldFileName, String newFileName)
{
SpreadsheetQuery query = new Google.GData.Documents.SpreadsheetQuery();
query.Title = oldFileName;
query.TitleExact = true;
DocumentsFeed feed = this.ds.Query(query);
AtomEntry entry = feed.Entries[0];
entry.Title.Text = newFileName;
var feedUri = new Uri(DocumentsListQuery.documentsBaseUri);
this.ds.Insert(feedUri, entry);
}
}
Google.GData.Documents.DocumentsService service = new Google.GData.Documents.DocumentsService("YOUR_APPLICATIONS_NAME");
service.setUserCredentials("YOUR_USERNAME", "YOUR_PASSWORD");
Google.GData.Documents.SpreadsheetQuery query = new Google.GData.Documents.SpreadsheetQuery();
query.Title = "YOUR_SPREADSHEETS_TITLE";
query.TitleExact = true;
Google.GData.Documents.DocumentsFeed feed = service.Query(query);
Google.GData.Client.AtomEntry entry = feed.Entries[0];
var feedUri = new Uri(Google.GData.Documents.DocumentsListQuery.documentsBaseUri);
service.Insert(feedUri, entry);
This solution is basically about retrieving an existing spreadsheet (service.Query) using the Document List API and re-inserting it (service.Insert).
Make sure you replace the ALL CAPS application name, username, password and spreadsheet title.
Add a reference to Google.GData.Documents.
This is using .NET 4 (should work with lower versions as well) and Google Documents List Data API v2.0 (DLL says version is 1.6.0.0: google-gdata), which seems to use version 3.0 of the protocol.
It is a bit unclear if you are developing a web application or a desktop application, so I'll try and cover both (essentially they are very much alike - because...).
If you are developing a web application you won't be able to make a 100% AJAX solution. You will only be able to request URL's on the same domain. To do this you will need to either do the communication server side only, or do it server side and proxy it to your web app through AJAX.
If you are developing a desktop application you'll have to do this stuff aswell. Except the AJAX part.
An example app would be fairly easy - 2-3 hours work to whip up considering the documentation given. With just a little knowledge of HTTP and POST request forming you should be able to make it work.