Microsoft Most Valuable Professional

Chris Pietschmann

An MVP From Wisconsin

Simple JavaScript Object Reflection API (.NET Style)

I was thinking about how JavaScript JSON serializers go about serializing objects. But how does the serializer know about each of the objects properties? I figured JavaScript must have some method of object reflection (similar to .NET Reflection) and it does.

Here's a simple Reflection namespace that allows you to more easily reflect through an objects methods and properties:

if (typeof PietschSoft == "undefined") var PietschSoft = {};
if (typeof PietschSoft.Reflection == "undefined") PietschSoft.Reflection = {};

PietschSoft.Reflection.GetProperties = function(obj){
    var props = new Array();

    for (var s in obj)
    {
        if (typeof(obj[s]) != "function") {
            props[props.length] = s;
        }
    }

    return props;
};

PietschSoft.Reflection.GetMethods = function(obj){
    var methods = new Array();

    for (var s in obj)
    {
        if (typeof(obj[s]) == "function") {
            methods[methods.length] = s;
        }
    }

    return methods
};

And, here's some simple code using the above simple reflection api:

/// Define our Person Object
Person = function(){
this.FirstName = "";
this.LastName = "";
};
Person.prototype.TestFunction = function(){return "Test Function";};

// Define our instance of the Person object
var p = new Person();
p.FirstName = "Chris";
p.LastName = "Pietschmann";

/// Loop through the Objects Properties
var props = PietschSoft.Reflection.GetProperties(p);
for (var i in props)
{
    alert(props[i] + " : " + p[props[i]]);
}

/// Loop through the Objects Methods
var methods = PietschSoft.Reflection.GetMethods(p);
for (var i in methods)
{
    alert(methods[i] + " : " + p[methods[i]]);
}

Currently rated 3.0 by 8 people

  • Currently 3/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Categories: General
Posted by crpietschmann on Thursday, February 28, 2008 7:17 PM
Permalink | Comments (3) | Post RSSRSS comment feed


JavaScript ForEach Equivalent

One thing with the For Loop in JavaScript is it doesn't seem to be very well documented that you can use it to do an equivalent of a ForEach loop.

Here's a short example of doing the ForEach loop equivalent in JavaScript:

var names = ["Chris","Kate","Steve"];

for ( var i in names )
{
    alert( names[i] );
}

In the above code, the variable "i" is our iterator and by using the "in" keyword the "for" loop actually loops through all elements in the Array for us. Using this you no longer have to worry about the length of the array.

Currently rated 4.5 by 11 people

  • Currently 4.454545/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Categories: General
Posted by crpietschmann on Thursday, February 28, 2008 6:23 PM
Permalink | Comments (0) | Post RSSRSS comment feed


.NET 3.5: JSON Serialization using the DataContractJsonSerializer

In ASP.NET AJAX Extensions v1.0 for ASP.NET 2.0 there is the JavaScriptSerializer class that provides JSON serialization and deserialization functionality. However, in .NET 3.5 the JavaScriptSerializer has been marked obsolete. The new object to use for JSON serialization in .NET 3.5 is the DataContractJsonSerliaizer object. I'm still new to the DataContractJsonSerializer, but here's a summary of what I've learned so far...

Object to Serialize

Here's a simple Person object with First Name and Last Name properties.

public class Person
{
    public Person() { }
    public Person(string firstname, string lastname)
    {
        this.FirstName = firstname;
        this.LastName = lastname;
    }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

Now in order to serialize our object to JSON using the DataContractJsonSerializer we must either mark it with the Serializable attribute or the DataContract attribute. If we mark the class with the DataContract attribute, then we must mark each property we want serialized with the DataMember attribute.

/// Marked with the Serializable Attribute
[Serializable]
public class Person
{
    public Person() { }
    public Person(string firstname, string lastname)
    {
        this.FirstName = firstname;
        this.LastName = lastname;
    }
    public string FirstName { get; set; }
    public string LastName { get; set; }

}

/// Marked with the DataContact Attribute
[DataContract]
public class Person
{
    public Person() { }
    public Person(string firstname, string lastname)
    {
        this.FirstName = firstname;
        this.LastName = lastname;
    }

    [DataMember]
    public string FirstName { get; set; }

