Ian Blackburn

Silverlight Wcf: The remote server returned an unexpected response: (404) Not Found. Jul 23

Keep getting this error on a Silverlight 2 B2 project that is referencing a WCF service in a Web Site (not web project).

error

There doesn't seem to be any reason for it, and it happens intermittently, however the workaround I have for it currently is to simple open up the cs class for the service and make any edit (e.g. just add a comment line) and then build.  This seems to fix it for a while.

Hope there is a better solution long term, or a fix for this somewhere...

Ian

 

Technorati Tags: ,

The Amazing Album Cover Atlas Jul 22

http://theamazingalbumcoveratlas.org/

The Amazing Album Cover Atlas

The excellent Word Magazine recently created an album cover atlas which shows locations of famous album covers.  Cool idea, but I didn't like the basic google maps interface. 

So as an exercise and to also help spike out some work we are doing on www.lovecleanstreets.org I created a quick Virtual Earth and Silverlight version that make use of the VIEWS VE managed wrapper for Silverlight.

Luckily the original developer, Ian Reeves used a REST service to get the data, so I was able to work with the same live data for my project.  There was no cross-domain policy that could be used by Silverlight though, so I created a WCF bridge service instead on my web project and referenced that from the Silverlight project:

[OperationContract()]
 public List<AlbumCover> GetAlbums()
 {
 
     const string rootUrl = "http://www.wordmagazine.co.uk/album_atlas/";

     WebClient client = new WebClient();
     string result= client.DownloadString(rootUrl + "xmlGeneratorAlbums.php");
     XDocument data = XDocument.Parse(result);
     IEnumerable<AlbumCover> albums = from cover in data.Elements("albumcovers").Elements()
                                      where cover.Attribute("ident").Value != "1"
                                      select new AlbumCover { 
                                          Ident = SafeIntParse(cover.Attribute("ident").Value), 
                                          Album = cover.Attribute("album").Value, 
                                          Latitude = SafeDoubleParse(cover.Attribute("latitude").Value),
                                          Longitude = SafeDoubleParse(cover.Attribute("longitude").Value),
                                          Artist=cover.Attribute("artist").Value,
                                          Link=cover.Attribute("link").Value,
                                          AddedBy=cover.Attribute("addedby").Value,
                                          Details=cover.Attribute("details").Value, 
                                          Location=cover.Attribute("location").Value,
                                          ImageUrl=rootUrl 
                                             + "getimage.php?ident=" 
                                             + SafeIntParse(cover.Attribute("ident").Value) };
     return albums.ToList();
 }

 

This worked fine on the development server, but I hit an issue when it was hosted on IIS.  The service threw an exception: "This collection already contains an address with scheme http" - turns out this is an issue if you have more than one host header with the Wcf service.  The solution is to write a custom host factory as described here by DiscountAsp support (we are not using DiscountAsp - but this is a good explanation that will work with any hoster)

Another issue I came across was to do with the images.  There are already over 400 album covers in the database, and I thought it would be nice to store those in Isolated Storage for fast re-use - unfortunately although you can serialise the data into isolated storage, there does not currently seem to be a way to get the Silverlight Image control to display them (you can't create an image from a stream - only from a Uri), so I have had to rely on browser caching instead.

Source code is available below, and offers no guarantee of anything but might be worth a look if you are trying this sort of thing.

 

Cheers

Ian

Being enticed by Live Mesh Jul 18

Live Mesh is in early days yet, but having had it installed for a while, I am starting to see the possibilities

The mobile web client is now available (though the full mobile client is still "coming soon") at http://m.mesh.com and using this to upload an image and then see it appear almost instantly on your other devices is compelling.

The real power of Mesh will come with the api - then we can start to really create apps that live on and offline easily.  I am eagerly anticipating when that will be available (my guess: the PDC).  In particular I am hoping that we can plug into the framework and process files during sync - resizing images on upload for example, and then downloading the full version from another desktop on request.

For now, I am happily syncing music between devices, playing them online using the Live Desktop Silverlight Media Player, and downloading any tracks I want on demand on my mobile device ;-)

