Alessandro Del Sole's Blog

/* A programming space about Microsoft® .NET® */
posts - 143, comments - 0, trackbacks - 0

My Links

News

Your host

This is me! This space is about Microsoft® .NET® and Microsoft® Visual Basic development. Enjoy! :-)

These postings are provided 'AS IS' for entertainment purposes only with absolutely no warranty expressed or implied and confer no rights.

Microsoft MVP

My MVP Profile

I'm a VB!

Watch my interview in Seattle

My new book on VB 2012

Order my book about VB 2012 on Amazon My book "Visual Basic 2012 Unleashed" is available. Click the cover!

My new book on LightSwitch!

Visual Studio LightSwitch Unleashed My book "Visual Studio LightSwitch Unleashed" is available. Click the cover!

Your visits

campusMVP.NET - Tutored online training for Microsoft developers

Follow me on Twitter!

Messenger me!


CyberInstaller Beta Tester

Download CIS 2008!!

CodePlex download Download my open-source projects from CodePlex!

Search the blog



Article Categories

Archives

Post Categories

.NET Framework

Blogroll

Help Authoring

Microsoft & MSDN

Setup & Deployment

Visual Basic 2005/2008/2010

venerdì 20 gennaio 2012

Windows Phone: listing and playing videos from YouTube (Visual Basic)

I am building an'app for Windows Phone 7.5 where I needed to show a list of videos from a YouTube channel, listing videos inside a ListBox and then allowing users to play the selected video.

I never did this before, so I found an interesting article on Visual Studio Magazine that put me on the right direction and that I adapted to my needs (not least writing code in Visual Basic ).

The first thing you need to do is constructing the Web address of the feed containing the desired list of videos. There is a number of URIs according to what you want to query, such as channels or categories. In this post I'm going to show you how to query a channel, which is nothing but querying the list of videos uploaded by a specific YouTube user.

YouTube provides specific APIs to do so. The full YouTube developer guide is available here.

Imagine you want to list all videos from the channel of Queen, my favorite rock band. The feed to retrieve the list is the following:

http://gdata.youtube.com/feeds/api/users/queenofficial/uploads?orderby=updated

You can easily verify how it works by pasting the link inside your browser. How about using it in Windows Phone? First you need a DataTemplate for the ListBox. This DataTemplate is going to show the videos' thumbnail and description:

    <phone:PhoneApplicationPage.Resources>
        <DataTemplate x:Key="SearchResultsItemTemplate">
            <StackPanel Margin="0,0,0,30" Orientation="Horizontal">
                <Image Source="{Binding VideoImageUrl}" HorizontalAlignment="Left" Width="100"   
         Height="90" Stretch="UniformToFill" VerticalAlignment="Top"/>
                <TextBlock Text="{Binding Title}" VerticalAlignment="Top" Width="300"
         HorizontalAlignment="Left" Margin="10,0,0,0" TextWrapping="Wrap"/>
            </StackPanel>
        </DataTemplate>
    </phone:PhoneApplicationPage.Resources>

Then you need a ListBox, which is simple:

                <ListBox x:Name="ResultsList" 
                         
                         ItemTemplate="{StaticResource SearchResultsItemTemplate}" 
                         ItemsSource="{Binding}" SelectionChanged="VideoListSelectionChanged" />

As you can see the ListBox uses the previously defined template. Now there are three things to do. The first thing is defining a class that represents a video, in a simplified way:

Public Class YouTubeVideo
    Public Property Title As String
    Public Property VideoImageUrl As String
    Public Property VideoId As String
End Class

The second thing to do is implementing the load operation for the list of videos. The place where you will write the code depends on your app implementation, however this is what you will write:

Dim w As New WebClient
AddHandler w.DownloadStringCompleted, Sub(sender As Object, e As DownloadStringCompletedEventArgs)
Dim atomns = XNamespace.Get("http://www.w3.org/2005/Atom")
Dim medians = XNamespace.Get("http://search.yahoo.com/mrss/")
Dim xml = XElement.Parse(e.Result)
Dim videos = (From entry In xml.Descendants(atomns.GetName("entry"))
              Select New YouTubeVideo With {.VideoId = entry.Element(atomns.GetName("id")).Value,
              .VideoImageUrl = (From thumbnail In entry.Descendants(medians.GetName("thumbnail"))
              Where thumbnail.Attribute("height").Value = "90"
              Select thumbnail.Attribute("url").Value).FirstOrDefault(),
              .Title = entry.Element(atomns.GetName("content")).Value}).ToArray()
                                                        ResultsList.ItemsSource = videos
 