    [DataMember]
    public string LastName { get; set; }
}

[/code]

 

Serialization Code

Jere's the most basic code to serialize our object to JSON:

Person myPerson = new Person("Chris", "Pietschmann");

/// Serialize to JSON
System.Runtime.Serialization.Json.DataContractJsonSerializer serializer = new System.Runtime.Serialization.Json.DataContractJsonSerializer(myPerson.GetType());
MemoryStream ms = new MemoryStream();
serializer.WriteObject(ms, myPerson);
string json = Encoding.Default.GetString(ms.ToArray());

Our resulting JSON looks like this:

/// Result of Person class marked as Serializable
{"<FirstName>k__BackingField":"Chris","<LastName>k__BackingField":"Pietschmann"}


/// Result of Person class marked as DataContract with
/// each Property marked as DataMember

{"FirstName":"Chris","LastName":"Pietschmann"}

As you can see the first serialization with the class marked with the Serializable attribute isn't quite what we were expecting, but is still JSON. This serialization actually isn't compatible with the client-side JSON Serializer in ASP.NET AJAX.

As you can see the second serialization with the class marked with the DataContract attribute is exactly what we were expecting, and is the same JSON that the old JavaScriptSerializer object would have generated. This is the method of JSON serialization using the DataContractJsonSerializer that you'll need to do if you are going to pass the resulting JSON down to the client to be consumed with ASP.NET AJAX.

 

Deserialization Code

Here's the most basic code to deserialize our object from JSON:

Person myPerson = new Person();
MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(json));
System.Runtime.Serialization.Json.DataContractJsonSerializer serializer = new System.Runtime.Serialization.Json.DataContractJsonSerializer(myPerson.GetType());
myPerson = serializer.ReadObject(ms) as Person;
ms.Close();

 

Controlling the property names in the resulting JSON

When using the DataContract and DataMember attributes, you can tell the DataMember attribute the specific name you want that property to have within the JSON serialization by setting its "Name" named parameter.

Here's an example that will give the name of "First" to the "FirstName" property within the JSON serialization:

[DataMember(Name = "First")]
public string FirstName { get; set; }

The resulting JSON looks like this:

{"First":"Chris","LastName":"Pietschmann"}

 

Here's the code for some Helper methods using Generics to do all the dirty work for you

using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;

public class JSONHelper
{
    public static string Serialize<T>(T obj)
    {
        System.Runtime.Serialization.Json.DataContractJsonSerializer serializer = new System.Runtime.Serialization.Json.DataContractJsonSerializer(obj.GetType());
        MemoryStream ms = new MemoryStream();
        serializer.WriteObject(ms, obj);
        string retVal = Encoding.Default.GetString(ms.ToArray());
        return retVal;
    }

    public static T Deserialize<T>(string json)
    {
        T obj = Activator.CreateInstance<T>();
        MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(json));
        System.Runtime.Serialization.Json.DataContractJsonSerializer serializer = new System.Runtime.Serialization.Json.DataContractJsonSerializer(obj.GetType());
        obj = (T)serializer.ReadObject(ms);
        ms.Close();
        return obj;
    }
}

/// Our Person object to Serialize/Deserialize to JSON
[DataContract]
public class Person
{
    public Person() { }
    public Person(string firstname, string lastname)
    {
        this.FirstName = firstname;
        this.LastName = lastname;
    }

    [DataMember]
    public string FirstName { get; set; }

    [DataMember]
    public string LastName { get; set; }
}


/// Sample code using the above helper methods
/// to serialize and deserialize the Person object

Person myPerson = new Person("Chris", "Pietschmann");

// Serialize
string json = JSONHelper.Serialize<Person>(myPerson);

// Deserialize
myPerson = JSONHelper.Deserialize<Person>(json);

 

What Assembly References does my application need for this?

From the namespace that contains DataContractJsonSerializer you can probably tell that you need to add a reference to the System.Runtime.Serialization assembly. However, you also need to add a reference to the System.ServiceModel.Web assembly.

 

Currently rated 5.0 by 6 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Categories: asp.net
Posted by crpietschmann on Wednesday, February 27, 2008 6:15 PM
Permalink | Comments (9) | Post RSSRSS comment feed


.NET: Why aren't Private Abstract methods allowed?

Sometimes when creating base objects you want to create methods that are overridable by object that inherit the base object, but keep the methods from being public. However, the compiler throws an exceptions when you try to define a method as "Private Abstract".

Why doesn't the compiler like "Private Abstract" methods?

The reason for this is Private methods can not be overriden. So, essentially the Abstract is useless if the method is Private.

How can I create a "Private" method that's able to be overriden?