image

Ian

Technorati Tags:

Linq Performance with Generic Lists Jul 10

** UPDATE * - this is messed up!  read the comments for more details...

A question came up today on MsWebDev as follows:

I have two lists of integers, each with approximately 300,000 integers in them. I need to work out which integers are in List A but not in List B.

Their first thought was to "literate through List A and ask if List B contains the current integer. If it doesn’t then I add it to a third list and return that at the end", but this was giving poor performance (10 minutes!)

The use of a Hashtable was suggested, and this gave dramatic performance improvements taking the operation down to 1 second!

 

foreach (int current in listB)
            {
                htB.Add(current, current);
            }

            List<int> cList2 = new List<int>();

            foreach (int current in listA)
            {
                if (htB[current] != null)
                {
                    cList2.Add(current);
                }
            }

 

However I was intrigued to see how Linq would perform.  The code was beautifully simple:

var cList = from c in aList
            where bList.Contains(c)
            select c;

 

And when I ran a simple test, Linq was significantly faster than the Hashtable too:

clip_image002

That is quite interesting and at some point I will investigate how it is so. 

For now if you want to play with the very rough and ready test code, you can download it from my sky drive here:

Cheers

Ian

 

Technorati Tags: ,

Silverlight Transparency - use PluginBackground not Background! Jun 27

If you want to have your Silverlight control to have a transparent background, then it is simply a question of setting the properties that Mike Snows describes in his tip post.

What had caught me out previously and the reason for this post is that I had used the Background property of the Silverlight control, rather then the correct PluginBackground property.  Confusingly this works for the Html control but not the Aspx one.  I had in fact filed it as a bug, and perhaps it is because I am not sure we need both of those properties?

Cheers

Ian

Technorati Tags:

Apple's Mobile Me == Windows Me (well the logo at least) Jun 09

Apple just announce MobileMe for push email, contacts and calendars for data in the cloud.  Interesting stuff - but the logo?  Hmmm.....

image  == image

 

Cheers

Ian

Technorati Tags: ,

Bridging Web Service Calls in Silverlight Jun 06

For security reasons, the Silverlight version 2 runtime restricts access to certain classes of URLs from the WebClient and HTTP classes in the System.Net namespace. 

The main requirement is that the services you want to use should implement either crossdomain.xml (which is the Flash policy file) or clientaccesspolicy.xml (which is the Silverlight one).  If the service you want to use does not implement one of these then you can't use Silverlight to access it.

However such restrictions are not present when using WebClient on the server, so you can easily create a bridge service that your Silverlight client can use.

For example you could create a very simple WCF Service in the same web site that will host your Silverlight app as follows:

using System;
using System.ServiceModel;

[ServiceContract]
public interface IFeeds
{
    [OperationContract]
    string GetFeed(Uri uri);
}
using System;
using System.Net;

public class Feeds : IFeeds
{
 

    #region IFeeds Members

    public string GetFeed(Uri uri)
    {
        WebClient client = new WebClient();
        return client.DownloadString(uri);
    }

    #endregion
}

Note:  You need to change the Wcf service binding in web.config so that you use a basicHttpBinding rather than the wsHttpBinding (which is not supported by Silverlight)

 

<system.serviceModel>
 <behaviors>
  <serviceBehaviors>
   <behavior name="FeedsBehavior">
    <serviceMetadata httpGetEnabled="true" />
    <serviceDebug includeExceptionDetailInFaults="false" />
   </behavior>
  </serviceBehaviors>
 </behaviors>
 <services>
  <service behaviorConfiguration="FeedsBehavior" name="Feeds">
   <endpoint address="" binding="basicHttpBinding" contract="IFeeds">
    <identity>
     <dns value="localhost" />
    </identity>
   </endpoint>
   <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
  </service>
 </services>
