If Web Comments Met Real Life Situations (NSFW)
This made me laugh so hard that I just had to share it. You don’t really realize just how juvenile some people until you can see and hear it.
while(!(succeed = try()));
This made me laugh so hard that I just had to share it. You don’t really realize just how juvenile some people until you can see and hear it.
Recently I have been diving in to the world of REST and all the great things that come along with that. If you are not familiar with REST and what it means to have a REST Web Service for your site, you can go through the Digg API, which should give you a pretty good idea. My company has been contracted to build the framework for a new Web 2.0 initiative of one of our clients. You cannot do Web 2.0 if you are not using some kind of AJAX/REST combination.
With the inclusion of Microsoft AJAX.NET are some very useful tools that have been added to the web services library. My current focus in System.Web.Script.Serialization.JavaScriptSerializer, which takes you objects and turns them in to a JSON string that can be evaluated by JavaScript and reversed in to an object. JSON (pronounced Jason) is very useful in AJAX because you do not have to retrieve and parse XML through the XML Browser Request that powers current AJAX implementations.
I found the attribute support lacking in the JavaScriptSerializer when compared to the XmlSerializer, ScriptIgnoreAttribute compared to XmlRootAttribute, XmlAttributeAttribute, XmlIgnoreAttribute, XmlElementAttribute, XmlArrayAttribute, and XmlArrayItemAttribute. So I decided to extend the JavaScriptSerializer to use the XML attributes to serialize my objects and give me greater control over how they were written in to JSON text form. The added benefit was that my XML and JSON outputs serialized the exact same way when the web service generated them. Below I have included the code.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Reflection;
using System.Web.Script;
using System.Web.Script.Serialization;
using System.Xml.Serialization;
namespace ManagedFusion.Script.Serializer
{
public class XmlJavaScriptConverter<T> : JavaScriptConverter
{
public override object Deserialize(IDictionary<string,string> dictionary, Type type, JavaScriptSerializer serializer)
{
throw new Exception("The method or operation is not implemented.");
}
public override IDictionary<string,string> Serialize(object obj, JavaScriptSerializer serializer)
{
return SerializeObject(obj);
}
private IDictionary<string,string> SerializeObject(object obj)
{
IDictionary<string,string> values = new Dictionary<string,string>();
Type type = obj.GetType();
foreach (FieldInfo info in type.GetFields(BindingFlags.Public | BindingFlags.Instance))
if (!info.IsDefined(typeof(XmlIgnoreAttribute), true))
values.Add(SerializeName(info), SerializeValue(info.GetValue(obj), info));
foreach (PropertyInfo info2 in type.GetProperties(BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance))
{
if (!info2.IsDefined(typeof(XmlIgnoreAttribute), true))
{
MethodInfo getMethod = info2.GetGetMethod();
if ((getMethod != null) && (getMethod.GetParameters().Length <= 0))
values.Add(SerializeName(info2), SerializeValue(getMethod.Invoke(obj, null), info2));
}
}
return values;
}
private string SerializeName(MemberInfo member)
{
string name = null;
if (member.IsDefined(typeof(XmlElementAttribute), true))
{
object[] attrs = member.GetCustomAttributes(typeof(XmlElementAttribute), true);
if (attrs.Length > 0)
{
XmlElementAttribute attr = attrs[0] as XmlElementAttribute;
name = attr.ElementName;
}
}
if (member.IsDefined(typeof(XmlAttributeAttribute), true))
{
object[] attrs = member.GetCustomAttributes(typeof(XmlAttributeAttribute), true);
if (attrs.Length > 0)
{
XmlAttributeAttribute attr = attrs[0] as XmlAttributeAttribute;
name = attr.AttributeName;
}
}
if (member.IsDefined(typeof(XmlArrayAttribute), true))
{
object[] attrs = member.GetCustomAttributes(typeof(XmlArrayAttribute), true);
if (attrs.Length > 0)
{
XmlArrayAttribute attr = attrs[0] as XmlArrayAttribute;
name = attr.ElementName;
}
}
if (String.IsNullOrEmpty(name))
name = null;
return name ?? member.Name;
}
private object SerializeValue(object obj, MemberInfo member)
{
if (obj == null)
return obj;
// make sure the object isn’t an easily handled primity type
if (Type.GetTypeCode(obj.GetType()) != TypeCode.Object)
return obj;
if (obj is IDictionary)
return obj;
if (obj is ICollection)
{
IList<object> list = new List<object>();
object[] attrs = member.GetCustomAttributes(typeof(XmlArrayItemAttribute), true);
string arrayName = null;
if (attrs.Length > 0)
{
XmlArrayItemAttribute attr = attrs[0] as XmlArrayItemAttribute;
arrayName = attr.ElementName;
}
if (String.IsNullOrEmpty(arrayName))
{
foreach (object o in (obj as ICollection))
{
if (Type.GetTypeCode(o.GetType()) != TypeCode.Object)
list.Add(o);
else
list.Add(SerializeObject(o));
}
}
else
{
foreach (object o in (obj as ICollection))
{
IDictionary<string,object> list2 = new Dictionary<string,object>();
if (Type.GetTypeCode(o.GetType()) != TypeCode.Object)
list2.Add(arrayName, o);
else
list2.Add(arrayName, SerializeObject(o));
list.Add(list2);
}
}
return list;
}
return SerializeObject(obj);
}
public override IEnumerable<Type> SupportedTypes
{
get { return new ReadOnlyCollection<Type>(new List<Type>(new Type[] { typeof(T) })); }
}
}
}
Then to serialize the object in my code I have the following code in place.
JavaScriptSerializer jsSerializer = new JavaScriptSerializer();
jsSerializer.RegisterConverters(new List<JavaScriptConverter>(new JavaScriptConverter[] { new XmlJavaScriptConverter<T>() }));
string response = jsSerializer.Serialize(SerializableObject);
The serializer from above outputs the following code.
{"timestamp":"\/Date(1187968133328)\/","maxCount":10,"count":1,"terms":[{"term":"dvd hollywood"}]}
From this object as the reference.
[XmlRoot("search")]
public class GetTermsResponse
{
private string[] _terms;
private int _maxCount;
[XmlAttribute("timestamp")]
public DateTime TimeStamp
{
get { return DateTime.Now; }
set { ; }
}
[XmlAttribute("maxCount")]
public int MaxCount
{
get { return _maxCount; }
set { _maxCount = value; }
}
[XmlAttribute("count")]
public int Count
{
get { return Terms.Length; }
set { ; }
}
[XmlArray("terms")]
[XmlArrayItem("term")]
public string[] Terms
{
get { return _terms; }
set { _terms = value; }
}
}
So that wasn’t too hard the next step for this code is to make it so it can deserialize the JSON string back to an object, but the chances of that happening are almost 100/1 against the use of that functionality, because POST using JSON is a very dangerous activity and shouldn’t be attempted unless you know all the problems that may occur. So this code above should work in most real world examples. Happy coding.
Tags: ASP.NET, Framework 2.0, JavaScript, Web 2.0
Recently I have started seeing this number repeated over and over again on the net. You may be asking what it represents and why it is so important. Well this number is one of the worst kept secrets of the MPAA. This 32 character 16 bit number is the key used to descramble data on HD-DVD disc’s. I have seen it wrote many different ways:
09 F9 11 02 9D 74 E3 5B D8 41 56 C5 63 56 88 C0
09-F9-11-02-9D-74-E3-5B-D8-41-56-C5-63-56-88-C0
09:F9:11:02:9D:74:E3:5B:D8:41:56:C5:63:56:88:C0
09F911029D74E35BD84156C5635688C0
{09F91102-9D74-E35B-D841-56C5635688C0}
Many bloggers are afraid to even touch this number or publish the whole number, because of the MPAA and their crack team of lawyers. Coder Journal doesn’t bow to that kind of pressure, because we are here to support our readers and help them better understand the world of programming. More specifically understanding the difference between the almost 100% failure rate of security through obscurity. This encryption key is a failed attempt by the MPAA of security though obscurity, they might as well have just not encrypted the disk, because it only took the crackers days to find this key, and probably months for th MPAA to implement it.
The reason you are seeing this so prominently displayed, not just on my site, is because of the wide scale revolt at the social bookmarking site Digg. The revolt started Tuesday 5/2/2007, when the Digg moderators started deleting posts containing this sequence of numbers. Apparently as explained in this post, Digg is sponsored by the MPAA and HD-DVD, and started bowing to the pressure to keep this 16 bit number a “secret”. The consumerist has posted a time line of events.
1:30, Diggs started to take longer to register . The digg box on one post started showing 11 diggs, when the post really had 56.
1:40 Our post is the top blog post when searching for digg in technorati tags, resulting in our first noticeable traffic ever from technorati. good thing we got reinstated in the directory for the 3rd time or so recently.
1:43 Serious slowdown after digging posts…more than 30 seconds.
1:44 Digg pwns sel: “Digg will be down for a brief period, while we make some changes.”
1:45 Listening to the “Oh Nine, Eff Nine” song.
1:47 Digg still down.
1:48 It is going to take them a really long time to remove all the stories with the code in it. And then there’s all those pesky users to ban.
1:49 Still down.
1:51 They are never going to keep that number out. People will add it as comments just for no reason. Congrats, MPAA, you’ve created a powerful new meme!
1:52 Just noticed that Kevin Rose, Digg founder, posted something two hours ago about how they’re effectively going to tell the MPAA to shove the C&D. It uses the AACS code as a headline so you know he is for reals, or maybe it’s just Digg-bait to increase his AdSense revenue.
1:59 People say it’s up. But they also say it’s timing out and hanging. Still down for us.
2:03 Now everyone sees “We’ll be back shortly.”
2:05 We remember enjoying the headline that said, “BREAKING: DELL DUDE LANDS ON MOOn!” With the subheading “also 09-f9-11-02-9d-74-e3-5b-d8-41-56-c5-63.jpg.” Think it linked to a picture of Kevin Rose, a shovel, one of those terrorist creatures from Aqua Teen Hunger Force, and a graphical representation of the deadly number. Not quite the perfect Venn diagram of Digg user interests, but cut ‘em some slack, they’re working on the fly.
2:08 This is a phat rap about the number.
2:09 Fatigue, thoughts of this post’s pointlessness, begin to settle in.
2:12 Posting more screencaps taken shortly before the crash, inside.
2:16 People say it’s up!
2:17 Hasn’t propogated to us yet. Apparently the top story is Rose’s, “I will never take this down.”
2:19 It’s back for us. Looks like the same crazy pile of hex stories. It’s well past the tipping point of where people are just clicking on, and submitting all, the hex code stories they can.
2:20 Wonder if Digg will credit their advertisers for all the page refreshes.
2:21 Again, Rose: “”But now, after seeing hundreds of stories and reading thousands of comments, you ‘ve made it clear. You’d rather see Digg go down fighting than bow down to a bigger company. We hear you, and effective immediately we won’t delete stories or comments containing the code and will deal with whatever the consequences might be.”" Let’s see what kills Digg first, fighting the MPAA suit or no one wanting to read a site full of hex spam.
2:28 Submitted this post to Digg.
And Kevin Rose founder of Digg has the following to say about what happened yesterday, and that he is taking this revolt to heart:
Today was an insane day. And as the founder of Digg, I just wanted to post my thoughts…
In building and shaping the site I’ve always tried to stay as hands on as possible. We’ve always given site moderation (digging/burying) power to the community. Occasionally we step in to remove stories that violate our terms of use (eg. linking to pornography, illegal downloads, racial hate sites, etc.). So today was a difficult day for us. We had to decide whether to remove stories containing a single code based on a cease and desist declaration. We had to make a call, and in our desire to avoid a scenario where Digg would be interrupted or shut down, we decided to comply and remove the stories with the code.
But now, after seeing hundreds of stories and reading thousands of comments, you’ve made it clear. You’d rather see Digg go down fighting than bow down to a bigger company. We hear you, and effective immediately we won’t delete stories or comments containing the code and will deal with whatever the consequences might be.
If we lose, then what the hell, at least we died trying.
Digg on,
Kevin
So there you have it the Web 2.0 version of a million man march.