Simple, you just declare the method as "Protected Abstract". Protected defines that the method is only accessible from within the class that declared it, and from within any derived class.

Currently rated 1.0 by 2 people

  • Currently 1/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Categories: General
Posted by crpietschmann on Tuesday, February 26, 2008 10:08 PM
Permalink | Comments (2) | Post RSSRSS comment feed

JavaScript Function Tips and Tricks

First, What is a JavaScript Function? As defined by W3Schools.com a JavaScript Function is:

"A function is a reusable code-block that will be executed by an event, or when the function is called." - http://www.w3schools.com/js/js_functions.asp

You're probably thinking, "Well, Yeah. I knew that." But, how much do you really know about JavaScript Functions?

JavaScript Function uses you already know

Here's the most basic ways of using functions to get things done that most web developers are familiar with:

/// Function that performs an action 
function Test1()
{
    alert("Test1");
}

/// Function that accepts arguments and performs an action
function Test2(a, b)
{
    alert(a + b);
}

/// Function that returns returns a value
function Test3(a, b)
{
    return a + b;
}

Ok, but what else could there be?

Well, actually there are a couple more Function usages that most web developers aren't familiar with.

To test your knowledge of JavaScript Functions, take the following quiz:

1) Is it possible to write a JavaScript Function "in-line"?
2) Is it possible to overload a JavaScript Function?
3) Is it possible to call a JavaScript Function Asynchronously?

If you answered "Yes" to all three questions, then you're probably familiar with the tips listed in this article. If not, definitely read on.

In-Line JavaScript Functions

You can write JavaScript Function "in-line".

var myFunction = function(a, b){ return a + b; };

/// This actually does the exact same as the following:
function myFunction(a, b)
{
    return a + b;
}

You can also use "in-line" function to define custom functions for use within a specific context. This allows you to reference variables within the context that the "in-line" function was defined without having to actually pass them as arguments.

function AddNumbers(a, b)
{
    var add = function(){ return a + b; };

    return add();
}

JavaScript Function Overloading

If you're a .NET developer, then you're definitely used to overloading methods so you can pass in different combinations of arguments. Contrary to popular belief, JavaScript does support this. It's just in a different way.

The "arguments" variable within a Function is an Array that contains all the arguments that were passed in. You can use this to define your function "overloads".

function Test()
{
    /// Check how many arguments were passed in.
    alert("There were " + arguments.length + " argument(s) passed in.");
}

Here's an implementation of the above AddNumbers function that will add any number of values.

function AddNumbers()
{
    var r = 0;
    for(var i = 0; i < arguments.length; i++)
    {
        r += arguments[i];
    }
    return r;
}

You can also do some basic Type checking in JavaScript to overload your function for different object types.

function Test(a)
{
    /// Get the Type of the object passed in
    var t = typeof(a);

    /// Execute different code depending on the type passed in
    switch (t)
    {
        case "number":
            /// Number Type Overload Stuff Here
            break;
        case "string":
            /// StringType Overload Stuff Here
            break;
        case "boolean":
            /// Boolean Type Overload Stuff Here
            break;
        case "object":
            /// Object Type Overload Stuff Here
            break;
        default:
            alert("No overload exists for this object type: " + t);
    }

}

Calling JavaScript Function Asynchronously

One trick with JavaScript Functions is that you can essentially call them asynchronously by using Timeouts.

function AddNumbers(a, b)
{
    alert(a + b);
}

/// Call AddNumbers Asynchronously
window.setTimeout("AddNumbers(5, 10);", 1);

One thing to remember when executing functions asynchronously in JavaScript, is all other JavaScript execution in the page halts until a function call is completed. This is how all the current browsers execute JavaScript, and can cause real performance issues if you are trying to call too many things asynchronously at the same time. A long running function will actually "lock up" the browser for the user. The same is true for synchronous function calls too.

Another trick when calling function asynchronously is to pass in a callback function so your code can be notified when the function call is finished executing.

var asyncArguments = null;
var asyncCallback = null;

function AddNumbers(a, b, callback)
{
    // Save a reference to the arguments
    asyncArguments = arguments;

    // Save a reference to the callback function
    asyncCallback = callback;

    // Call Function Asynchronously
    window.setTimeout("AsynchronousAddNumbers();", 1);
}

function AsynchronousAddNumbers()
{
    // This is call asynchonously by AddNumbers, and then
    // calls the callback function when completed and passes
    // it the results.
    asyncCallback(asyncArguments[0] + asyncArguments[1]);
}

