When trying to access remote content in Silverlight, you need to add a clientaccespolicy.xml file to the root of the web server that you are trying to access. I did this, my file looked like this:
<?xml version="1.0" encoding="utf-8" ?>
<access-policy>
<cross-domain-access>
<policy>
<allow-from http-request-headers="*">
<domain uri="*"/>
</allow-from>
<grant-to>
<resource include-subpaths="true" path="/"/>
</grant-to>
</policy>
</cross-domain-access>
</access-policy>
So essentially, anyone can access this.
I wrote my code to retrieve the information in a C# console app, just to test it out the WebClient as follows:
using System;
using System.IO;
using System.Net;
using System.Linq;
using System.Xml;
using System.Xml.Linq;
namespace GetBlogContentTest
{
class Program
{
static void Main(string[] args)
{
WebClient w = new WebClient();
string result = w.DownloadString(new Uri("http://blogs.interakting.co.uk/MainFeed.aspx"));
if (!String.IsNullOrEmpty(result))
{
XDocument xDoc = XDocument.Parse(result, LoadOptions.SetBaseUri);
var blogItems = from item in xDoc.Descendants("item")
select new ChannelItem
{
Title = (string)item.Element("title"),
Link = (string)item.Element("link"),
PubDate = (DateTime)item.Element("pubDate"),
SourceUrl = (string)item.Element("source").Attribute("url"),
Description = (string)item.Element("description"),
Author = (string)item.Element(XName.Get("creator","http://purl.org/dc/elements/1.1/"))
};
foreach (ChannelItem item in blogItems)
{
Console.WriteLine("Title: {0}", item.Title);
Console.WriteLine("Link : {0}", item.Link);
Console.WriteLine("SUrl : {0}", item.SourceUrl);
Console.WriteLine("Auth : {0}", item.Author);
Console.WriteLine("Date : {0}", item.PubDate);
Console.WriteLine("Content Length: {0}{1}", item.Description.Length, Environment.NewLine);
}
}
else
{
Console.WriteLine("No Results Retrieved");
}
Console.ReadLine();
}
}
}
This also, worked fine. However, when I put the same code in to my shiny new Silverlight application and run it through debug I get myself a nice little error. The error message itself is a little bit on the ambiguous as we sometimes come to expect from technologies in their infancy. Essentially the error I got was "Security error". Gee, thanks for that?!
Digging a little deeper in tot eh actual exception, we get the stack etc and the actual error (sort of):
SecurityException
at MS.Internal.InternalWebRequest.Send()
at System.Net.BrowserHttpWebRequest.BeginGetResponseImplementation()
at System.Net.BrowserHttpWebRequest.InternalBeginGetResponse(AsyncCallback callback, Object state)
at System.Net.AsyncHelper.BeginOnUI(BeginMethod beginMethod, AsyncCallback callback, Object state)
at System.Net.BrowserHttpWebRequest.BeginGetResponse(AsyncCallback callback, Object state)
at InteraktingMainFeed.Page.GetMainFeed()
at InteraktingMainFeed.Page..ctor()
at InteraktingMainFeed.App.Application_Startup(Object sender, StartupEventArgs e)
at System.Windows.CoreInvokeHandler.InvokeEventHandler(Int32 typeIndex, Delegate handlerDelegate, Object sender, Object args)
at MS.Internal.JoltHelper.FireEvent(IntPtr unmanagedObj, IntPtr unmanagedObjArgs, Int32 argsTypeIndex, String eventName)
I was trying everything to fix this until I hit upon the idea of taking Casini (Visual Studio's web server) out of the question (just in case) and setting up a virtual directory on my local IIS to server the Silverlight web app.
That actually fixes it. I don't know why this effects the way the Silverlight app works, but it does. It's highly frustrating and in my opinion completely under-tested. As developers, we generally need to be able to debug our applications but there is now a nice hurdle in the way and you can't just use F5. Basically, I'm going to have to attach to the web process to debug. It's not the end of the world, but it would be nice if I could just debug the lazy way.
I can see that picking up Silverlight is going to have some nice little challenges along the way.