Friday, December 28, 2007

Adding Hidden Fields Programmatically With C#

Sorry it's taken so long to get another post up. The holidays, and the fact that I have a major project due tuesday, have been keeping me from my beloved blogzorz.

This is just something I ran across in my project, it stumped me for about 10 minutes, so I did a search for it, and nothing I saw explained it adequately, or even loaded properly. So here's what I came up with.

I need to add several hidden fields to a form, that contain data needed on the receiving end of a POST request I'll be sending. The values are not static, and need to be a) pulled from a database, and b) used in a crypto method, so obviously just posting HTML input tags just wouldn't cut it. So, I tried having the input tags, but couldn't access them from the codebehind. There are two easy ways to fix this.

1) The CodeBehind Way

In the codebehind, create a new HiddenField:

Hiddenfield field = new HiddenField();

Give it a value:

field.Value = value;

...and set it's ID

field.ID = idValue;

Then, all you have to do is add it to your form:

form.Controls.Add(field);

And it's there! One interesting thing to note, though, is that the ID value you give the HiddenField will be used in the HTML as both the id attribute, and the name attribute. So, if the name attribute is important to your reciever's code (which it is in my case,) make sure you set the ID properly.

2) The Even Easier HTML Way

Add runat="server" to the input tag. I had a face-palm moment when I realized this would work, but it does. The caveat with this method, though, is you have to give it an id attribute as well, or else you won't be able to access it from the codebehind. To set the value using this method, make sure that the HTML is like so:



Then you can edit it in the codebehind as such:

nametocodebehind.Value = hiddenvalue;

And that's it! To make up for not posting last week, I'll be posting again this week, most likely about jewelry and user experience.

Friday, December 14, 2007

URL Sanitization and Picnik

This is a much shorter post than the others have been, but I don't think that's going to be too terrible. ;-P

Anyways, I'm also working on integration with our product with Picnik, and just recently resolved an issue with them. Our images are (or will be) hosted with Amazon's S3 service (which is wicked sweet, if you know how to use it,) and we use secure URLs to access them, along with all the parameters that amazon requires to call a photo (securely.) They fixed the secure URL issue, but for some reason, the photos still would not load in. It turned out that the parameters in the Amazon URL were the problem. They needed to be sanitized (i.e. all "="s became %3D, etc. I found the conversions on this website.) before they'd work. After doing that, they worked fine. One important thing to note, though, is that if I write anything to generate URLs for S3-based images, there should be another one for creating the "editing" url, complete with the picnik url and sanitized S3 URL. Good thing to remember, and it was a reminder that little things like that really have to be watched for, since they happen to me far more often then I'd like to say.

Wednesday, December 12, 2007

OpenSocial Activities Retrieval

NOTE: This code and post was written for an older version of Opensocial. I make no guarantees as to it's validity in later versions.

I know I missed my post last week, but I plan to make up for it with two this week. I've been working on some stuff that I shouldn't be blogging about (company secrets, nothing major, I just have to keep it hush-hush) for the past week, hence nothing major to talk about. However! I did get some fun stuff taken care of yesterday, so now I have something worth posting.

I've been talking a lot with Arne Roomann-Kurrik, a Google employee, and he's been helping me through the problems I've been running into. Yesterday, the two of us discovered (more like he knew and I found out) how retrieving activities work.

Before we begin, there is a major limitation to what you can do. Your application can only retrieve activities it has created. This immediately limits you, as a developer, but just having the functionality provides you with a lot. I'd like to be able to access all of a user's activities, but I can also see why a social networking site would prefer if developers didn't have access to a user's every move.

Alright, now onto the fun stuff. Last post, I mentioned how to create an activity, so I won't go into detail on that again, save to say that you should always remember that duplicate entries won't be posted twice. When you want to load the activities from a user's update feed, you need to make a FetchActivitiesRequest. To do that, you set up a standard DataRequest...


var req = opensocial.newDataRequest();

...add the FetchActivitiesRequest...

req.add(req.newFetchActivitiesRequest("VIEWER"), "viewer_activities");

...and make the request...

req.send(showActivities);

Now, the important things to note are that "viewer_activities" is the variable that the resultant data will be stored in, and that "showActivities" is the method that will be called with said resultant data. Also, I have the request asking for the viewer's activities, but "OWNER" works just as well, even if they aren't the same (i.e. you can view a friend's activities if they are the owner but you are the viewer.)

When we get to the "showActivities" function, things get a little bit stranger. Yes, you do have to pull the data that was sent back, like so...


var response = data.get("viewer_activities").getData();

But the data needs to be segmented further before it is useable. When it is set to viewer_activities, it's actually a collection (opensocial collection), with the two keys: "actvity" and "requestedStream". There's no need to pull them both out if you don't need one, but I did for the sake of science. Here's how you do that.

var activities = response["activities"];
var stream = response["requestedStream"];


Mindblowing, I know. I'm not going to bother with the stream at all, mostly because it's boring, save to say that for some reason, even if you create two different streams, and post events to them, when you retrieve the events, they will claim only to belong to the first. Kind of weird, but it's something I felt I should mention.

Anyways, there are a few ways you can retrieve the data from the activities object. Like "viewer_activities", it is a collection of the activities. If you want every single entry, just use:

activities.each(printActivity)

That will call the printActivity function once with every entry in actvities. Here's my printActivity, it's pretty basic:

function printActivity(activity)
{
document.getElementById("gadgetdiv").innerHTML += activity.getField(opensocial.Activity.Field.TITLE) + "
";
};


You can also use the array (and my preferred) method. Simply convert the collection into an array using:

activities = activities.asArray()

And then you have an array, which you can use indexes with. Hooray!

Also, according to Arne (and the documentation), you can also use the getById function of the collection, but there's no way to get an array of ids, and getById needs the full activity ID. That number, at least in Orkut (where I've been testing) is 20 digits, so you better know it beforehand if you want to use it.

Other than that, that's all it takes to retrieve Activities in OpenSocial! Just remember what you're limited to, and have fun!