searchUri = "http://gdata.youtube.com/feeds/api/users/queenofficial/uploads?orderby=updated"
w.DownloadStringAsync(New Uri(searchUri))

We can use LINQ to XML to parse the content of the feed and create an instance of the YouTube class which is populated with values coming from the feed. I'm not using XML literals here because we are referring to a namespace which is different in the Descendants element.

The very last step is handling the SelectionChanged event on the ListBox:

    Private Sub VideoListSelectionChanged(sender As System.Object, e As System.Windows.Controls.SelectionChangedEventArgs)
        Dim video = CType(ResultsList.SelectedItem, YouTubeVideo)
        If video IsNot Nothing Then
            Dim parsed = video.VideoId.Split(CChar("/"))
            Dim id = parsed(parsed.Length - 1)
            Dim playbackUrl = "vnd.youtube:" + id
 
            Dim task As New WebBrowserTask With {.Uri = New Uri(playbackUrl)}
            task.Show()
        End If
    End Sub

Basically the selected item is converted into an instance of the YouTubeVideo class; properties of the instance are read and these are used to construct the video's URL which is then launched via the WebBrowserTask launcher.

At this point you should not be suprised that your application will try to launch the YouTube app, which is created from Microsoft and that is free. The particular video format requires such an app to be available. This implies that you will not be able to test the code on the Windows Phone Emulator, because this does not allow downloading apps from the MarketPlace. This definitely means that you will have to test the result on the physical device.

If you disregard this limitation, you will see how effective this technique is especially if you need to play videos that are not available in other formats.

Alessandro

posted @ lunedì 1 gennaio 0001 00:00 | Feedback (0) | Filed Under [ Visual Basic Silverlight/Windows Phone ]

Windows Phone: protecting confidential data (Visual Basic)

Protecting user's confidential information is so important and it becomes even more when developing apps for mobile devices.

When you create applications for Windows Phone you can still use existing skills related to the System.Security.Cryptography namespace of the .NET Framework, and one existing technique offers a simplified way to protect information via encryption.

There is a class called ProtectedData which exposes two shared methods, Protect and Unprotect. The first method receives a string and returns its content under the form of an encrypted array of byte. The second method receives the encrypted array and returns the original, unprotected string.

That said, let's see how to define a class that implements this technique:

Imports System.Security.Cryptography
Imports System.Text
 
Public Class CryptoService
 
    Public Shared Function EncryptString(data As String) As Byte()
        Dim PinByte = Encoding.UTF8.GetBytes(data)
 
        Dim ProtectedPinByte = ProtectedData.Protect(PinByte, Nothing)
        Return ProtectedPinByte
    End Function
 
    Public Shared Function DecryptData(data As Byte()) As String
        Dim unprotected = ProtectedData.Unprotect(data, Nothing)
        Return Encoding.UTF8.GetString(unprotected, 0, unprotected.Length)
    End Function
 
End Class

The first method called EncryptString first converts the string into an array of byte and then encrypts the latter via the ProtectedData.Protect method. As opposite, the second method called DecryptData first unprotects the information into an array of byte which is finally converted into the original string. Using this technique is strictly related to the isolated storage. The following code demonstrates how to encrypt and save a string:

        Dim store = System.IO.IsolatedStorage.IsolatedStorageFile.GetUserStoreForApplication
        Using protStream As New IsolatedStorageFileStream("myfile.bin", IO.FileMode.Create, store)             Dim data = "Confidential string, do not share"             Dim protectedData = CryptoService.EncryptString(data)             protStream.Write(protectedData, 0, protectedData.Length)         End Using

The following code demonstrates how to retrieve the previously encrypted string from a stream:

        Using protStream As New IsolatedStorageFileStream("myfile.bin", IO.FileMode.Open, store)
            Dim pinArray As Byte() = New Byte(CInt(protStream.Length - 1)) {}
            protStream.Read(pinArray, 0, pinArray.Length)
            Dim info = CryptoService.DecryptData(pinArray)
        End Using

