views:

3985

answers:

5

I have Vista with IIS7.

I want to create a simple Silverlight application that reads an xml file from localhost.

I created this file (which I had to copy and click "allow" as administrator):

C:\inetpub\wwwroot\data\customers.xml

and can see it when I go here in a browser:

http://localhost/data/customers.xml

But when I run the following code, I get a target invocation exception:

using System;
using System.Net;
using System.Windows.Controls;
using System.IO;

namespace TestXmlRead234
{
    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();

            WebClient client = new WebClient();
            client.OpenReadAsync(new Uri("http://localhost/data/customers.xml", UriKind.Absolute));
            client.OpenReadCompleted += new OpenReadCompletedEventHandler(client_OpenReadCompleted);
        }

        void client_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
        {
            StreamReader myReader = new StreamReader(e.Result);
            Output.Text = myReader.ReadLine();
            myReader.Close();
        }
    }
}

So I created C:\inetpub\wwwroot\crossdomainpolicy.xml:

<?xml version="1.0" encoding="utf-8"?>
<access-policy>
    <cross-domain-access>
        <policy >
            <allow-from http-request-headers="Content-Type">
                <domain uri="*"/>
            </allow-from>
            <grant-to>
                <resource path="/" include-subpaths="true"/>
            </grant-to>
        </policy>
    </cross-domain-access>
</access-policy>

But I still get the target invocation exception error.

Here is the full inner exception:

{System.Security.SecurityException ---> System.Security.SecurityException: Sicherheitsfehler bei System.Net.Browser.BrowserHttpWebRequest.InternalEndGetResponse(IAsyncResult asyncResult) bei System.Net.Browser.BrowserHttpWebRequest.<>c__DisplayClass5.b__4(Object sendState) bei System.Net.Browser.AsyncHelper.<>c__DisplayClass2.b__0(Object sendState) --- Ende der internen Ausnahmestapelüberwachung --- bei System.Net.Browser.AsyncHelper.BeginOnUI(SendOrPostCallback beginMethod, Object state) bei System.Net.Browser.BrowserHttpWebRequest.EndGetResponse(IAsyncResult asyncResult) bei System.Net.WebClient.GetWebResponse(WebRequest request, IAsyncResult result) bei System.Net.WebClient.OpenReadAsyncCallback(IAsyncResult result)}

update 1: In windows explorer, I then right clicked C:\inetpub\wwwroot\data and made IIS_USERS a co-owner of that directory. But still get the same error. :-(

update 2: also made "everyone" co-owner of C:\inetpub\wwwroot\data, same error. :-(

update 3: opened command window as administrator and executed this command: netsh http add urlacl url=http://+:80/ user=MYDOMAIN\MyUserName

What else do I have to be able to read a text file from localhost from a Silverlight application?

PRAGMATIC ANSWER:

For testing locally just publish to the temporary localhost webserver port for which you don't even need a cross-domain file, then make necessary changes when you publish live:

using System;
using System.Linq;
using System.Net;
using System.Windows.Controls;
using System.IO;
using System.Xml.Linq;

namespace TestWeb124
{
    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();

            WebClient wc = new WebClient();
            wc.OpenReadAsync(new Uri("http://localhost:49512/customers.xml", UriKind.Absolute));
            wc.OpenReadCompleted += wc_OpenReadCompleted;
        }

        private void wc_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                Output.Text = e.Error.Message;
                return;
            }
            using (Stream s = e.Result)
            {
                XDocument doc = XDocument.Load(s);
                Output.Text = doc.ToString(SaveOptions.OmitDuplicateNamespaces);
                var customers = from c in doc.Descendants("customer")
                                select new
                                {
                                    FirstName = c.Element("firstName").Value
                                };

                foreach (var customer in customers)
                {
                    Output.Text += customer.FirstName;
                }

            }
        }        



    }
}
A: 

Making a Service Available Across Domain Boundaries

Koistya Navin
right, that page says "Save the clientaccesspolicy.xml file to the root of the domain where the service is hosted." which is what I did. Just as a test I also added the clientaccesspolicy.xml to C:\inetpub\wwwroot\data but that predictably doesn't work either. What else do I have to do?
Edward Tanguay
A: 

Try removing the attribute http-request-headers="Content-Type", I'm not sure what that is acheiving.

AnthonyWJones
thanks, tried that but still same error, I assume this is some kind of difficult to determine ACL security issue on vista, what could it be, do I need to give access to wwwroot and below to IUSER... (I'm thinking back to ASP 3.0 days here) it must be something simple like that, and something common.
Edward Tanguay
@Edward: That may be a possiblity but if that were true you shouldn't be able to visit it via your browser either. Try visiting the XML in firefox. Then try using IE and SL with fiddler running (so you can inspect the http conversation). http://www.fiddlertool.com/fiddler
AnthonyWJones
A: 

I had similar issues being able to access pages on my local IIS from a Silverlight application. I ended up configuring a HTTP proxy to see what was going on. In my case Silverlight was sending the request for crossdomainpolicy.xml and IIS was correctly returning it so there were definitely no ACL issues but for some reason Silverlight just wouldn't accept it.

After trying endless options in the crossdomainpolicy file I decided I'd test out the alternative option of the Flash crossdomain.xml policy file which Silverlight also understands and it worked first time.

Might work for you.

<?xml version=""1.0""?>
<!DOCTYPE cross-domain-policy SYSTEM ""http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd""&gt;
<cross-domain-policy>
    <allow-http-request-headers-from domain=""*"" headers=""*""/>
</cross-domain-policy>

Edit: To try this out you will need to remove the crossdomainpolicy.xml file as Silverlight requests that first and if it finds it won't request crossdomain.xml.

sipwiz
I tried both combinations that you mentioned, I still get the same error as posted above, e.g. I now have only the crossdomain.xml file at C:\inetpub\wwwroot\crossdomain.xml. Is there anything I need to do in IIS7? I'm going to try turning up access on the folder with my data xml file.
Edward Tanguay
If you're suspect about your IIS server not getting the files through to SL I'd highly recommend configuring your browser with a proxy server to check the IIS response http://www.pocketsoap.com/tcptrace/pt.aspx.
sipwiz
+1  A: 

From what I've seen, the usual behaviour is to create a webservice that can get around Silverlight's cross domain issues entirely, then have Silverlight code communicate through that web service.

TreeUK
A: 

Your xml is illformed and has an extra > near the top.