Building a Web Site with ASP .NET 2.0 to Navigate Your Music Library

Published 31 October 06 10:40 AM | Coding4Fun 
  This article focuses on a common solution for managing shared music files. It is accomplished by keeping shared music files on a single computer and have other computers' media libraries point to, and stay current with, the files on that computer.

Difficulty: Intermediate
Time Required: 1-3 hours
Cost: Free
Software: Visual Studio Express Editions
Hardware:
Download: Download

     

    Introduction
    It's easy to assume that most people with computers have media libraries. As computers become cheaper, easier to network and easier to use, people are more likely to create home networks. Since servers aren't practical in a home setting, information is distributed amongst the computers in the network, which makes managing and finding formation difficult. This is probably most evident in music libraries.
    Most media players maintain a private database containing all of the songs they're aware of. Keeping these databases up-to-date can be a chore on a single computer, and keeping databases current on several computers often seems impossible.
    A common solution is to keep all music files on a single computer and have other computers' media libraries point to, and stay current with, the files on that computer. Anyone that has tried this in practice knows that it's an adequate solution, but not an ideal one. Personally, I just want to listen to music, not manage it.
    My home setup consists of a Windows Media Center computer that drives my TV and has all of my music on it, my workstation, and occasionally a laptop. Keeping the workstation current with the music on the Media Center has always been a hassle, and doing so on the laptop just isn't practical. I wanted a simple, clean way to listen to music anywhere in my apartment, from any computer, without having to worry about the accuracy of the library. I chose to build a little website whose only purpose would be to get me to the music I wanted to listen to as painlessly as possible. I used Microsoft Visual Web Developer 2005 Express Edition Beta 2 to make this happen.
    COM: A friend from the past
    Back in the old days we had a technology called COM that let us use libraries written in any language from our code, regardless of the langauge we were using (as long as it supported COM), much like .NET does today. COM did a great job solving some problems, but introduced a few others that became more apparent over time. .NET is, among other things, a solution to many of these problems.
    Years ago, Microsoft started exposing operating system and application services via COM. This let common folk write code against Microsoft Word, Windows Scripting Host, Windows Media Player, and countless others. Due to the number of languages, frameworks, etc. that support COM, it's still a major player in the Microsoft world and it's common to find COM support in Microsoft applications before .NET support. Luckily, .NET does a great job talking to COM (most of the time).
    This history lesson is relevant because the site uses the Windows Media Player COM component to access its media library. Adding a reference to a COM component is just as easy as adding a reference to a .NET assembly. Click the Website menu and select Add Reference, then click the COM tab on the Add Reference dialog.

    Figure 1: Adding a reference to the Windows Media Player COM component

    Database
    Quick access to a subset of the WMP library's information is required, so an in-memory database consisting of Artist, Album, Database and Track classes is required. The Database class has a static (or shared in Visual Basic) constructor that populates the database with a call to the Refresh method:

    Visual C#

    private static void Refresh()
        {
            WindowsMediaPlayer wmp = new WindowsMediaPlayer();
            IWMPPlaylist playlist = wmp.mediaCollection.getAll();
            Dictionary<string, Artist> artistDictionary = 
    new Dictionary<string, Artist>();
    
            for (int i = 0; i < playlist.count; i++)
            {
                IWMPMedia media = (IWMPMedia)playlist.get_Item(i);
                string albumArtistName = media.getItemInfo("AlbumArtist");
                string albumName = media.getItemInfo("Album");
                string trackName = media.getItemInfo("Title");
                string trackLocation = media.getItemInfo("SourceUrl");
                string trackNumberString = media.getItemInfo("OriginalIndex");
    
                Artist artist;
                string artistSortName = Artist.GetSortName(albumArtistName);
    
                if (!artistDictionary.TryGetValue(artistSortName, out artist))
                {
                    artist = new Artist(albumArtistName);
                    artistDictionary.Add(artistSortName, artist);
                }
    
                Album album;
    
                if (!artist.Albums.TryGetValue(albumName, out album))
                {
                    album = new Album(albumName, artist);
                    artist.Albums.Add(albumName, album);
                }
    
                Track track;
    
                if (!album.Tracks.TryGetValue(trackName, out track))
                {
                    int trackNumber;
    
                    if (int.TryParse(trackNumberString, out trackNumber))
                    {
                        track = new Track(trackNumber, trackName, trackLocation);
                    }
                    else
                    {
                        track = new Track(trackName, trackLocation);
                    }
    
                    track.Album = album;
                    album.Tracks.Add(trackName, track);
                }
            }
    
            ArtistList.AddRange(artistDictionary.Values);
            ArtistList.Sort();
        }

    Visual Basic  

    Private Shared Sub Refresh()
            Dim wmp As WindowsMediaPlayer = New WindowsMediaPlayer
            Dim playlist As IWMPPlaylist = wmp.mediaCollection.getAll()
            Dim artistDictionary As Dictionary(Of String, Artist) = _
    New Dictionary(Of String, Artist)
    
            For i As Integer = 0 To playlist.count - 1
                Dim media As IWMPMedia = playlist.Item(i)
                Dim albumArtistName As String = media.getItemInfo("AlbumArtist")
                Dim albumName As String = media.getItemInfo("Album")
                Dim trackName As String = media.getItemInfo("Title")
                Dim trackLocation As String = media.getItemInfo("SourceUrl")
                Dim trackNumberString As String = _
                    media.getItemInfo("OriginalIndex")
    
                Dim theArtist As Artist
                Dim artistSortName As String = _
                    Artist.GetSortName(albumArtistName)
    
    If Not artistDictionary.TryGetValue(artistSortName, theArtist) Then
                    theArtist = New Artist(albumArtistName)
                    artistDictionary.Add(artistSortName, theArtist)
                End If
    
                Dim theAlbum As Album
    
                If Not theArtist.Albums.TryGetValue(albumName, theAlbum) Then
                    theAlbum = New Album(albumName, theArtist)
                    theArtist.Albums.Add(albumName, theAlbum)
                End If
    
                Dim theTrack As Track
    
                If Not theAlbum.Tracks.TryGetValue(trackName, theTrack) Then
                    Dim trackNumber As Integer
    
                    If Integer.TryParse(trackNumberString, trackNumber) Then
                        theTrack = New Track(trackNumber, trackName, trackLocation)
                    Else
                        theTrack = New Track(trackName, trackLocation)
                    End If
    
                    theTrack.Album = theAlbum
                    theAlbum.Tracks.Add(trackName, theTrack)
                End If
            Next
    
            ArtistList.AddRange(artistDictionary.Values)
            ArtistList.Sort()
        End Sub

    The WMP library is a flat structure of media items, so the Artist -> Albums -> Tracks hierarchy must be created manually while populating the database. Accessing the WMP library is simple; calling the getAll method off of a WindowsMediaPlayer object's mediaCollection property returns a playlist of all items in the library, represented by the IWMPPlaylist interface. Collecting the information needed from each media item (represented by the IWMPMedia interface) is just as easy, via a call to IWMPMedia's getItemInfo method. Once all of the relevant information for the media item is collected, the artist, album and track objects must be retrieved or created.
    Note that I've used a generic Dictionary object to store the artists while we're iterating through the playlist. Some media collections consist of tens of thousands of items, and having to do a brute-force search through the ArtistList for every media item would further slow down an already slow operation. (Why the Dictionary object is quicker is beyond the scope of this article. Please see Scott Mitchell's examination of the Hashtable class, Dictionary's non-generic counterpart, in an article from his fantastic series on data structures.)
    Designing the website
    To keep things as simple as possible, we'll make three pages: Artists, Artist's Albums, and Album.

    Figure 2: The Artists page

    The Artists page (Figure 2) shows ten groups of artists at a time. Each time a group is clicked, that group is shown and so on until the user gets to the artist she's looking for.

    Figure 3: The Albums page

    The Albums page (Figure 3) shows all of the albums, including artwork, for an artist. Clicking the album name brings the user to the Album page, and clicking the play button will launch a playlist containing the tracks in the album in Windows Media Player.

    Figure 4: The Album page

    The Album page shows the large album artwork and tracks. The user can play the entire album or individual tracks.
    Each page uses object data binding and shares a common master page. ASP.NET has a new feature called Master Pages, which allows you to create a consistent layout for the Web site and share common functionality without having to duplicate it for every page. The Master Page in this website is used to share Cascading Style Sheet (CSS) information and host the "breadcrumb bar," or SiteMapPath, as it's called in ASP.NET. I won't be covering the SiteMapPath control, but the implementation should be interesting to anyone that needs to drive one programmatically and not through a static definition. More information about master pages can be found in Fritz Onion's Master Your Site Design with Visual Inheritance and Page Templates.
    The Albums and Album page also have images and play buttons that launch Windows Media Player playlist files. Album images are cached in a Web-accessible directory, and WMP playlist files are generated on the fly in an HTTP handler. Both of these topics are covered below.
    Binding objects to grids
    The new ObjectDataSource is the middleman between the grid and objects. It must be configured to work with a class to return data requested by the grid. We'll step through creating the data source for the Albums page.

    Figure 5: The ObjectDataSource wizard, first page

    The "Binder" class is selected as the business object. The objects used to represent the artists, et al, are simple and primarily represent data, and therefore don't have much in the way of persistence methods. The Binder class provides the functionality that may otherwise be handled by the objects themselves.

    Figure 6: The ObjectDataSource wizard, second page

    The next page is where we choose which method we would like to use to get the data, so we pick GetAlbums. Update, Insert and Delete methods can also be specified, but are not required.

    Figure 7: The ObjectDataSource wizard, third page

    The final page specifies where the parameter values will come from. The value can come from one of the following: Cookie, Control, Form, Profile, QueryString and Session.
    Once the data source is configured, setting it as the DataSource of the grid is all that's required to make the magic happen.
    Generating custom grid values
    All of the grids use template columns and custom code to generate their hyperlinks. For example, the artists page (figure 2) consists of a single GridView that's bound to a generic List of RangeListItems. RangeListItem is a custom class that represents the first and last artist IDs in the range, as well as the text that is displayed in the grid. The hyperlinks are created by using a template field in the grid and calling a method in the page's server-side script section.

    <asp:TemplateField ItemStyle-HorizontalAlign=Center>
        <ItemTemplate>
            <asp:HyperLink ID="HyperLink1" runat="server" NavigateURL='<%# CreateNavigateURL(GetDataItem() %>'
                Text='<%# Eval("Text") %>'></asp:HyperLink>
        </ItemTemplate>
    </asp:TemplateField>
    The NavigateUrl attribute is populated by a call to the CreateNavigateUrl method:

    Visual C#

    private string CreateNavigateUrl(object o)
        {
            RangeListItem listItem = (RangeListItem)o;
    
            if (listItem.StartIndex == listItem.EndIndex)
            {
                return "albums.aspx?artist=" + listItem.StartIndex;
            }
            else
            {
    return string.Format("default.aspx?start={0}&end={1}", listItem.StartIndex, listItem.EndIndex);
            }
        }
    

    Visual Basic

    Private Function CreateNavigateUrl(ByVal o As Object) As String
            Dim listItem As RangeListItem = CType(o, RangeListItem)
            
            If (listItem.StartIndex = listItem.EndIndex) Then
                Return "albums.aspx?artist=" & listItem.StartIndex
            Else
                Return String.Format("default.aspx?start={0}&end={1}", listItem.StartIndex, listItem.EndIndex)
            End If
    End Function
    
    More information about templates in ASP.NET 2.0 can be found in Dino Esposito's Move Over DataGrid, There's a New Grid in Town!.
    Displaying Album Art

    Windows Media Player downloads album art, both large and small versions, when possible. These image files are stored in the same folders as the album tracks, but are hidden by default. These images must be copied to a child folder of the Web site so the browser can access them. This is done by first finding the correct image, then copying that file to a subfolder of the Web site and giving it a unique name to so it can be more easily retrieved the next time it's required. If album art isn't found, a small transparent image is used instead.

    Visual C#

    public string GetAlbumArtUrl(AlbumArtSize size)
        {
            string albumArtFileName = GetCustomAlbumArtFileName(size);
    string albumArtFullFilename = Path.Combine(_albumArtDirectory, 
        albumArtFileName);
    
            bool fileExists = File.Exists(albumArtFullFilename);
    
            if (!fileExists)
            {
                string dir = Path.GetDirectoryName(Tracks[0].Location);
                string filename;
    
                if (Directory.Exists(dir))
                {
                    filename = GetRealAlbumArtFileName(dir, size);
    
                    if (filename != null)
                    {
                        File.Copy(filename, albumArtFullFilename);
                        File.SetAttributes(albumArtFullFilename, 
                            FileAttributes.Normal);
                        fileExists = true;
                    }
                }
            }
    
            string url;
    
            if (fileExists)
            {
                url = "Images/AlbumArt/" + albumArtFileName;
            }
            else
            {
                url = "Images/dot.gif";
            }
    
            return url;
        }
    
    

    Visual Basic   

    Public Function GetAlbumArtUrl(ByVal size As AlbumArtSize) As String
            Dim albumArtFileName As String = GetCustomAlbumArtFileName(size)
            Dim albumArtFullFilename As String = _
                Path.Combine(_albumArtDirectory, albumArtFileName)
    
            Dim fileExists As Boolean = File.Exists(albumArtFullFilename)
    
            If Not fileExists Then
                Dim dir As String = Path.GetDirectoryName(Tracks(0).Location)
                Dim filename As String
    
                If Directory.Exists(dir) Then
                    filename = GetRealAlbumArtFileName(dir, size)
    
                    If Not filename Is Nothing Then
                        File.Copy(filename, albumArtFullFilename)
                        File.SetAttributes(albumArtFullFilename, _
                            FileAttributes.Normal)
                        fileExists = True
                    End If
                End If
            End If
    
            Dim url As String
    
            If fileExists Then
                url = "Images/AlbumArt/" & albumArtFileName
            Else
                url = "Images/dot.gif"
            End If
    
            Return url
        End Function

    The GetCustomAlbumArtFileName method creates a consistent name that is used to save the copy of the image and more easily retrieve it in subsequent requests:

    Visual C#   

    private string GetCustomAlbumArtFileName(AlbumArtSize size)
        {
            return string.Format("{0}-{1}-{2}.jpg", 
                GetAlphanumericString(_artist.Name), 
                GetAlphanumericString(Name),
                size.ToString());
        }
    
        private string GetAlphanumericString(string s)
        {
            StringBuilder sb = new StringBuilder();
    
            foreach (char c in s)
            {
                if (char.IsLetterOrDigit(c))
                {
                    sb.Append(c);
                }
            }
    
            return sb.ToString();
        }
    

    Visual Basic  

     Private Function GetCustomAlbumArtFileName(ByVal size As AlbumArtSize) As String
            Return String.Format("{0}-{1}-{2}.jpg", _
                GetAlphanumericString(_artist.Name), _
    GetAlphanumericString(Name), size.ToString)
        End Function
    
        Private Function GetAlphanumericString(ByVal s As String) As String
            Dim sb As StringBuilder = New StringBuilder
    
            For Each c As Char In s
                If Char.IsLetterOrDigit(c) Then
                    sb.Append(c)
                End If
            Next
    
            Return sb.ToString()
        End Function
    
    To make things even more interesting, album art filenames can match any of the following patterns:

    Large
    AlbumArt_{FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF}_Large.jpg

    AlbumArt__Large.jpg

    Folder.jpg

    Small
    AlbumArt_{FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF}_Small.jpg

    AlbumArt__Small.jpg

    AlbumArtSmall.jpg

    GetRealAlbumArtFileName gets the filename for the album art, if it exists, by searching for the patterns above:

    Visual C#   

    private string GetRealAlbumArtFileName(string dir, AlbumArtSize size)
        {
            string filename = null;
            string[] filenames = 
    Directory.GetFiles(dir, "AlbumArt*" + size + ".jpg");
    
            if (filenames.Length > 0)
            {
                filename = filenames[0];
            }
            else if (size == AlbumArtSize.Large)
            {
                FileInfo file = new FileInfo(Path.Combine(dir, "Folder.jpg"));
                
                if (file.Exists)
                {
                    filename = file.FullName;
                }
            }
            return filename;
        }
    

    Visual Basic

    Private Function GetRealAlbumArtFileName(ByVal dir As String, ByVal size As AlbumArtSize) As String
            Dim filename As String = Nothing
            Dim filenames() As String = _
    Directory.GetFiles(dir, "AlbumArt*" & size.ToString() & ".jpg")
    
            If (filenames.Length > 0) Then
                filename = filenames(0)
            ElseIf (size = AlbumArtSize.Large) Then
                Dim file As FileInfo = _
    New FileInfo(Path.Combine(dir, "Folder.jpg"))
                If file.Exists Then
                    filename = file.FullName
                End If
            End If
    
            Return filename
        End Function

    Creating a Playlist

    Playlists are created by the PlaylistCreator class, which is a lightweight web request handler that implements the IHttpHandler interface. The handler is quite simple: It writes out a header, notifying the browser that the type of content it will be returning is "video/x-ms-asf", then creates and returns an XML playlist. The content type header helps the browser determine what to do with the content, and is a very important step since we want to play the playlist, not show it in the browser.
    PlaylistCreator writes directly to the response stream with an XmlTextWriter:

    Visual C#   

    public void ProcessRequest(HttpContext context)
        {
            _trackIndex = QueryStringHelper.TrackIndex;
            _artistIndex = QueryStringHelper.ArtistIndex;
            _albumIndex = QueryStringHelper.AlbumIndex;
    
            context.Response.ContentType = "video/x-ms-asf";
    
            StreamWriter streamWriter = 
    new StreamWriter(context.Response.OutputStream);
            _writer = new XmlTextWriter(streamWriter);
            _writer.WriteProcessingInstruction("wpl", "version=\"1.0\"");
    
            _writer.WriteStartElement("smil");
    
            CreateHead();
            
            _writer.WriteStartElement("body");
            _writer.WriteStartElement("seq");
    
            if (_trackIndex.HasValue)
            {
                CreateTrackEntry();
            }
            else if (_albumIndex.HasValue)
            {
                CreateAlbumEntries();
            }
    
            _writer.WriteEndElement();
            _writer.WriteEndElement();
            _writer.WriteEndElement();
    
            _writer.Close();
        }
    

    Visual Basic   

    Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
            _trackIndex = QueryStringHelper.TrackIndex
            _artistIndex = QueryStringHelper.ArtistIndex
            _albumIndex = QueryStringHelper.AlbumIndex
    
            context.Response.ContentType = "video/x-ms-asf"
    
            Dim streamWriter As StreamWriter = _
    New StreamWriter(context.Response.OutputStream)
            _writer = New XmlTextWriter(streamWriter)
            _writer.WriteProcessingInstruction("wpl", "version=\""1.0\""")
    
            _writer.WriteStartElement("smil")
    
            CreateHead()
    
            _writer.WriteStartElement("body")
            _writer.WriteStartElement("seq")
    
            If _trackIndex.HasValue Then
                CreateTrackEntry()
            ElseIf _albumIndex.HasValue Then
                CreateAlbumEntries()
            End If
    
            _writer.WriteEndElement()
            _writer.WriteEndElement()
            _writer.WriteEndElement()
    
            _writer.Close()
        End Sub

    Registering the Playlist Creator
    ASP.NET knows how to handle requests to ASPX pages: it finds the page with the same name and executes it. HTTP handlers are handled a bit differently. An entry must be made in the web.config file associating a file name or pattern with the type of the object to use to handle the request. The XML fragment below is from the configuration/system.web section of the web.config file. It's instructing ASP.NET to direct any request with an extention of "wpl" to an object of type "PlaylistCreator". 
    <httpHandlers>
    
    
    
              <add path="*.wpl" type="PlaylistCreator" verb="*" validate="false" />
    </httpHandlers>
    
    	

    Comment Notification

    If you would like to receive an email when updates are made to this post, please register here

    Subscribe to this post's comments using RSS

    Comments

    # iandra said on May 21, 2007 8:48 AM:

    you gave me an inspiration for another things that involve music

    # Dan Ribar said on June 19, 2007 1:16 PM:

    Have you had luck actually playing the mp3 if stored in the db?   We are storing the mp3 in a SQL server and can try to listen to it -- but it won't work on the fly.  have to save it to disk first which makes the end user do double the work.

    any ideas?

    Dan Ribar

    dribar@yahoo.com

    # Ram Rangarajan said on June 29, 2007 6:37 PM:

    Good information. Very clean.

    Hop you also have information on playing, uploading video files too

    # mouna said on July 9, 2007 11:45 AM:

    comment fusionner asp.net avec media player

    # Javier said on August 17, 2007 10:56 AM:

    Just wanted to thank you for the instructional project. Just recently dove into ASP .NET 2.0 for work, and loving it. Not to mention I'm a weekend DJ and my "purchased" music  collection is well over 1,000 CD's, now on my server for my home network. This will be a fun project. THANKS!

    # yaniv said on August 22, 2007 5:08 PM:

    where can i get some info about this cassini web server

    and some detailed Instructions about using it , like where

    what and so on....

    # Web 2.0 » Blog Archives » BNET Intercom Video: Web 2.0 and Your Business on BNET said on August 31, 2007 2:07 AM:

    PingBack from http://chaespot.com/web2.0/2007/08/31/bnet-intercom-video-web-20-and-your-business-on-bnet/

    # Dave Johnson said on September 10, 2007 10:33 AM:

    Just the artical I was looking for! Thankyou very much!!

    # Dave Johnson said on September 11, 2007 6:19 PM:

    Hi,

    When I implement this on my local machine it works fine. When I put it on my server 2003 box and browse to it the list of sonds is empty despite the server having loads of songs on there along with media player.

    Any ideas?

    # Emmanuel said on September 17, 2007 5:58 AM:

    Dear Jeff,

                Can you please send me how to create the database that contains the audio files.

    Regards,

    Emmanuel.

    # Robert Williams said on September 20, 2007 12:50 AM:

    I am trying to build a website using www.broardcasting-software.com BS-Server. I am a very novice user and I wanted to know if I could use the coding you suggested using this software? Any suggestion would be greatly appreciated. my email is robertwilliams@sbstechnology.net

    # Mobileapples said on October 5, 2007 5:36 AM:

    This is useful code. I will and test and see if it works with  all the formats.

    # Clarence said on October 22, 2007 2:07 PM:

    What is the user wants to stop the currentMedia? I have tried to use a 'Stop' button

    Sub button_OnClick()

    wmpPlayer.controls.stop

    End Sub

    But on Page.PostBack I cannot access the Media Player that I was controlling from the previous page. All I can access is the new instance of the media player created after my postback oocurred.

    I am not handling anything via client side.

    # Clarence said on November 1, 2007 12:48 AM:

    Got it, Save it to a session variable

    Session.Add("mediaPlayer", wmpPlayer)

    # Duy said on November 10, 2007 10:40 AM:

    Can I hlep you change skin using window media sdk  ( language C# or VB)

    # CodeSnippet: Lets make us a Longhorn - Paul’s Blog said on November 14, 2007 9:29 PM:

    PingBack from http://www.aeoth.net/blog/2007/11/15/codesnippet-lets-make-us-a-longhorn/

    # Coding4Fun said on November 15, 2007 11:48 AM:

    @Emmanuel:  Use a BLOB datatype.

    # Mani said on December 14, 2007 2:59 PM:

    How do I access the "Add to Library" functionality from C# or c++?

    Help will be highly appreciated.

    # Coding4Fun : Building a Web Site with ASP .NET 2.0 to Navigate Your … | Music said on January 1, 2008 12:42 PM:

    PingBack from http://music.247blogging.info/?p=3957

    # Lee said on January 11, 2008 10:42 AM:

    I can only make this work using Cassini.  If i use IIS, it doesn't detect any of my music files.  What am i missing?

    # varadharaj said on January 16, 2008 8:28 AM:

    i need to develop an web application in such a way that the audio files will be stored in a server and i need to play those audio files from an asp.net page i.e i should be able to share the music to all user.

    more over you havent given how to create the database.

    # Coding4Fun said on January 19, 2008 1:42 PM:

    @varadharaj:  I believe we've covered databases in a different area.

    From looking at this, it should play.

    With that said, I think I'm going to create a new version of this article since I tried to run it and couldn't get it to run very easily.

    - clint

    # kram said on February 23, 2008 3:27 PM:

    I have  just begun to use  Microsoft Visual Web Developer 2005 Express Edition version 2.050 727-7600. For development I am usinng  the ASP.NET DEVELOPMENT SERVER that is installed with the developer.

    I have tried to run your code by downloading it from this site and opening in the IDE. I performed a build, resulting in 3 benign looking warnings, that should not really impede execution. Upon execution I received the following server error:

    Server Error in '/VisualBasic' Application.

    --------------------------------------------------------------------------------

    Specified cast is not valid.

    Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

    Exception Details: System.InvalidCastException: Specified cast is not valid.

    Source Error:

    Line 25: Private Shared Sub Refresh()

    Line 26: Dim wmp As WindowsMediaPlayer = New WindowsMediaPlayer

    Line 27: Dim playlist As IWMPPlaylist = wmp.mediaCollection.getAll()

    Line 28: Dim artistDictionary As Dictionary(Of String, Artist) = New Dictionary(Of String, Artist)

    Line 29:

    Can  you  comment?

    Can COM controls be conveniently  used in visual web developer.net express edition? Some users say no!!

    Thank You!!

    # Coding4Fun said on February 23, 2008 11:48 PM:

    I'll work on reencoding this project in a VS Friendlier solution.  This is one of our projects from Coding4Fun version 1 so it could very well be much older than the date listed above.

    # College Fun Facts » Coding4Fun : Building a Web Site with ASP .NET 2.0 to Navigate Your … said on March 31, 2008 4:43 PM:

    PingBack from http://collegefunfactsblog.info/coding4fun-building-a-web-site-with-asp-net-20-to-navigate-your/

    # Samardeep said on April 4, 2008 8:35 AM:

    The simplest way to have a media player in your web applicaion is- Download Microsot Silverlight and ASP.net 3.5 extensions

    # kevin said on May 3, 2008 11:53 AM:

    can you please upload the zip file so i can study, thank you.

    # Matt said on November 10, 2008 5:38 PM:

    Have you fixed this yet so it works over the internet?

    # Matt said on November 10, 2008 11:04 PM:

    How do you point it to your music file. I the directions it says to:

    Replace the following in the web.config with a mapping that's valid on your computer:

     <add key="Mappings" value="g:\music|\\mediacenter\music"/>

    But if I get rid of this line completely and leave it blank the app still gives me that default list of artists. What's going on?????????

    # Matt said on November 10, 2008 11:15 PM:

    I'm sorry but it is very hard to follow your code and your explanation above does not help. THis is supposed to be coding for fun, not code that will frustrate the hell out of you. What is the WMPLib.dll? What is the starting point of the app? Where are you getting the artist that come up when you run the app? Why in your instructions you say to change a line of code that when you change it HAS NO AFFECT ON THE APP. Why when I click on the config for the ObjectDatasSource it gives me an error saying "The type Binder could not be loaded. If the type is located in the App_Code folder, please check that it compiles." What does that mean?

    I'm sorry but this is very frustrating. Try to explain your code better.

    # Avaz said on February 2, 2009 2:35 AM:

    i think it's a great article and does say level: intermediate!

    definetly was fun for me!

    If you don't get it, don't worry ...others do!

    Avaz

    # avaz said on February 2, 2009 4:16 AM:

    Dummy question: Mr.Jeff Key,

    Your application is loading every single artist and it's all albums,  tracks on default.aspx into the memory.

    artist.albums.tracks

    Is not that too much to load? if I had 5,000 University students using my music server per minute?

    If it is how would you solve it?

    May be the design patterns you are practicing just off the shelf and not meant for large scale software?

    Sincerely,

    Avaz

    # Coding4Fun said on February 10, 2009 1:45 PM:

    @Avaz, You can cache the page.  I'd cache it for an hour or longer depending on how often the music collection changes or how often you want it to update.

    No matter what, if you have 5000 people accessing your computer, your hard drives may have a hard time keeping up.  Figure 5MB a song, song is 3 minutes long (so 1.66MB/min), that comes out to be 8.3 gigs worth of data transferred every minute.

    I don't think this was designed for the scenario you're describing.

    # Mosh Jahan said on February 28, 2009 6:22 AM:

    For IIS you may need to configure the Windows Media Player Network Sharing service to run using LocalSystem account.  The IUSR account's media library might also be empty.  I wonder if there is a way to work directly with the WMP database?

    Leave a Comment

    (required) 
    (optional)
    (required) 
    Page view tracker