</system.serviceModel>

 

Now you can add a service reference from your Silverlight application to this Wcf service and use it something like as follows:

private void Button_Click(object sender, RoutedEventArgs e)
  {
      ServiceReference1.FeedsClient client = new ServiceReference1.FeedsClient();
      client.GetFeedCompleted += client_GetFeedCompleted;
      client.GetFeedAsync(new Uri("http://timesonline.typepad.com/sports_commentary/atom.xml"));
  }

  void client_GetFeedCompleted(object sender, ServiceReference1.GetFeedCompletedEventArgs e)
  {
      TextBlock1.Text = e.Result;
  }

 

Cheers

Ian

Technorati Tags: ,,

Simple FriendFeed C# User Control Jun 06

image We use a simple Friend Feed user control on our home page.  We have found this a great way to share "filtered" information that is relevant to our customers. 

What we have done is created a FriendFeed account called bbits, which we share things into (via google reader and other feeds). 

The user control then picks the friendfeed up and displays this in a gridview.

When we did this FriendFeed didn't have any widgets, which they do have now, (and here) so if you prefer to use those rather than a c# user control go visit those pages now.

Our c# user control can be found below or from here (this also includes a modified version of the c# library produced by friendfeed, that solves a few small issues and bugs)

 

Cheers

Ian Blackburn

Technorati Tags: ,,

WCF: "a non-empty contract name must be specified" Jun 03

This error had me baffled today, and I could find little reference to it from Google or Live Search.

It was the result of creating a simple WCF Service with two methods as follows and then trying to add a reference to it from Silverlight 2:

[ServiceContract]
public interface IWcfService
{
    [OperationContract]
    string HelloWorld(string name);
    [OperationContract]
    List<Person> GetPeople();
}

 

public class WcfService : IWcfService
{
    public string HelloWorld(string name)
    {
        return "Hello World " + name;
    }


    #region IWcfService Members


    public List<Person> GetPeople()
    {
        List<Person> people = new List<Person>();
        people.Add(new Person() { FirstName = "Fred", LastName = "Bloggs", Age = 23 });
        people.Add(new Person() { FirstName = "Fred", LastName = "Smith", Age = 24 });
        people.Add(new Person() { FirstName = "John", LastName = "Bloggs", Age = 29 });
        return people;
    }

    #endregion
}
 
The service config looked good (having changed to a basicHttpBinding - which is the what Silverlight 2 supports:
 
<system.serviceModel>
  <behaviors>
   <serviceBehaviors>
    <behavior name="WcfServiceBehavior">
     <serviceMetadata httpGetEnabled="true" />
     <serviceDebug includeExceptionDetailInFaults="true" />
    </behavior>
    
   </serviceBehaviors>
  </behaviors>
  <services>
   <service behaviorConfiguration="WcfServiceBehavior" name="WcfService">
    <endpoint address="" binding="basicHttpBinding" bindingConfiguration=""
     contract="IWcfService">
     <identity>
      <dns value="localhost" />
     </identity>
    </endpoint>
   </service>
   
  </services>
 </system.serviceModel>

 

But I kept getting this error.  And the other 6 delegates on the course I was delivering were getting exactly the same problem!  I kept thinking that this was something to do with Silverlight, but I was barking up the wrong tree.  It wasn't until I got on the train home, that it suddenly hit me, I had not marked the Person class with the DataContract and DataMember attributes!  This was what was needed to sort it out:

[DataContract]
public class Person
{
    [DataMember]
    public string FirstName { get; set; }
    [DataMember]
    public string LastName { get; set; }
    [DataMember]
    public int Age { get; set; }
}

 

Still, in my defence, I think the cause of the error message wasn't that obvious.

Hope this helps someone!

Cheers

Ian

Technorati Tags: ,