Consuming URL Shortening Services – bit.ly

هذه المقالة متوفرة أيضا باللغة العربية، اقرأها هنا.

Read more about URL shortening services here.

Source- Elsheimy.Samples.ShortenSvcs.zip

Contents

Contents of this article:

  • Contents
  • Overview
  • Introduction
  • API
    • Overview
    • Function Explanation
    • Shortening Function
    • Expanding Function
    • Validation Function
    • Stats Function
    • Lookup Function
    • Info Function
    • Authentication Function
  • JSON Support
    • Sample
    • Where to go next

    Overview

    This is a very hot article that you can’t leave without checking it first. This article is talking about the most popular and powerful URL shortening service ever, bit.ly.

    Today, we are going to talk about bit.ly API, its functions, and how you can access them from your .NET application.

    Don’t forget to download the sample code at the end of the article.

    Let’s go!

    Introduction

    Today we are going to talk about the most popular yet most powerful URL shortening service ever in the web. Yes you guessed, it is bit.ly.

    Of course this service is well-known enough and we don’t need to describe it or talk about its features, so we’ll dig into the API immediately.

    API

    Overview

    There’re few things that you should keep in mind about bit.ly API:

    • REST API:

    The bit.ly API is a REST web service; means that it’s a collection of HTTP endpoints each accessed by a simple address filled with arguments the function (endpoint) requires the way you fill up query strings of a web page. Actually, you don’t need to care about REST web services or HTTP endpoints; you just need to know how to call those functions (simply, to access those addresses programmatically.)

    Yet, the current and only version of the API is version 3 and that can be accessed using the following address:

    http://api.bit.ly/v3/%5Bfunction_name%5D?%5Bargs%5D

    Simply, substitute function_name with the name of the function you need to call, and replace args with function arguments.

    Notice that you can try any function by just typing the address into the browser and navigating to the results.

    • Functions:

    The API provides you with lots of functions that satisfy your application needs. The following list contains the functions available:

    • Shorten:
      Used to shorten a long URL.
    • Expand:
      Used to expand the URL; to get the original long URL from the short one.
    • Validate:
      Used to validate a username and his API key.
    • Clicks:
      Used to retrieve stats (number of clicks) about the short URL specified.
    • Lookup:
      Used to check a long URL if exists in the database, i.e., if it has been shortened before.
    • Info:
      Used to retrieve information about the URL (e.g. the user created it, page title, etc.)
    • Authenticate:
      Used to check if a username and password are valid. Access restricted, more information available later at the end of this article.

    As you see, the API of bit.ly is the most sophisticated yet powerful API compared to the APIs of the other URL shortening services.

    • Input Arguments:

    Any URL passed to a function must be encoded first to eliminate the ‘#’, ‘?’, ‘=’ and other problematic characters in the URL. For encoding a URL, the function System.Net.Uri.EscapeUriString() is very sufficient.

    There’re three main required arguments that are used by all functions:

    • login:
      Username.
    • apiKey:
      The key used to authenticate the user access to the API.
    • format:
      The format (type) of returned data from functions.

    Those three are required by all functions and you cannot work without one of them.

    • Authentication:

    All functions require user authentication. The user can prove his identity using his login name (username) and his API key (not his password.) You can get your API key by accessing the page http://bit.ly/a/account (after logging on to your account) or directly from http://bit.ly/a/your_api_key.

    One of the hot features of the API is that it provides you a demo user that can be used in your API training, the information of that user is as follows:

    Username: bitlyapidemo

    API Key: R_0da49e0a9118ff35f52f629d2d71bf07

    You might face problems with this account like violation of rate limits and many other problems, and that because it’s used by many users in the same time. Therefore, it’s recommended that you use another account.

    • Supported Formats:

    The API supports two formats of its returned data, XML and JSON (the default.) Yes it supports plain text too, but it’s not supported by all functions. XML data is easily manipulated by XML, so we’ll concentrate on XML besides the plain text format of course.

    • Handling Errors:

    If the function failed and you have specified the format as Plain Text (txt) in the call, you get an exception thrown in your code. If the format was XML, you can check the returned data for whether the function succeeded or not.

    The XML data returned from functions must follow this schema:

    <?xml version="1.0" encoding="UTF-8"?>
    <response>
        <status_code />
        <status_txt />
        ...
    </response>

    Here we have status_code set to the value 200 if the function succeeded and to the error code if the function failed. The status_txt describes the status of the function, it’s set to ‘OK’ if the function succeeded and to the error description if the function failed.

    The rest of the XML data is defined based on the function.

    • Preferred Domain:

    You have the option to use one of two domains, http://bit.ly and http://j.mp (new,) both offer you the same functionality and the same flexibility, however, the first counts to 20 characters while the other counts to only 18. (The domain can be set in the shortening function in the argument domain.)

    Keep in mind that the code just after the domain name (e.g. bnPuEX of http://bit.ly/bnPuEX) is called Hash and it is exactly 6 characters (case-sensitive.)

    There’re two types of hash, each short URL has many hashes:

    • User Hash:
      That hash of the URL generated for a given user shortened the URL. That means that a long URL might have more than one user hash equals to the number of users shortened that URL. (More than one hash means more than one short URL.)
    • Global Hash:
      A hash that is shared by all users for the same short URL.

    Thus, a short URL has only one global hash, but it might have more than one user hash (for each user shortened the same long URL.)

    • Rate Limits:

    You cannot think about making thousands of function calls every hour, access to the API is limited for each user on an hourly base. Limits are very sufficient for your application, but it’s going not to be sufficient if you are willing to spam the service or to drop it!

    Function Explanation

    Now we are going to talk about each function and how you can call it.

    First, get your API key that will be used to authenticate your calls to the API. If you need to bother yourself and to clog your application use the demo API user bitlyapidemo that have the API key R_0da49e0a9118ff35f52f629d2d71bf07.

    Shortening Function

    The first function we are going to talk about today is the shortening function, shorten. This function has the following address http://api.bit.ly/v3/shorten (as you expected) and is used to shorten long URLs. Besides main arguments key, apiKey, and format, it takes two more:

    • longUrl:
      The long URL to be shortened.
    • domain:
      Optional. The preferred domain, bit.ly or j.mp.

    You can get hands on this function and try it simply by navigating to the results of the following URL:

    http://api.bit.ly/v3/shorten?login=bitlyapidemo&apiKey=R_0da49e0a9118ff35f52f629d2d71bf07 &format=txt&longUrl=http://JustLikeAMagic.com

    This call simply tries to shorten the URL http://JustLikeAMagic.com by using credentials of the demo API user (substitute the current information with your own.) The format is set to plain text.

    You can also use change the format to XML and get output like this:

    <?xml version="1.0" encoding="utf-8"?>
    <response>
        <status_code>200</status_code>
        <status_txt>OK</status_txt>
        <data>
            <url>http://bit.ly/bO9TgE</url>
            <hash>bO9TgE</hash>
            <global_hash>9gSDEU</global_hash>
            <long_url>http://JustLikeAMagic.com&lt/long_url>
            <new_hash>0</new_hash>
        </data>
    </response>

    Notice that the status code is 200 that means that everything went ‘OK’. Notice that we have 5 elements:

    • url:
      The long URL generated.
    • hash:
      The user hash string.
    • global_hash:
      The globally shared hash. Can be used to browse to the URL too, it would be counted in the global statistics but not in user’s.
    • long_url:
      The original URL.
    • new_hash:
      Equals to 1 if this is the first time that URL being shortened (using the bit.ly service of course,) or 0 otherwise.

    Now, let’s code! The following function accepts a long URL and user API credentials and tries to shorten the URL using our shortening function.

    Don’t forget to add using statements to namespaces System.IO, System.Net, and System.Xml to that code and to the other code demonstrated in this article.

    // C#
    
    string Shorten(string url, string login, string key, bool xml)
    {
        url = Uri.EscapeUriString(url);
        string reqUri =
            String.Format("http://api.bit.ly/v3/shorten?" +
            "login={0}&apiKey={1}&format={2}&longUrl={3}",
            login, key, xml ? "xml" : "txt", url);
    
        HttpWebRequest req = (HttpWebRequest)WebRequest.Create(reqUri);
        req.Timeout = 10000; // 10 seconds
    
        // if the function fails and format==txt throws an exception
        Stream stm = req.GetResponse().GetResponseStream();
    
        if (xml)
        {
            XmlDocument doc = new XmlDocument();
            doc.Load(stm);
    
            // error checking for xml
            if (doc["response"]["status_code"].InnerText != "200")
                throw new WebException(doc["response"]["status_txt"].InnerText);
    
            return doc["response"]["data"]["url"].InnerText;
        }
        else // Text
            using (StreamReader reader = new StreamReader(stm))
                return reader.ReadLine();
    }

    Take notice of the mechanism used to check for errors.

    Expanding Function

    The next function we have is the function that is used to expand a URL, i.e., to get the long URL from the short one. Obviously, this function is called expand and it accepts the short URL shortUrl besides the three main arguments.

    Likewise, calling this function generate a data based on the function format, txt, xml, or json. The following XML data is generated when the function is called while the format is set to xml:

    <?xml version="1.0" encoding="utf-8" ?>
    <response>
        <status_code>200</status_code>
        <status_txt>OK</status_txt>
        <data>
            <entry>
                <short_url>http://bit.ly/bnPuEX</short_url>
                <long_url>http://justlikeamagic.com</long_url>
                <user_hash>bnPuEX</user_hash>
                <global_hash>bdE96m</global_hash>
            </entry>
        </data>
    </response>

    Now you can see the two hashes, user_hash and global_hash, and the two lend the user to your page (although the access is counted differently.)

    Now, let’s code! The following function retrieves the long URL from the short one:

    // C#
    
    string Expand(string url, string login, string key, bool xml)
    {
        url = Uri.EscapeUriString(url);
        string reqUri =
            String.Format("http://api.bit.ly/v3/expand?" +
            "login={0}&apiKey={1}&format={2}&shortUrl={3}",
            login, key, xml ? "xml" : "txt", url);
    
        HttpWebRequest req = (HttpWebRequest)WebRequest.Create(reqUri);
        req.Timeout = 10000; // 10 seconds
    
        // if the function fails and format==txt throws an exception
        Stream stm = req.GetResponse().GetResponseStream();
    
        if (xml)
        {
            XmlDocument doc = new XmlDocument();
            doc.Load(stm);
    
            // error checking for xml
            if (doc["response"]["status_code"].InnerText != "200")
                throw new WebException(doc["response"]["status_txt"].InnerText);
    
            return doc["response"]["data"]["entry"]["long_url"].InnerText;
        }
        else // Text
            using (StreamReader reader = new StreamReader(stm))
                return reader.ReadLine();
    }

    Validation Function

    The function validate is used to check if another username and API key pair is valid. For this function to work, you should use valid API credentials to check for the other credentials if they are valid or not. Therefore, you are going to use two additional arguments for the additional credentials, x_login and x_apiKey.

    This function doesn’t support plain text format. If XML was used, the function returns data like the following:

    <?xml version="1.0" encoding="UTF-8"?>
    <response>
        <status_code>200</status_code>
        <status_txt>OK</status_txt>
        <data>
            <valid>0</valid>
        </data>
    </response>

    The valid element is set to 1 if the credentials were OK or 0 otherwise.

    And this is our C# function that validates user API credentials:

    // C#
    
    string Validate(string login, string key,
        string xLogin, string xKey, bool xml)
    {
        string reqUri =
            String.Format("http://api.bit.ly/v3/validate?" +
            "login={0}&apiKey={1}&x_login={4}&x_key={5}&format={2}" +
            login, key, xLogin, xKey, xml ? "xml" : "txt");
    
        HttpWebRequest req = (HttpWebRequest)WebRequest.Create(reqUri);
        req.Timeout = 10000; // 10 seconds
    
        // if the function fails and format==txt throws an exception
        Stream stm = req.GetResponse().GetResponseStream();
    
        if (xml)
        {
            XmlDocument doc = new XmlDocument();
            doc.Load(stm);
    
            // error checking for xml
            if (doc["response"]["status_code"].InnerText != "200")
                throw new WebException(doc["response"]["status_txt"].InnerText);
    
            return int.Parse(doc["response"]["data"]["valid"]) == 1 ? true : false;
        }
        else // Text
            using (StreamReader reader = new StreamReader(stm))
                return int.Parse(reader.ReadLine()) == 1 ? true : false;
    }

    Stats Function

    This function is used to get stats about the short URL; the stats are represented in two values, user clicks and global clicks. User clicks value is the number of access times made to that user link. Global clicks value is the number of access times made from all short URLs (from all users) refer to the same address (almost like user hashes and global hash.)

    The function only accepts the short URL, shortUrl, besides the three main arguments. The data returned from the function is almost like this (in XML):

    <?xml version="1.0" encoding="utf-8" ?>
    <response>
        <status_code>200</status_code>
        <data>
            <clicks>
                <short_url>http://bit.ly/bnPuEX</short_url>
                <global_hash>bdE96m</global_hash>
                <user_clicks>0</user_clicks>
                <user_hash>bnPuEX</user_hash>
                <global_clicks>0</global_clicks>
            </clicks>
        </data>
        <status_txt>OK</status_txt>
    </response>

    The following C# function is used to retrieve number of access times for the current user and for all users:

    // C#
    
    int GetClicks(string url, string login, string key, out int globalClicks)
    {
        url = Uri.EscapeUriString(url);
        string reqUri =
            String.Format("http://api.bit.ly/v3/clicks?" +
            "login={0}&apiKey={1}&shortUrl={2}&format=xml" +
            login, key, url);
    
        HttpWebRequest req = (HttpWebRequest)WebRequest.Create(reqUri);
        req.Timeout = 10000; // 10 seconds
    
        Stream stm = req.GetResponse().GetResponseStream();
    
        XmlDocument doc = new XmlDocument();
        doc.Load(stm);
    
        // error checking for xml
        if (doc["response"]["status_code"].InnerText != "200")
            throw new WebException(doc["response"]["status_txt"].InnerText);
    
        XmlElement el = doc["response"]["data"]["clicks"];
        globalClicks = int.Parse(el["global_clicks"].InnerText);
        return int.Parse(el["user_clicks"].InnerText);
    }

    Lookup Function

    This function is used with long URLs to check whether they have been shortened before, and if so, the function returns the short URLs.

    If the long URL was found in service database, XML data like this is returned:

    <?xml version="1.0" encoding="utf-8" ?>
    <response>
        <status_code>200</status_code>
        <status_txt>OK</status_txt>
        <data>
            <lookup>
                <url>http://JustLikeAMagic.com</url>
                <short_url>http://bit.ly/9gSDEU</short_url>
                <global_hash>9gSDEU</global_hash>
            </lookup>
        </data>
    </response>

    Otherwise, you get another form of XML data:

    <?xml version="1.0" encoding="utf-8" ?>
    <response>
        <status_code>200</status_code>
        <status_txt>OK</status_txt>
        <data>
            <lookup>
                <url>http://JustLikeAMagic.com/books</url>
                <error>NOT_FOUND</error>
            </lookup>
        </data>
    </response>

    The following C# function looks-up a URL and returns its short URL if found:

    // C#
    
    string Lookup(string url, string login, string key)
    {
        url = Uri.EscapeUriString(url);
        string reqUri =
            String.Format("http://api.bit.ly/v3/lookup?" +
            "login={0}&apiKey={1}&url={2}&format=xml" +
            login, key, url);
    
        HttpWebRequest req = (HttpWebRequest)WebRequest.Create(reqUri);
        req.Timeout = 10000; // 10 seconds
    
        Stream stm = req.GetResponse().GetResponseStream();
    
        XmlDocument doc = new XmlDocument();
        doc.Load(stm);
    
        // error checking for xml
        if (doc["response"]["status_code"].InnerText != "200")
            throw new WebException(doc["response"]["status_txt"].InnerText);
    
        if (doc["response"]["data"]["lookup"]["error"] == null)
            return null; // not found
    
        return doc["response"]["data"]["lookup"]["short_url"].InnerText;
    }

    Info Function

    The info function is used to retrieve information about the current short URL. This function returns XML data like the following:

    <?xml version="1.0" encoding="utf-8" ?>
    <response>
        <status_code>200</status_code>
        <status_txt>OK</status_txt>
        <data>
            <info>
                <short_url>http://bit.ly/bnPuEX</short_url>
                <global_hash>bdE96m</global_hash>
                <user_hash>bnPuEX</user_hash>
                <created_by>elsheimy</created_by>
                <title>Just Like a Magic</title>
            </info>
        </data>
    </response>

    Besides link hashes, it returns the name of user who created it and the page title.

    And this is our C# function that retrieves that information:

    // C# Code
    
    string GetInfo(string url, string login, string key, out string createdBy)
    {
        url = Uri.EscapeUriString(url);
        string reqUri =
            String.Format("http://api.bit.ly/v3/info?" +
            "login={0}&apiKey={1}&shortUrl={2}&format=xml" +
            login, key, url);
    
        HttpWebRequest req = (HttpWebRequest)WebRequest.Create(reqUri);
        req.Timeout = 10000; // 10 seconds
    
        Stream stm = req.GetResponse().GetResponseStream();
    
        XmlDocument doc = new XmlDocument();
        doc.Load(stm);
    
        // error checking for xml
        if (doc["response"]["status_code"].InnerText != "200")
            throw new WebException(doc["response"]["status_txt"].InnerText);
    
        XmlElement el = doc["response"]["data"]["info"];
        createdBy = el["created_by"].InnerText;
        return el["title"].InnerText;
    }

    Authentication Function

    This is the last function today, the authenticate function. This function is used to check whether a username and a password are valid. Although this function and the validation function work the same way, there’s a big difference. The validation function checks for API credentials, the username and the API key, while this function checks for login information, the username and the password. Another big difference is that this function is currently access-restricted and you cannot use it before asking for permission from api@bit.ly.

    This function accepts two addition parameters, the username x_login and the password x_password.

    This function is called in a very specific way. You add arguments in the body of your request. In addition, the request is made by the method POST.

    If the function succeeded you get the API key for that user. For example:

    <?xml version="1.0" encoding="UTF-8"?>
    <response>
        <status_code>200</status_code>
        <data>
            <authenticate>
                <username>bitlyapidemo</username>
                <successful>1</successful>
                <api_key>R_0da49e0a9118ff35f52f629d2d71bf07</api_key>
            </authenticate>
        </data>
        <status_txt>OK</status_txt>
    </response>

    Otherwise, the successful element is set to 0 and no other information is available:

    <?xml version="1.0" encoding="UTF-8"?>
    <response>
        <status_code>200</status_code>
        <data>
            <authenticate>
                <successful>0</successful>
            </authenticate>
        </data>
        <status_txt>OK</status_txt>
    </response>

    The next C# function tries to authenticate a given user and retrieve his API key (Notice how to set information in the body of the request):

    // C#
    
    string Authenticate(string login, string key, string xLogin, string xPassword)
    {
        string reqUri = "http://api.bit.ly/v3/authenticate";
        string body =
            string.Format("login={0}&apiKey={1}&x_login={2}" +
            "&x_password={3}&format=xml",
            login, key, xLogin,xPassword);
    
        HttpWebRequest req = (HttpWebRequest)WebRequest.Create(reqUri);
        req.Timeout = 10000;
        req.Method = "POST";
    
        StreamWriter writer = new StreamWriter(req.GetRequestStream());
        writer.WriteLine(body);
    
        Stream stm = req.GetResponse().GetResponseStream();
        XmlDocument doc = new XmlDocument();
        doc.Load(stm);
    
        // error checking for xml
        if (doc["response"]["status_code"].InnerText != "200")
            throw new WebException(doc["response"]["status_txt"].InnerText);
    
        XmlElement el = doc["response"]["data"]["authenticate"];
        if (el["successful"].InnerText == "1")
            return el["api_key"].InnerText;
        else
            return null;
    }

    JSON Support

    We have been talking about the API and its support for XML and plain text formats and we missed the third one (is also the default,) that is JSON (JavaScript Object Notation.) Although XML and plain-text are enough and sufficient for most applications, and they’re very easy too, there’re some times when you are forced to work with JSON (some web services support only JSON data.) At least for completeness’ sake, we need to know how to handle JSON data when we have it in our hands.

    Worth mentioning that JSON is not supported by versions before .NET 3.5.

    First thing to know about bit.ly API is that you can get JSON data out of a function by passing the value json to the format parameter. Other way is to omit the format parameter completely, that’s because JSON is the default format that will be used when the format parameter not specified.

    Let’s take the shortening function as an example. Try calling the shortening function specifying json in the format parameter or removing the parameter completely:

    http://api.bit.ly/v3/shorten?login=bitlyapidemo&apiKey=R_0da49e0a9118ff35f52f629d2d71bf07
    &format=json&longUrl=http://JustLikeAMagic.com

    When you call the previous function you get some results similar to those:

    {
        "status_code": 200, 
        "status_txt": "OK", 
        "data":
        {
            "long_url": "http://justlikeamagic.com",
            "url": "http://bit.ly/bnPuEX",
            "hash": "bnPuEX",
            "global_hash": "bdE96m",
            "new_hash": 0
        }
    }

    Can you notice the similarities between the structure of this JSON-formatted data and the XML-formatted data we have seen earlier? Actually, the structure is the same, there’s no difference except how data is formatted.

    Looking at this JSON snippet we can see that it’s just a structure contains a few members, every member has a name and value both separated by a colon (:) and each surrounded by double quotes, members are separated by commas (,), and the whole structure is surrounded by curly brackets. Worth mentioning that the data member is a compound data member, means that it defines some other members inside it.

    The first step in handling JSON data is to create .NET classes/structures from the JSON code keeping the same structure definitions and parameter names. For our example, we need to create the following classes:

    C#
    
        class ShortUrl
        {
            public int status_code;
            public string status_txt;
            public ShortUrlData data;
        }
    
        class ShortUrlData
        {
            public string long_url;
            public string url;
            public string hash;
            public string global_hash;
            public int new_hash;
        }

    Here comes the trick, the DataContractJsonSerializer class that’s available in the namespace System.Runtime.Serialization.Json which is available in System.Runtime.Serialization.dll for .NET 4.0 and in System.ServiceModel.Web.dll for .NET 3.5 (not available before version 3.5.)

    This class can be used in two ways: to serialize (i.e. generate JSON data from a structure) or to deserialize (i.e. return the data structure from JSON data) this data. To serialize some data you call any of the WriteXXX() functions (based on the data type,) to deserialize this data you call any of the ReadXXX() functions (based on the data type too.)

    After you add the right assembly to project references and import the namespace System.Runtime.Serialization.Json, you can now start coding:

    // C#
    
    ShortUrl Shorten(string url, string login, string key)
    {
        url = Uri.EscapeUriString(url);
        string reqUri =
            String.Format("http://api.bit.ly/v3/shorten?" +
            "login={0}&apiKey={1}&format={2}&longUrl={3}",
            login, key, "json", url);
    
        HttpWebRequest req = (HttpWebRequest)WebRequest.Create(reqUri);
        req.Timeout = 10000; // 10 seconds
    
        // if the function fails and format==txt throws an exception
        Stream stm = req.GetResponse().GetResponseStream();
    
        DataContractJsonSerializer con = 
            new DataContractJsonSerializer(typeof(ShortUrl));
        ShortUrl shortUrl = (ShortUrl)con.ReadObject(stm);
    
        return shortUrl;
    }

    Have fun with JSON!

    Sample

    Download the sample code here.

    Where to go next

    Read more about URL shortening services here.

    Consuming URL Shortening Services – Cligs

    هذه المقالة متوفرة أيضا باللغة العربية، اقرأها هنا.

    Read more about URL shortening services here.

    Source- Elsheimy.Samples.ShortenSvcs.zip

    Contents

    Contents of this article:

    • Contents
    • Overview
    • Introduction
    • Description
    • API
      • Shortening URLs
      • Expanding URLs
    • Where to go next

    Overview

    This is another article that talks about URL shortening services. Today we are going to talk about Cligs, one of the popular shortening services on the web.

    Be prepared!

    Introduction

    Today we are talking about another popular shortening service; it’s Cligs, one of the most popular shortening services that provide lots of premium features for FREE.

    Enough talking, let’s begin the discussion.

    In December 2009, Cligs acquired by Mister Wong (a very nice bookmarking service.)

    Description

    How Cligs can help you? Cligs gives you plenty of features, including the following:

    • Shortening URLs (registered and non-registered users):
      You get a short URL that’s no more than 20 characters (Tweetburner is 22 and is.gd is only 18) including the domain http://cli.gs.
    • URL Management (registered users only):
      It allows you to manage your short URLs, to edit them, and to remove them if you like.
    • Real-time Analytics (registered users only):
      How many clicked your link, and when.
    • URL Previewing (registered and non-registered users):
      Preview the URL before opening it. Protects you from spam and unwanted sites.

    API

    Cligs provides you a very nice API with many advantages. The first advantage that we want to talk about is its simplicity. The API is very simple; it has just two functions, one for shortening URLs, and the other for expanding short URLs (to expand a URL means to get the long URL from the short one.)

    Another advantage of this API is that it allows you to shorten the URLs whether you are a registered user or not. Of course a registered user need to get an API key in order to link the API calls to his accounts so he can manage the links generated by the API and to watch the analytics.

    Shortening URLs

    The first function is used for shortening URLs and it’s called, create. This function has the following address:

    http://cli.gs/api/v1/cligs/create?url={1}&title={2}&key={3}&appid={4}

    The API is still in version 1, that’s why you see ‘v1’ in the address. This function takes four parameters, only the first one is required, other parameters are used for authentication:

    1. url:
      Required. The URL to be shortened.
    2. title:
      Optional. For authenticated calls only. The name that would be displayed on the short URL in your control panel (used for managing your URLs.)
    3. key:
      Optional. If you are a registered user and you want to link the API calls to your account, you’ll need to enter your API key here.
    4. appid:
      Optional. If you have used an API key, then you have to provide your application name that used to generate this API call (help users know the source of the link.)

    So how can you use this function? If this is an anonymous call (i.e. no authentication details provided,) just call the function providing the long URL in its single required argument.

    If you need to link this call to a specific account, then you’ll need an API key, which the user can get by signing in to his Cligs account, choosing ‘My API Keys’, then clicking ‘Create New API Key’ (if he doesn’t have one you.) The last step generates an API key that’s no exactly 32 characters (see figure 1.)

    Figure 1 - Creating API Keys, Cligs

    After you get the API key, you can push it to the function along with your application name in the appid argument.

    What about the title argument? For registered users, they can access their clig list (see figure 2) and see the URLs they shortened and the titles they choose above each of the URLs.

    Figure 2 - My Cligs, Cligs

    Now, let’s code! The following function makes use of the Cligs API to shorten URLs. It accepts three arguments, the long URL, the API key, and the application name. If the API key is null (Nothing in VB.NET,) the call is made anonymously, otherwise, the API key and the application name are used.

    // C#
    
    string Shorten(string url, string key, string app)
    {
        url = Uri.EscapeUriString(url);
        string reqUri =
            String.Format(@"http://cli.gs/api/v1/cligs/create?url={0}", url);
        if (key != null)
            reqUri += "&key=" + key + "&appid=" + app;
    
        HttpWebRequest req = (HttpWebRequest)WebRequest.Create(reqUri);
        req.Timeout = 5000;
    
        try
        {
            using (System.IO.StreamReader reader =
                new System.IO.StreamReader(req.GetResponse().GetResponseStream()))
            {
                return reader.ReadLine();
            }
        }
        catch (WebException ex)
        {
            return ex.Message;
        }
    }
    ' VB.NET
    
    Function Shorten(ByVal url As String, _
                     ByVal key As String, ByVal app As String) As String
    
        url = Uri.EscapeUriString(url)
        Dim reqUri As String = _
            String.Format("http://cli.gs/api/v1/cligs/create?url={0}", url)
        If key Is Nothing Then
            reqUri &= "&key=" & key & "&appid=" & app
        End If
    
        Dim req As WebRequest = WebRequest.Create(reqUri)
        req.Timeout = 5000
    
        Try
            Dim reader As System.IO.StreamReader = _
                New System.IO.StreamReader(req.GetResponse().GetResponseStream())
    
            Dim retValue As String = reader.ReadLine()
            reader.Close()
    
            Return retValue
        Catch ex As WebException
            Return ex.Message
        End Try
    
    End Function

    Expanding URLs

    The other function we have today is the expand function that’s used to get the long URL from the short one (e.g. to expand the short URL http://cli.gs/p1hUnW to be http://JustLikeAMagic.com.) This function is very simple and it has the following address:

    http://cli.gs/api/v1/cligs/expand?clig={1}

    This function accepts only a single argument, that’s the clig (short URL) to be expanded. The clig can be specified using one of three ways:

    • The clig ID. e.g. p1hUnW.
    • The raw URL. e.g. http://cli.gs/p1hUnW.
    • The encoded URL. e.g. http%3A%2F%2Fcli.gs%2Fp1hUnW.

    You can read more about URL encoding here.

    Now it’s the time for code! The following function takes a clig and returns its original URL:

    // C#
    
    string Expand(string url)
    {
        url = Uri.EscapeUriString(url);
        string reqUri = String.Format(@"http://cli.gs/api/v1/cligs/expand?clig={0}", url);
    
        HttpWebRequest req = (HttpWebRequest)WebRequest.Create(reqUri);
        req.Timeout = 5000;
    
        try
        {
            using (System.IO.StreamReader reader =
                new System.IO.StreamReader(req.GetResponse().GetResponseStream()))
            {
                return reader.ReadLine();
            }
        }
        catch (WebException ex)
        {
            return ex.Message;
        }
    }
    ' VB.NET
    
    Function Expand(ByVal url As String) As String
    
        url = Uri.EscapeUriString(url)
        Dim reqUri As String = _
            String.Format("http://cli.gs/api/v1/cligs/expand?clig={0}", url)
    
        Dim req As WebRequest = WebRequest.Create(reqUri)
        req.Timeout = 5000
    
        Try
            Dim reader As System.IO.StreamReader = _
                New System.IO.StreamReader(req.GetResponse().GetResponseStream())
    
            Dim retValue As String = reader.ReadLine()
            reader.Close()
    
            Return retValue
        Catch ex As WebException
            Return ex.Message
        End Try
    
    End Function

    Where to go next

    Some other articles about URL shortening services are available here.

    Consuming URL Shortening Services – Tweetburner (twurl)

    هذه المقالة متوفرة أيضا باللغة العربية، اقرأها هنا.

    Read more about URL shortening services here.

    Source- Elsheimy.Samples.ShortenSvcs.zip

    Contents

    Contents of this article:

    • Contents
    • Overview
    • Introduction
    • Description
    • API
    • Where to go next

    Overview

    Just another article of the URL shortening services series.

    Today, we are going to talk about another hot and easy-to-use service, it’s Tweetburner. If you haven’t used it before, then it’s the time to.

    We’re going to discuss how to use Tweetburner first. After that, we’ll inspect its API and learn how to use it in your .NET application.

    Introduction

    Again, one of the most popular URL shortening services ever.

    Today is dedicated for Tweetburner (known as twurl,) one of the hot, simple, and easy-to-use shortening services that you can compare to is.gd.

    Description

    When you visit Tweetburner website (via http://tweetburner.com or http://twurl.nl,) you can see that it allows users to register to gain more functionalities (specifically, link analytics.) However, at the time of this writing, the account page is disabled for technical issues and nothing interesting would happen if you register there.

    One of the hot features of Tweetburner is that it allows you to post your links to twitter (you guessed) and friendfeed as soon as they’re shortened just click ‘Share this link’ before you leave the page.

    Figure 1 - Shortening a URL, Tweetburner

    Figure 2 - Sharing a URL, Tweetburner

    Unfortunately, you can’t benefit from this sharing feature programmatically, but of course, you can create your own routines.

    After shrinking your URL, you get a new short link about 22 characters long (18 in is.gd) prefixed with http://twurl.nl.

    API

    Actually, Tweetburner doesn’t help you with an API. Instead, it provides you with a simple web page (used for shortening URLs) that you can access it from your code and get your short URLs.

    Let’s try it! Browse to our key page, http://tweetburner.com/links, and push your long URL and click the shortening button.

    Figure 3 - Shortening Links API, Tweetburner

    So how you can access this page via your .NET application and fill in its single field? Let’s get the idea! If you check the API documentation page, you might find that you are required just to request information from that page, post it the required URL via a simple string included in the request body, link[url]={0} (where {0} is the long URL, and just wait for the response that would contain the short URL of course if the function succeed.

    Do you find that ‘link[url]={0}’ strange? Try this with me! Browse to our page, http://tweetburner.com/links, and save it as HTML in your PC (not required, just grab its HTML code.)

    Sure we are interested on this magical text box, so scroll down to its definition that looks like this:

    Notice that the text box is given the name ‘link[url]’, that’s why we push ‘link[url]={0}’ on the request body. Given that hot information, you can push any data to any web form, just get the information required.

    Now, let’s code! The next function browses to our page, http://tweetburner.com/links, pushes the long URL specified, and gets the short URL back from the server. (Remember to include the namespace System.Net for the code to work properly.)

    // C#
    
    string Short(string url)
    {
        url = Uri.EscapeUriString(url);
    
        HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://tweetburner.com/links");
        req.Timeout = 5000;
        req.Method = "POST";
        req.ContentType = "application/x-www-form-urlencoded";
    
        byte[] buffer = System.Text.Encoding.UTF8.GetBytes("link[url]=" + url);
        req.ContentLength = buffer.Length;
    
        System.IO.Stream ios = req.GetRequestStream();
        ios.Write(buffer, 0, buffer.Length);
    
        try
        {
    
            using (System.IO.StreamReader reader =
                new System.IO.StreamReader(req.GetResponse().GetResponseStream()))
            {
                return reader.ReadLine();
            }
        }
        catch (WebException ex)
        {
            return ex.Message;
        }
    }
    ' VB.NET
    
    Function Shorten(ByVal url As String) As String
        url = Uri.EscapeUriString(url)
    
        Dim req As HttpWebRequest = _
            CType(WebRequest.Create("http://tweetburner.com/links"), HttpWebRequest)
        req.Timeout = 5000
        req.Method = "POST"
        req.ContentType = "application/x-www-form-urlencoded"
    
        Dim buffer() As Byte = _
            System.Text.Encoding.UTF8.GetBytes("link[url]=" + url)
        req.ContentLength = buffer.Length
    
        Dim ios As System.IO.Stream = req.GetRequestStream()
        ios.Write(buffer, 0, buffer.Length)
    
        Try
            Dim reader As System.IO.StreamReader = _
                New System.IO.StreamReader(req.GetResponse().GetResponseStream())
    
            Dim retValue As String = reader.ReadLine()
    
            reader.Close()
    
            Return retValue
        Catch ex As WebException
            Return ex.Message
        End Try
    End Function

    Notice that we have specified the POST method because it’s required if you are going to change some data in the server. It’s worth mentioning too that we have set the content type to application/x-www-form-urlencoded because it’s required if you are going to push data to a web form (it’s usually perfect for all web forms except file-uploads.)

    In addition, we have included the input required in the request stream.

    What’s next

    Some other articles about URL shortening services are available here.

    Consuming URL Shortening Services – is.gd

    هذه المقالة متوفرة أيضا باللغة العربية، اقرأها هنا.

    Read more about URL Shortening Services here.

    Source- Elsheimy.Samples.ShortenSvcs.zip

    Contents

    Contents of this article:

    • Contents
    • Overview
    • Introduction
    • API
    • What’s next

    Overview

    Another article of our series that talks about accessing URL shortening services programmatically.

    This article is talking about is.gd shortening service, how you can use it, and how to access it via your C#/VB.NET application.

    Introduction

    is.gd is one of the most popular shortening services ever in the web because of its simple interface and its easy-to-use API.

    When you visit service website, http://is.gd, you can see that nothing easier from is.gd, just push your long URL into the text box and click the shortening button.

    API

    is.gd provides you a very simple easy-to-use API. This API contains only one function that’s used for shortening URLs. Another good thing is that this function doesn’t require any kind of authentication for users. Therefore, you need just to spam it with your long URL (as you did with the website.)

    This glorious function is called http://is.gd/api.php, it accepts only a single argument, longurl, which can be set to the long URL you need to shorten. When you call the function, it simply returns the shortened URL as plain text (no more overhead.)

    Now, let’s try this function. We’ll try to shorten the URL http://JustLikeAMagic.com with our function. First, connect the arguments, http://is.gd/api.php?longurl=http://JustLikeAMagic.com. Now copy this address and paste it into your favorite browser. If everything was OK, you should see the short URL after clicking €˜Go’ in the browser toolbar.

    Now, let’s do it in C# and VB.NET. Check the following function that tries to shorten long URLs via the id.gd API:

    // C#
    
    string Shorten(string url)
    {
        url = Uri.EscapeUriString(url);
        string reqUri = String.Format(@"http://is.gd/api.php?longurl={0}", url);
    
        HttpWebRequest req = (HttpWebRequest)WebRequest.Create(reqUri);
        req.Timeout = 5000;
    
        try
        {
            using (System.IO.StreamReader reader =
                new System.IO.StreamReader(req.GetResponse().GetResponseStream()))
            {
                return reader.ReadLine();
            }
        }
        catch (WebException ex)
        {
            return ex.Message;
        }
    }
    ' VB.NET
    
    Function Shorten(ByVal url As String) As String
    
        url = Uri.EscapeUriString(url)
        Dim reqUri As String = _
            String.Format("http://is.gd/api.php?longurl={0}", url)
        Dim req As WebRequest = WebRequest.Create(reqUri)
        req.Timeout = 5000
    
        Try
            Dim reader As System.IO.StreamReader = _
                New System.IO.StreamReader(req.GetResponse().GetResponseStream())
    
            Dim retValue As String = reader.ReadLine()
            reader.Dispose()
    
            Return retValue
        Catch ex As WebException
            Return ex.Message
        End Try
    
    End Function

    Notice that we have used the function System.Net.Uri.EscapeUriString() to eliminate unacceptable characters from the URL by encoding them.

    Notice too that we have included our code in a Try-Catch block so we can catch exceptions before they blow up our application.

    What’s next

    Consider reading other articles in this series here.

    Consuming URL Shortening Services – Introduction

    هذه المقالة متوفرة أيضا باللغة العربية، اقرأها هنا.

    Read more about URL shortening services here.

    Source- Elsheimy.Samples.ShortenSvcs.zip

    Contents

    Contents of this article:

    • Contents
    • Overview
    • Introduction
    • Accessing the API
    • Authentication
    • .NET Support
    • Encoding
    • Sample
    • Where to Go Next
    • Poll: What are your favorite URL shortening services?

    Overview

    This is the first article of our series that talks about accessing URL shortening services programmatically.

    Here we introduce new concepts like the REST API. We also have a brief discussion of URL shortening services APIs and how you can access them.

    In addition, we are going to talk about .NET support for the REST API and tools and techniques available that would help us during our journey through the API.

    A working example built using C# and WinForms is available at the end of this article.

    This article is the base for all other articles. Articles other than this discuss specific services and their APIs. We will make use of code and techniques discussed here throughout the rest of articles.

    Let’s go!

    Introduction

    URL shortening services are very popular these days since web addresses tend to be very long and very difficult to be exchanged via email or other micro-blogging services like Twitter.

    Today, there’re tenths of URL shortening services spread out all over the web. Most of them are listed in the following articles:

    In this series, we are going to talk about how to consume URL shortening services in your .NET application. In other words, we will discuss how to program URL shortening services; we mean how to access them programmatically. In addition, we will have a brief discussion of each service and its unique features.

    How we will go through this discussion? This is going to be a series of articles published regularly. Each article discusses a given shortening service from the following list (updated regularly, expect new services to be added):

    The preceding list may not be comprehensive, many other popular services exist. However, not all shortening services have APIs! The preceding list contains the shortening services we know that allow developers to consume their functionalities via an exposed API.

    Before we start with a specific service, let’s have a brief discussion of features of the API and how we can access them.

    Accessing the API

    Most APIs in the web are just REST (Representational State Transfer) web services. A REST web service is simply a collection of functions (HTTP endpoints) that can be used to retrieve data in a variety of formats (optional.)

    Given an endpoint (function) like http://ab.c/api/shrink, we could supply the required input arguments as query strings in the URL. For example, we could shorten the URL www.google.com using a call to the HTTP endpoint http://ab.c/api/shrink?url=www.google.com supplied with the required information. It is worth mentioning that every service has its own API functions and arguments. Although they all do the same thing (shortening the URL,) they differ in function and argument names.

    When you call a web function, you just end up with the results in the format used in that function (XML, Atom, JSON, etc.) The function could also return plain text! It’s all about the function documentation that you should check carefully before calling the function. In addition, the returned value from a function may also contain error details if the function didn’t success.

    Keep in mind that API calls are limited and you can’t just leave the shortening code in an end-less loop! Other limitations of specific APIs should be discussed later.

    Authentication

    Most URL shortening services allow users to consume the service without being registered, some of allow users to register, and others not. Many other services require users to be registered in order to use the service.

    Likewise, service APIs may or may not require user authentication. Some services give the user an API key that can be used in the authentication process. Other services require user to enter his login details in the API calls. Most use the API key approach.

    .NET Support

    Does .NET support the REST API? Sure! As long as REST web services are just collections of HTTP endpoints, we do not need to worry about accessing them from .NET since that the BCL offers us a bunch of classes (available in System.dll) that can help with HTTP requests and responses.

    In addition, we will rely heavily on classes of System.Xml.dll to handle the data returned from functions (we will make use of functions that support XML.)

    If we could write something in C# that calls our fake web function http://ab.c/api/shrink, we could end up with some code like this:

    // C#
    
    public void string Shorten(string url)
    {
        string reqUri = @"http://ab.c/api/shrink?url=" + url;
    
        WebRequest req = WebRequest.Create(reqUri);
        req.Timeout = 5000;
    
        XmlDocument doc = new XmlDocument();
        doc.Load(req.GetResponse().GetResponseStream());
    
        return HandleXml(doc);
    }
    ' VB.NET
    
    Function Shorten(ByVal url As String) As String
    
        Dim reqUri As String = "http://ab.c/api/shrink?url=" &amp; url
    
        Dim req As WebRequest = WebRequest.Create(reqUri)
        req.Timeout = 5000
    
        Dim doc As new XmlDocument()
        doc.Load(req.GetResponse().GetResponseStream())
    
        Return HandleXml(doc)
    
    End Function

    Encoding

    If the URL to shorten have special characters like ‘&’, ‘?’, ‘#’, or ‘ ‘, those characters should be handled first before the URL is sent to the shortening function.

    This special handling for URLs is usually called Percent-encoding or URL Encoding. This encoding replaces unsafe characters with their hexadecimal values preceded by percentage (‘%’) signs.

    There are many unsafe characters that should be percent-encoded including ‘$’, ‘+’, ‘&’, ‘:’, and ‘=’. A nice discussion of URL Encoding can be found in the article URL Encoding by Brian Wilson.

    Why unsafe characters are problematic? Consider the following example: we need to shorten the URL http://justlikeamagic.com/?s=twitter with our fake shortening service http://ab.c, we end up with a call to the function using the following address http://ab.c/api/shrink?url=http://justlikeamagic.com/?s=twitter. Now we have two ‘?’s!!!

    So how can we encode URLs? Simply use the EscapeUriString() function of System.Net.Uri class it would work well for us here. If you need a full-featured encoder; a procedure that would work for all and every situation, you will need to consider creating one yourself, or you can use this:

    // C#
    
    char[] _chars = new char[]
    {
         '%',
         '$' ,
         '&amp;',
         '+',
         ',',
         '/',
         ':',
         ';',
         '=',
         '?',
         '@',
         ' ',
         '"',
         '',
         '#',
         '{',
         '}',
         '|',
         '\',
         '^',
         '~',
         '[',
         ']',
         ''', };
    
    string EncodeUrl(string url)
    {
        for (int i = 0; i < _chars.GetUpperBound(0); i++)
            url = url.Replace(
                _chars[i].ToString(),
                string.Format("{0:X}", (int)_chars[i]));
    
        return url;
    }
    
    string DecodeUrl(string url)
    {
        for (int i = 0; i < _chars.GetUpperBound(0); i++)
            url = url.Replace(
                string.Format("{0:X}", (int)_chars[i]),
                _chars[i].ToString());
    
        return url;
    }

    ' VB.NET

    Private _chars() As String = _
    { _
    "%", _
    "$", _
    "&amp;", _
    "+", _
    ",", _
    "/", _
    ":", _
    ";", _
    "=", _
    "?", _
    "@", _
    " ", _
    "", _
    "”, _
    “#”, _
    “{“, _
    “}”, _
    “|”, _
    “”, _
    “^”, _
    “~”, _
    “[“, _
    “]”, _
    “‘”}

    Public Function EncodeUrl(ByVal url As String) As String
    For i As Integer = 0 To _chars.GetUpperBound(0) – 1
    url = url.Replace( _
    _chars(i).ToString(), _
    String.Format(“{0:X}”, CInt(_chars(i))))
    Next

    Return url
    End Function

    Public Function DecodeUrl(ByVal url As String) As String
    For i As Integer = 0 To _chars.GetUpperBound(0) – 1
    url = url.Replace( _
    String.Format(“{0:X}”, CInt(_chars(i))), _
    _chars(i))
    Next

    Return url
    End Function

    Sample

    Download the sample from here.

    Where to Go Next

    Now start with any shortening service you like (links are update regularly, new services will be available too):

    Or else, check our URL Shortening Services tag.

    Poll

    Setting Device Information in MCI

    هذه المقالة متوفرة أيضا باللغة العربية، اقرأها هنا.

    Interested in MCI multimedia processing? First check this article out if you didn’t:

    Creating a Sound Recorder in C and C#

    After we received your feedbacks and comments about th.e article, we decided to add a small appendix to the end of the article about setting information (volume, channel, sampling rate, etc.) to a MCI device (a Waveform device of course.)

    Like anything else in MCI, you can set device information using a MCI command (string/numeric), and this time it’s the MCI_SET command.

    This command is used to set information about a specific device. This command requires an input parameter of the MCI_SET_PARMS structure. However, that input parameter might have extended members for specific devices. Because we are concentrating of Waveform devices, so we are going to use the MCI_WAVE_SET_PARMS structure that contains the extended members for our device and is defined as following:

    typedef struct {
        DWORD_PTR dwCallback;
        DWORD     dwTimeFormat;
        DWORD     dwAudio;
        UINT      wInput;
        UINT      wOutput;
        WORD      wFormatTag;
        WORD      wReserved2;
        WORD      nChannels;
        WORD      wReserved3;
        DWORD     nSamplesPerSec;
        DWORD     nAvgBytesPerSec;
        WORD      nBlockAlign;
        WORD      wReserved4;
        WORD      wBitsPerSample;
        WORD      wReserved5;
    } MCI_WAVE_SET_PARMS;

    This structure contains all and every little piece of information that can be set to a device. I expect that you read the main article and you are already familiar with members like dwCallback (other members are self-explanatory) that we have talked about many times, and you are fine too with function calls and setting up input parameters, so I won’t get into the discussion of the structure or how you are going to use that command. However, if you need more help setting up the input parameters for the structure, you should take a brief look at the MCI_WAVE_SET_PARMS Structure documentation in the MSDN.

    As you know, the MCI_WAVE_SET_PARMS unmanaged structure can be marshaled in C# as following:

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct MCI_WAVE_SET_PARMS
    {
        public IntPtr dwCallback;
        public uint     dwTimeFormat;
        public uint     dwAudio;
        public uint      wInput;
        public uint      wOutput;
        public ushort      wFormatTag;
        public ushort      wReserved2;
        public ushort      nChannels;
        public ushort      wReserved3;
        public uint     nSamplesPerSec;
        public uint     nAvgBytesPerSec;
        public ushort      nBlockAlign;
        public ushort      wReserved4;
        public ushort      wBitsPerSample;
        public ushort      wReserved5;
    }

    Congratulations! You did set the device information! So how to get them back?

    This can be done through the MCI_STATUS (discussed earlier) by setting up the MCI_STATUS_ITEM flag and setting the query item to the required information you need to query about (like MCI_DGV_STATUS_VOLUME to query about volume.)

    More about the MCI_STATUS command can be found in the MSDN documentation.

    Serialization vs. Marshaling

    هذه المقالة متوفرة أيضا باللغة العربية، اقرأها هنا.

    Overview

    Are you somewhat confused between Serialization and Marshaling? This writing would break this confusion up, it would give you a basic understanding of the process of Serialization and the process of Marshaling, and how you can get the most out of each.

    Serialization

    Serialization is the process of converting a data structure or object into a sequence of bits so that it can be stored in a file, a memory buffer, or transmitted across a network connection to be “resurrected” later in the same or another computer environment. And this sequence of bits can be of any format the user chooses; however, they are usually formed as XML or binary.

    Serialization comes in many forms in .NET Framework, it can be observed in ADO.NET, Web services, WCF services, Remoting, and others.

    For example, calling the WriteXml() function of a DataSet serializes this DataSet into a XML file.

        ds.WriteXml("data.xml");

    And if we have such this structure:

        public struct User
        {
            public int id;
            public string name;
        }

    we can get the following results if we serialize a collection of that structure into XML:

    
    
        
            12
            Mark
        
        
            13
            Charles
        
        
            14
            John
        
    

    Serialization can be observed in Web and WCF services too. The request and parameter information for a function are serialized into XML, and when the function returns the response and the returned data too are serialized into XML. Actually, you don’t have to think about these XML data, CLR handles this for you.

    In the same vein, when it comes to Remoting, the sender and recipient must agree to the same form of XML data. That’s, when you send some data CLR serializes this data for you before it sends it to the target process. When the target process receives this XML data, it turns it back (deserializes it) to its original form to be able to handle it.

    Thus, the process of converting data structures and objects into series of bits is called Serialization. The reverse of this process, converting these bits back to the original data structures and objects, is called Deserialization.

    Therefore, the following ADO.NET line does deserializes the XML file:

        DataSet ds;
        ds.ReadXml("data.xml");

    And when your application receives response from the server or from another process, the CLR deserializes that XML data for you.

    So why XML is preferred over binary serialization? That’s because XML is text-based. Thus, it’s free to be transmitted from a process to another or via a network connection, and firewalls always allow it.

    Marshaling

    Marshaling is the process of converting managed data types to unmanaged data types. There’re big differences between the managed and unmanaged environments. One of those differences is that data types of one environment is not available (and not acceptable) in the other.

    For example, you can’t call a function like SetWindowText() -that sets the text of a given window- with a System.String because this function accepts LPCTSTR and not System.String. In addition, you can’t interpret (handle) the return type, BOOl, of the same function, that’s because your managed environment (or C# because of the context of this writing) doesn’t have a BOOL, however, it has a System.Boolean.

    To be able to interact with the other environment, you will need to not to change the type format, but to change its name.

    For example, a System.String is a series of characters, and a LPCTSTR is a series of characters too! Why not just changing the name of the data type and pass it to the other environment?

    Consider the following situation. You have a System.String that contains the value €œHello€:

    System.String str = "Hello";

    The same data can be represented in an array of System.Char too, like the following line:

    System.Char[] ch = str.ToCharArray();

    So, what is the difference between that System.String variable and that System.Char array? Nothing. Both contain the same data, and that data is laid-out the same way in both variables. That’s what Marshaling means.

    So what is the difference between Serialization and Marshaling?

    C# has a System.Int32, and Windows API has an INT, and both refer to a 32-bit signed integer (on 32-bit machines.) When you marshal the System.Int32 to INT, you just change its type name, you don’t change its contents, or lay it in another way (usually.) When you serialize a System.Int32, you convert it to another form (XML for instance,) so it’s completely changed.

    Summary

    Look, after I get back to Wikipedia documentation for Marshaling, I realized that my answer was so specific to C#!

    I mean that, Marshaling is a very general term used to describe transformations of memory. Theoretically, it’s more general than Serialization. In Python for instance, the terms Marshaling and Serialization are used interchangeably. There (in Python,) Marshaling = Serialization, and Serialization = Marshaling, there’s no difference. In computer methodology, there’s a silent difference between Marshaling and Serialization (check the Wikipedia definition.)

    So what is that System.MarshalByRefObject class? Why that name -specifically- was used? First, System.MarshalByRefObject class allows objects to be passed by reference rather than by value in applications that use Remoting.

    Personally, I like to say that Microsoft .NET Framework team’s name was very scientific when they have called that object “MarshalByRefObject” with respect to that silent difference between serialization and marshaling or maybe that name was derived from Python, dunno!

    After all, we should keep in mind that in .NET methodology, there’s a big difference between Serialization and Marshaling, Marshaling usually refers to the Interop Marshaling. In .NET Remoting, it refers to that serialization process.

    By the way, Marshalling is so named because it was first studied in 1962 by Edward Waite Marshall, then with the General Electric corporation.

    That’s all.

    Have a nice day!

    Microsoft Agent; Providing a Custom Popup Menu

    هذه المقالة متوفرة أيضا باللغة العربية، اقرأها هنا.

    A second honeymoon with Microsoft Agent. Do you remember our article Programming Microsoft Agent in WinForms and our sample application PartIt? After you have included your desired agent in your application, are you feeling bad with the default popup menu? If so, then you are in the right place (welcome :).)

    Enough talking, let’s get to work! First, prepare your code that loads the Microsoft Agent and brings it to the screen.

    After that, create your System.Windows.Forms.ContextMenuStrip and add your required items (well, including ‘Hide’ maybe) and finish the item event handlers.

    Now, let’s complete it. Get to the code that loads the agent character (e.g. calls the Characters.Load() method of the agent control object, AxAgentObjects.AxAgent) and just disable the AutoPopupMenu flag/property of the character object, AgentObjects.IAgentCtlCharacterEx. This flag/property determines whether to allow the default popup menu or not.

    For example, the following code disables this property:

        AxAgentObjects.AxAgent agentCtl;
        AgentObjects.IAgentCtlCharacterEx agentChar;
    
        // initializing 'agentCtl'
        // . . .
    
        agentCtl.Characters.Load("Merlin", "merlin.acs");
        agentChar = agentCtl.Characters.Character("Merlin");
        agentChar.AutoPopupMenu = false;

    Next comes the interesting point. When the character is clicked, the ClickEvent event of the agent control (AxAgent) fires. So the next step is to handle this event and to provide your code that brings up your custom context menu. Consider the following code:

    // agentCtl.ClickEvent += agent_ClickEvent;
    
    public void agentCtl_ClickEvent(object sender, AxAgentObjects._AgentEvents_ClickEvent e)
    {
        if (e.characterID == "Merlin")  // check for this if you have many characters
        {
            if (e.button == 2) // 1 = left, 2 = right
            {
                myContextMenu.Show(e.x, e.y);
            }
        }
    }

    Well done!

    Have a nice Sunday!

    9 Rules about Constructors, Destructors, and Finalizers

    هذه المقالة متوفرة أيضا باللغة العربية، اقرأها هنا.

    Overview

    First, this writing concentrates of and compares between three programming languages, C#, C++/CLI, and ISO/ANSI C++. It discusses 9 rules that every developer should keep in mind while working with constructors, destructors, and finalizers and class hierarchies:

    • Rule #1: Contrsuctors are called in descending order
    • Rule #2: In C# lexicology, a destructor and a finalizer refer to the same thing
    • Rule #3: Destructors are called in ascending order
    • Rule #4: Finalizers are a feature of GC-managed objects only
    • Rule #5: You cannot determine when finalizers would be called
    • Rule #6: C++/CLI differs between destructors and finalizers
    • Rule #7: In C++/CLI and classic C++, you can determine when destructors are called
    • Rule #8: In C++/CLI, destructors and finalizers are not called together
    • Rule #9: Beware of virtual functions in constructors

    Rule #1: Constructors are called in descending order

    Rule #1: Constructors are called in descending order; starting from the root class and stepping down through the tree to reach the last leaf object that you need to instantiate. Applies to C#, C++/CLI, and ANSI C++.

    Let’s consider a simple class hierarchy like this:

        class BaseClass
        {
            public BaseClass()
            {
                Console.WriteLine("ctor of BaseClass");
            }
        }
    
        class DerivedClass : BaseClass
        {
            public DerivedClass()
            {
                Console.WriteLine("ctor of DerivedClass");
            }
        }
    
        class ChildClass : DerivedClass
        {
            public ChildClass()
            {
                Console.WriteLine("ctor of ChildClass");
            }
        }

    ChildClass inherits from DerivedClass, and DerivedClass, in turn, inherits from BaseClass.

    When we create a new instance of ChildClass using a simple line like this:

        static void Main()
        {
            ChildClass cls = new ChildClass();
        }

    the code outputs the following results:

    ctor of BaseClass
    ctor of DerivedClass
    ctor of ChildClass

    Rule #2: In C# lexicology, a destructor and a finalizer refer to the same thing

    Rule #2: In C# lexicology, a destructor and a finalizer refer to the same thing; the function called before the object is fully-removed from the memory (i.e. GC-collected). Applies to C# only.

    Let’s consider the same class hierarchy but with destructors:

        class BaseClass
        {
            public ~BaseClass()
            {
                Console.WriteLine("dtor of BaseClass");
            }
        }
    
        class DerivedClass : BaseClass
        {
            public ~DerivedClass()
            {
                Console.WriteLine("dtor of DerivedClass");
            }
        }
    
        class ChildClass : DerivedClass
        {
            public ~ChildClass()
            {
                Console.WriteLine("dtor of ChildClass");
            }
        }

    When you define a class destructor with that C++-alike syntax (preceding the function name with a ~) the compiler actually replaces your destructor with an override of the virtual Object.Finalize() function. That is, before the object is removed (i.e. GC-collected) from the memory, the finalizer (i.e. destructor) is called first. This finalizer first executes your code. After that it calls the finalizer of the base type of your object. If we could decompile our assembly, we would see that our destructor in the ChildClass (so other classes) has been replaced with this function:

            protected virtual void Finalize()
            {
                try
                {
                    Console.WriteLine("dtor of ChildClass");
                }
                finally
                {
                    base.Finalize();
                }
            }

    Rule #3: Destructors are called in ascending order

    Rule #3: Destructors are called in ascending order, starting from the leaf object that you need to instantiate and moving up through the tree to reach the very first base class of your object. In reverse of constructors calling order. Applies to C#, C++/CLI, and ANSI C++.

    Now, instantiate your class:

        static void Main()
        {
            ChildClass cls = new ChildClass();
    
            // 'cls' is removed from memory here
        }

    the code should outputs the following results:

    dtor of ChildClass
    dtor of DerivedClass
    dtor of BaseClass

    Rule #4: Finalizers are a feature of GC-managed objects

    Rule #4: Finalizers are a feature of GC managed objects (i.e. managed classes). That’s because the finalizer is called only when the GC removes the object from the memory (i.e. frees memory associated with).

    Now, try to create a simple structure with a destructor:

        struct MyStruct
        {
            ~MyStruct()
            {
                Console.WriteLine("dtor of MyStruct");
            }
        }

    The code won’t compile. That’s because that GC doesn’t handle structures.

    Rule #5: You can’t determine when finalizers would be called

    That’s because you don’t know when the next garbage collection would occur, even if you performed a manual garbage collection (using System.GC.Collect() function) you won’t know exactly when memory would be released. In addition, GC always delay releasing of finalizable object, it puts them in a special GC queue called freachable (pronounced ef-reachable, F stands for Finalize) queue. Applies to C# and C++/CLI (.NET.)

    Rule #6: C++/CLI differs between destructors and finalizers

    Rule #6: C++/CLI differs between destructors and finalizers. That is, finalizers are called by GC, and destructors are called when you manually delete the object.

    Let’s consider the same example but in C++/CLI:

    ref class BaseClass
    {
    public:
    	BaseClass()
    	{
    		Console::WriteLine("ctor of BaseClass");
    	}
    
    	~BaseClass()
    	{
    		Console::WriteLine("dtor of BaseClass");
    		GC::ReRegisterForFinalize(this);
    	}
    };
    
    ref class DerivedClass : BaseClass
    {
    public:
    	DerivedClass()
    	{
    		Console::WriteLine("ctor of DerivedClass");
    	}
    
    	~DerivedClass()
    	{
    		Console::WriteLine("dtor of DerivedClass");
    		GC::ReRegisterForFinalize(this);
    	}
    };
    
    ref class ChildClass : DerivedClass
    {
    public:
    	ChildClass()
    	{
    		Console::WriteLine("ctor of ChildClass");
    	}
    
    	~ChildClass()
    	{
    		Console::WriteLine("dtor of ChildClass");
    		GC::ReRegisterForFinalize(this);
    	}
    };

    When we run the code:

    int main()
    {
    	ChildClass^ cls = gcnew ChildClass();
    }

    it outputs the following results:

    ctor of BaseClass
    ctor of DerivedClass
    ctor of ChildClass

    The destructors are not called. Why? Unlike C#, in C++/CLI there is a big difference between destructors and finalizers. As you know, the finalizer is called when the GC removes the object from the memory. Destructors, on the other hand, are called when you destroy the object yourself (e.g. use the delete keyword.)

    Now, try to change the test code to the following:

    int main()
    {
    	ChildClass^ cls = gcnew ChildClass();
    	delete cls;
    }

    Run the code. Now, destructors are called.

    Next, let’s add finalizers to our objects. The code should be like the following:

    ref class BaseClass
    {
    public:
    	BaseClass()
    	{
    		Console::WriteLine("ctor of BaseClass");
    	}
    
    	~BaseClass()
    	{
    		Console::WriteLine("dtor of BaseClass");
    		GC::ReRegisterForFinalize(this);
    	}
    	!BaseClass()
    	{
    		Console::WriteLine("finz of BaseClass");
    	}
    };
    
    ref class DerivedClass : BaseClass
    {
    public:
    	DerivedClass()
    	{
    		Console::WriteLine("ctor of DerivedClass");
    	}
    
    	~DerivedClass()
    	{
    		Console::WriteLine("dtor of DerivedClass");
    		GC::ReRegisterForFinalize(this);
    	}
    	!DerivedClass()
    	{
    		Console::WriteLine("finz of DerivedClass");
    	}
    };
    
    ref class ChildClass : DerivedClass
    {
    public:
    	ChildClass()
    	{
    		Console::WriteLine("ctor of ChildClass");
    	}
    
    	~ChildClass()
    	{
    		Console::WriteLine("dtor of ChildClass");
    		GC::ReRegisterForFinalize(this);
    	}
    	!ChildClass()
    	{
    		Console::WriteLine("finz of ChildClass");
    
    	}
    };

    As you see, the syntax of constructors, destructors, and finalizers are very similar.

    Now, let’s try the code:

    int main()
    {
    	ChildClass^ cls = gcnew ChildClass();
    }

    GC would call finalizers and the code would outputs the following:

    ctor of BaseClass
    ctor of DerivedClass
    ctor of ChildClass
    finz of ChildClass
    finz of DerivedClass
    finz of BaseClass

    Rule #7: In C++/CLI and C++, you can determine when destructors are called

    Now, try to destroy the object yourself:

    int main()
    {
    	ChildClass^ cls = gcnew ChildClass();
    	delete cls;
    }

    The delete statement calls object destructors and removes the object from memory.

    Or else, declare the object with stack-semantics:

    int main()
    {
    	ChildClass cls;
    }

    Now, destructors are called when the scope of the object ends.

    Rule #8: In C++/CLI, destructors and finalizers are not called together

    Rule #8: In C++/CLI, destructors and finalizers are not called together. Only destructors or finalizers are called. If you manually delete the object or you declare it with stack-semantics, destructors are called. If you leaved the object for GC to handle, finalizers are called.

    Now try to run the code. The code should outputs the following results:

    ctor of BaseClass
    ctor of DerivedClass
    ctor of ChildClass
    dtor of ChildClass
    dtor of DerivedClass
    dtor of BaseClass

    Rule #9: Beware of virtual functions in constructors

    Rule #9: Beware of virtual (overridable) functions in constructors. In .NET (C# and C++/CLI,) the overload of the most derived object (the object to be instantiated) is called. In traditional C++ (ISO/ANSI C++,) the overload of the current object constructed is called.

    Let’s update our C# example:

    class BaseClass
    {
        public BaseClass()
        {
            Foo();
        }
    
        public virtual void Foo()
        {
            Console.WriteLine("Foo() of BaseClass");
        }
    }
    
    class DerivedClass : BaseClass
    {
        public DerivedClass()
        {
        }
    
        public override void Foo()
        {
            Console.WriteLine("Foo() of DerivedClass");
        }
    }
    
    class ChildClass : DerivedClass
    {
        public ChildClass()
        {
        }
    
        public override void Foo()
        {
            Console.WriteLine("Foo() of ChildClass");
        }
    }

    When you execute the code:

        static void Main()
        {
            ChildClass cls = new ChildClass();
        }

    you would get the following results:

    Foo() of ChildClass

    The same code in C++/CLI:

    ref class BaseClass
    {
    public:
    	BaseClass()
    	{
    		Foo();
    	}
    
    	virtual void Foo()
    	{
    		Console::WriteLine("Foo() of BaseClass");
    	}
    };
    
    ref class DerivedClass : BaseClass
    {
    public:
    	DerivedClass()
    	{
    	}
    
    	virtual void Foo() override
    	{
    		Console::WriteLine("Foo() of DerivedClass");
    	}
    };
    
    ref class ChildClass : DerivedClass
    {
    public:
    	ChildClass()
    	{
    	}
    
    	virtual void Foo() override
    	{
    		Console::WriteLine("Foo() of ChildClass");
    	}
    };

    The code outputs the same results.

    But what if you need to call the virtual function of the BaseClass? Just change the code to the following:

    ref class BaseClass
    {
    public:
    	BaseClass()
    	{
    		BaseClass::Foo();
    	}
    
    	virtual void Foo()
    	{
    		Console::WriteLine("Foo() of BaseClass");
    	}
    };

    Now, the code outputs:

    Foo() of BaseClass

    Let’s consider the same example but in classic ISO/ANSI C++:

    class CBaseClass
    {
    public:
    	CBaseClass()
    	{
    		Foo();
    	}
    	virtual void Foo()
    	{
    		cout << "Foo() of CBaseClass" << endl;
    	}
    };
    
    class CDerivedClass : CBaseClass
    {
    public:
    	CDerivedClass()
    	{
    	}
    
    	virtual void Foo() override
    	{
    		cout << "Foo() of CDerivedClass" << endl;
    	}
    };
    
    class CChildClass : CDerivedClass
    {
    public:
    	CChildClass()
    	{
    	}
    
    	virtual void Foo() override
    	{
    		cout << "Foo() of CChildClass" << endl;
    	}
    };

    Now, run the code. It should outputs:

    Foo() of BaseClass

    In classic C++, the overload of the function of the class being constructed is called unlike C# and C++/CLI (.NET in general.)

    Video: What’s New in C# 2/3/4

    هذه المقالة متوفرة أيضا باللغة العربية، اقرأها هنا.

    Here’s the complete “What’s New in C#” webcast series of Bruce Kyle (ISV Architect Evangelist of Microsoft) from Channel 9 blog:

    What’s new in C# 2:

    We will try to update this list as soon as new items release.