function AddNumbersCallback(result)
{
    // This gets called when AddNumbers is completed asynchronously
    alert(result);
}

/// TO USE:

/// Call AddNumbers to do our addition asynchronously
/// and pass it the callback function to call when done
AddNumbers(5, 10, AddNumbersCallback);

Conclusion

In this article we covered some tips and tricks of using JavaScript Functions. Using these tips, you'll be able to write functions that are more reusable and flexible.

If you have any additional tips, feel free to post them in the comments.

Currently rated 3.7 by 3 people

  • Currently 3.666667/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Categories: General
Posted by crpietschmann on Monday, February 25, 2008 5:45 PM
Permalink | Comments (3) | Post RSSRSS comment feed

The Purina Diet {Joke}

I don't know who originally wrote this, but I received it in an email the other day. I thought it funny enough to share.

When someone asks you a dumb question wouldn't you like to respond like this?.....

Yesterday I was buying a large bag of Purina dog chow for Athena the wonder dog at Wal-Mart and was about to check out. A woman behind me asked if I had a dog. What did she think I had, an elephant? So since I'm retired, with little to do, on impulse, I told her that no, I didn't have a dog, and that I was starting the Purina Diet again.

Although I probably shouldn't, because I'd ended up in the hospital last time, but that I'd lost 50 pounds before I awakened in an intensive care ward with tubes coming out of most of my orifices and IVs in both arms.

I told her that it was essentially a perfect diet and that the way that it works is to load your pants pockets with Purina nuggets and simply eat one or two every time you feel hungry and that the food is nutritionally complete so I was going to try it again. (I have to mention here that practically everyone in the line was by now enthralled with my story.)

Horrified , she asked if I ended up in intensive care because the dog food poisoned me. I told her no; I stepped off a curb to sniff an Irish Setter's ass and a car hit us both.

I thought the guy behind her was going to have a heart attack, he was laughing so hard!

WAL-MART won't let me shop there anymore.

Currently rated 5.0 by 1 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: ,
Categories: General
Posted by crpietschmann on Thursday, February 14, 2008 9:58 AM
Permalink | Comments (3) | Post RSSRSS comment feed

Search Keyword Highlighter BlogEngine.NET v1.3 Extension

In my previous blog, I used the se_hilite.js file from Scott Yang to hightlight the search keywords people used to search for my site when they are referred to my site via the search engines. This is functionality that I want to maintain, and I couldn't find an existing extension. So, I decided to write one. This is a really simple extension, and a neat feature to have.

Here it is...

SearchKeywordHighlighter.zip (2.55 kb)

Currently rated 5.0 by 1 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Categories: General
Posted by crpietschmann on Wednesday, February 13, 2008 6:36 PM
Permalink | Comments (2) | Post RSSRSS comment feed

I just finished migrating to BlogEngine.NET...

I just finished migrating my blog over to use BlogEngine.NET. The process was very painless. I only had to do two things: 1) write a sql script to import my posts/comments/tags from my old blog into BlogEngine, and 2) setup some redirect pages to redirect traffic to the new urls.

Now, I just need to find or create a better theme to use.

Currently rated 3.0 by 2 people

  • Currently 3/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:
Categories: General
Posted by crpietschmann on Tuesday, February 12, 2008 9:28 PM
Permalink | Comments (6) | Post RSSRSS comment feed

Virtual Earth: Draw a Circle Radius Around a Lat/Long Point

I get requests on how to draw radius' around points on the map. And, up until now, I never needed to do it myself, so I didn't have a code snippet to do it. I did a search and quickly found an example over at viavirtualearth on how to do it in an older version of Virtual Earth. Other than being coded for an older version of Virtual Earth (and incompatible with VE6); it's coded to only handle drawing a radius in Kilometers.

So, I decided to upgrade the code example to support VE6, and support both Miles and Kilometers. I'm also converted it to make use of the GeoCodeCalc.ToDegrees function that I originally posted in my "Calculate Distance of User-Drawn Polyline" post.

Download the Full Example Here

And, in case you don't feel like downloading the example code that uses it, here's the source to the method that calculates the points that make up the radius: 