You might want to consider using different techniques for additional protection, however this is very simple and efficient. Don't miss the official MSDN documentation about it.

Alessandro

posted @ lunedì 1 gennaio 0001 00:00 | Feedback (0) | Filed Under [ Visual Basic Silverlight/Windows Phone ]

Windows Phone: saving pictures from the Web to the Pictures hub (Visual Basic)

The development platform for Windows Phone offers a number of APIs to interact with the Pictures Hub, which is the place where pictures are stored.

A very frequently asked question is how to save pictures to the Hub, given their Web address. This first assumes you have permissions to do so . To accomplish this we first use the WebClient class to make an asynchronous download of the picture; next, we move the picture's content (which is an array of byte) into a file inside the isolated storage; finally, we move the picture to the Hub.

The quickest way to interact with the Pictures Hub is the MediaLibrary class (which is not limited to this), offered by the Microsoft.Xna.Framework assembly, so you first need to add a reference to it in your project. This assembly is specific to games developed with the XNA instrumentation but it works fine with apps as well.

The code that allows performing such an operation is not that difficult, it just requires some skills with streams. Here it is, with comments for better reading experience:

'The following Imports directives are required
'Imports System.Windows.Resources
'Imports System.IO
'Imports Microsoft.Xna.Framework.Media
'Imports System.IO.IsolatedStorage
 
Private Sub SavePictureToHub(webAddress As Uri, pictureName As String)
    Dim client As New WebClient()
    AddHandler client.OpenReadCompleted, Sub(sender As Object, e As OpenReadCompletedEventArgs)
                                             'Get the result of the download operation as a stream
                                             Dim resInfo As New StreamResourceInfo(e.Result, Nothing)
                                             Dim reader As New StreamReader(resInfo.Stream)
 
                                             'Get a reference to the isolated storage
                                             Dim store = IsolatedStorageFile.GetUserStoreForApplication
 
                                             'Read the downloaded stream
                                             Dim contents As Byte()
                                             Using bReader As New BinaryReader(reader.BaseStream)
                                                 contents = bReader.ReadBytes(CInt(reader.BaseStream.Length))
                                             End Using
 
                                             'Move the downloaded stream to a temp file into the isolated storage
                                             Using fStream As IsolatedStorage.IsolatedStorageFileStream = store.CreateFile(pictureName)
                                                 fStream.Write(contents, 0, contents.Length)
                                             End Using
 
                                             'Save the picture to the Pictures hub (Saved pictures)
                                             Using rStream As New IsolatedStorageFileStream(pictureName, FileMode.Open, store)
                                                 Dim ml As New MediaLibrary
                                                 ml.SavePicture(pictureName, rStream)
                                             End Using
 
                                             reader.Close()
 
                                             'Remove the temp file from the isolated storage
                                             store.DeleteFile(pictureName)
                                         End Sub
 
    client.OpenReadAsync(webAddress)
End Sub

I prefer using statement lambdas, anyway you could certainly encapsulate the lambda's code inside a separate delegate. One thing you must keep in mind (other than having permissions to download pictures) is that the MediaLibrary class saves pictures into the Saved Pictures album.

Alessandro

posted @ lunedì 1 gennaio 0001 00:00 | Feedback (0) | Filed Under [ Visual Basic Silverlight/Windows Phone ]

Entity Framework: solving the "New transaction is not allowed because there are other threads running in the session" exception

It is not unusual to perform a For..Each loop over an entity set based on the ADO.NET Entity Framework. Something like this:

For Each animal In MyModel.Animals

'Do something here...

Next

In the sample above the Animals entity set is of type ObjectSet(Of T), and of course T is a dummy Animal type. If you loop directly an ObjectSet(Of T) then the EF might return the following exception:

"New transaction is not allowed because there are other threads running in the session". In order to solve this problem you must avoid performing the loop directly against the ObjectSet, which also means using something like the AsQueryable or ToList extension methods:

For Each animal In MyModel.Animals.AsQueryable()

Next

In this way you will be able to execute your loop correctly avoiding the exception, and of course you might prefer writing a LINQ query instead of using the extension methods according to your context.

Alessandro

posted @ lunedì 1 gennaio 0001 00:00 | Feedback (0) | Filed Under [ Visual Basic ]

Powered by:
Powered By Subtext Powered By ASP.NET