Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Browser app with bit.ly shortening for Windows Phone 7

DZone's Guide to

Browser app with bit.ly shortening for Windows Phone 7

· Mobile Zone
Free Resource

Discover how to focus on operators for Reactive Programming and how they are essential to react to data in your application.  Brought to you in partnership with Wakanda

The mobile version of Internet Explorer is not really extendable and this has its reasons – security, stability and general reliability. Therefore, developers don’t really have the “keys” to extending the built-in browser. However, there are many workarounds to this, including the possibility to develop your own browser app that is based on the same IE core, but with custom functionality.

This is done with the help of the WebBrowser control that is available in the default Toolbox. In this article, I am going to show how to create a browser application that incorporates bit.ly shortening and allows the end-user to share the link via email.

First of all, I created a simple Windows Phone 7 application and edited the contents of the main XAML file to represent a page with a WebBrowser control, a TextBox where the user will enter the URL and a Go button.

I also added the Application Bar (displayed at the bottom when the application is running), where I placed the Shorten button.

The overall XAML markup for the page looks like this:

<phone:PhoneApplicationPage
    x:Class="WindowsPhoneTest.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    FontFamily="{StaticResource PhoneFontFamilyNormal}"
    FontSize="{StaticResource PhoneFontSizeNormal}"
    Foreground="{StaticResource PhoneForegroundBrush}"
    SupportedOrientations="Portrait" Orientation="Portrait"
    mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="696"
    shell:SystemTray.IsVisible="True">
    
    <Grid x:Name="LayoutRoot" Background="Transparent">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <TextBlock Grid.Row="0" Height="30" Margin="10,10,420,10" Text="URL:"></TextBlock>
        <TextBox x:Name="urlBox" Grid.Row="0" Margin="50,0,100,0" Text="http://"></TextBox>
        <Button Grid.Row="0" Margin="360,0,0,0" Content="GO" Click="Button_Click"></Button>

        <phone:WebBrowser Grid.Row="1"   Name="webBrowser"  />
    </Grid>
    
    <phone:PhoneApplicationPage.ApplicationBar>
        <shell:ApplicationBar IsVisible="True">
            <shell:ApplicationBarIconButton x:Name="getBitLy" Click="getBitLy_Click" IconUri="/Images/bitly.png" Text="Shorten"></shell:ApplicationBarIconButton>
        </shell:ApplicationBar>
    </phone:PhoneApplicationPage.ApplicationBar>
</phone:PhoneApplicationPage>

The image I am referencing for the Application Bar button is a sample bit.ly logo – you can either download one or use any other image. It will be automatically framed in a circle and resized accordingly when you reference it as IconUri (given that it is present in your project).

The code part is a bit more complicated, but at the same time it is easily understandable.

For the Go button, the procedure is simple:

if (!string.IsNullOrEmpty(urlBox.Text.Trim()))
{
    if (Uri.IsWellFormedUriString(urlBox.Text, UriKind.Absolute))
    {
        webBrowser.Navigate(new Uri(urlBox.Text));
    }
    else
    {
        MessageBox.Show("Invalid URL string. Make sure you are using the www prefix.","Invalid URL",MessageBoxButton.OK);
    }
}
I am making sure that a correctly-formatted URL is entered before the navigation occurs.

When the user clicks on the Shorten button, you need to actually find out whether there is a URL to shorten. Since this functionality is directly tied to the WebBrowser control, you need to check whether there is a URL to which the WebBrowser control already navigated.

This is done inside the getBitLy_Click event handler:

if (webBrowser.Source != null)
{
    // The validation passed - there is a correct URI present
}
else
{
    // No valid URI - nothing to shorten
    MessageBox.Show("URL cannot be shortened.\nYou need to open a web page first.", "Shorten URL", MessageBoxButton.OK);
}

When the user decides to shorten an inexistent URL, he will be prompted with a popup message:

The actual shortening is done in two parts. The triggering part and the asynchronous part, that will obtain the server response. The triggering part looks like this:

enum Format
{
    XML,
    JSON,
    TXT
}

enum Domain
{
    BITLY,
    JMP
}

void ShortenUrl(string longURL,
    string username, string apiKey, Format format = Format.XML, Domain domain = Domain.BITLY)
{
    string _domain;

    // Build the domain string depending on the selected domain type
    if (domain == Domain.BITLY)
        _domain = "bit.ly";
    else
        _domain = "j.mp";

    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(
        string.Format(@"http://api.bit.ly/v3/shorten?login={0}&apiKey={1}&longUrl={2}&format={3}&domain={4}",
        username, apiKey, HttpUtility.UrlEncode(longURL), format.ToString().ToLower(), _domain));

    request.BeginGetResponse(new AsyncCallback(GetResponse), request);
}

There are two enums that define allowed domains and return formats. The API call is structured the way you see it passed to the request. Eventually, you will need a bit.ly API key for your application to perform the shortening, so make sure you have a bit.ly account (can be created at no cost).

As you see, the response is obtained through an AsyncCallback that is referencing the GetReponse method.

void GetResponse(IAsyncResult result)
{
    XDocument doc;
    HttpWebRequest request = (HttpWebRequest)result.AsyncState;
    HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(result);

    using (StreamReader reader = new StreamReader(response.GetResponseStream()))
    {
        doc = XDocument.Load(reader.BaseStream);
    }
    
    var x = from c in doc.Root.Element("data").Elements() where c.Name == "url"
            select c;

    XElement n = ((IEnumerable<XElement>)x).ElementAt(0);

    EmailComposeTask task = new EmailComposeTask();
    task.Subject = "Shortened Link";
    task.Body = n.Value;
    task.Show();
}

First of all, it reads the response and presents it in a form of XDocument (I selected XML as the return format) and then I read the URL element. Of course, you can add error handling here, since there is a slight chance one time the phone won’t be connected and it might cause an issue. But right now I am just showing the idea behind my method.

All you have to do now is create a request to the bit.ly API by calling ShortenUrl:

ShortenUrl(webBrowser.Source.AbsoluteUri, USER_NAME, API_KEY); 

Once the URL is obtained, it will be shared through the built-in email application. Although you cannot test it directly on the emulator, you are able to do this on an actual Windows Phone 7 device.

If you want to learn more about URL shortening via bit.ly in a .NET application, take a look at this article.

Learn how divergent branches can appear in your repository and how to better understand why they are called “branches".  Brought to you in partnership with Wakanda

Topics:

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}