[code:js]
/* *************************************************************************** */
/* Written Chris Pietschmann (http://pietschsoft.com) */
/* This code is dependant on the GeoCodeCalc class found here: */
/* http://pietschsoft.com/Blog/Post.aspx?PostID=1453 */
/* *************************************************************************** */
/* This mathimatical code is a modified version of the code originally posted */
/* at the following location: *//* http://viavirtualearth.com/Wiki/Draw+a+circle.ashx */
/* *************************************************************************** */
if (GeoCodeCalc == undefined)
    var GeoCodeCalc = {}

GeoCodeCalc.ToDegrees = function(radians){ return radians * 180 / Math.PI;};

function CreateCircle(loc, radius, units){
var earthRadius = parseFloat(units);
var lat = GeoCodeCalc.ToRadian(loc.Latitude); //radians
var lon = GeoCodeCalc.ToRadian(loc.Longitude); //radians
var d = parseFloat(radius) / earthRadius; // d = angular distance covered on earth&#39;s surface
var locs = new Array();
for (x = 0; x &lt;= 360; x++) {
var p2 = new VELatLong(0,0)
brng = GeoCodeCalc.ToRadian(x); //radians
var latRadians = Math.asin(Math.sin(lat) * Math.cos(d) + Math.cos(lat) * Math.sin(d) * Math.cos(brng));
var lngRadians = lon + Math.atan2(Math.sin(brng) * Math.sin(d) * Math.cos(lat), Math.cos(d) - Math.sin(lat) * Math.sin(latRadians));
locs.push(new VELatLong(GeoCodeCalc.ToDegrees(latRadians), GeoCodeCalc.ToDegrees(lngRadians)));
}
return new VEShape(VEShapeType.Polyline, locs);
}
[/code]

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted by crpietschmann on Saturday, February 09, 2008 2:58 AM
Permalink | Comments (0) | Post RSSRSS comment feed

Virtual Earth Plus ASP.NET AJAX Breaks In Safari!

Update 5/17/2008: This issue has since been fixed with the release of the Virtual Earth v6.1 release. There is still a small issue related to the CalendarExtender and Virtual Earth that only occurs in Safari. You can read more about it here.

 

I do alot of development with ASP.NET AJAX and Virtual Earth, and each of them work fine by themselves in Safari 3 on Windows. However, if you use them both on the same page, it will cause ASP.NET AJAX to break and stop working in Safari.

This issue comes up when you include the Virtual Earth API JavaScript file in the page. You don't even need to create an instance of VE on the page to cause the issue to occur.

I don't have a Mac, so keep in mind that I haven't tested this in Safari on the Mac. I've only verified this issue in Safari 3 on Windows.

Below is a code example using the CalendarExtender in the Ajax Control Toolkit to demonstrate the issue. If you run the following code, you will notice that when you click on the textbox in Safari, the calendar never pops up, and the JavaScript console will register a couple exceptions in the ASP.NET AJAX Extensions JavaScript code.

[code:html]
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="SafariTest.aspx.cs" Inherits="SafariTest" %>
<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="ajaxToolkit" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Untitled Page</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script type="text/javascript" src="http://dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6" mce_src="http://dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6"></script>
<script type="text/javascript"> var map = null; function GetMap() { map = new VEMap('myMap'); map.LoadMap(); } </script>
</head>
<body onload="GetMap();">
<form id="form1" runat="server">
<asp:ScriptManager runat="server" ID="ScriptManager1"></asp:ScriptManager>
<div>
<asp:TextBox runat="server" id="txtDate"></asp:TextBox>
<ajaxToolkit:CalendarExtender runat="server" ID="CalendarExtender1" TargetControlID="txtDate"></ajaxToolkit:CalendarExtender>
<br /><br />
<div id='myMap' style="position:relative; width:400px; height:400px;"></div>
</div>
</form>
</body>
</html>
[/code]

This is a real issue for me, since I can not add Safari support to my Web.Maps.VE product because of this issue. I know it's probably an issue with Safari, since everything works perfect in IE and Firefox, but I hope it gets fixed soon.

Currently rated 4.0 by 1 people

  • Currently 4/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted by crpietschmann on Thursday, February 07, 2008 12:51 AM
Permalink | Comments (1) | Post RSSRSS comment feed

About the author

I'm Chris Pietschmann, go to the About Me page to learn more about me.

Search

Sponsors

Web.Maps.VE - ASP.NET AJAX Virtual Earth Mapping Server Control

Recent comments

Disclaimer


This work is licensed under a Creative Commons Attribution 3.0 United States License, unless explicitly stated otherwise within the posted content.
© Copyright 2004 - 2008 Chris Pietschmann