views:

280

answers:

5

Hi,

I'm trying to get the html content of a page using silverlight. Webresponse and request classes don't work in silverlight.

I did some googling and I found something. This is what i tried:

public partial class MainPage : UserControl
 {
  string result;
  WebClient client;

  public MainPage()
  {
   InitializeComponent();
   this.result = string.Empty;
   this.client = new WebClient();
   this.client.DownloadStringCompleted += ClientDownloadStringCompleted;
  }

  private void btn1_Click(object sender, RoutedEventArgs e)
  {
   string url = "http://www.nu.nl/feeds/rss/algemeen.rss";

   this.client.DownloadStringAsync(new Uri(url, UriKind.Absolute));

   if (this.result != string.Empty && this.result != null)
   {
    this.txbSummery.Text = this.result;
   }
  }

  private void ClientDownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
  {
   this.result = e.Result;
   //handle the response.
  }
 }

It gives me a runtime error after pressing the button:

Microsoft JScript runtime error: Unhandled Error in Silverlight Application An exception occurred during the operation, making the result invalid. Check InnerException for exception details. at System.ComponentModel.AsyncCompletedEventArgs.RaiseExceptionIfNecessary() at System.Net.DownloadStringCompletedEventArgs.get_Result() at JWTG.MainPage.ClientDownloadStringCompleted(Object sender, DownloadStringCompletedEventArgs e) at System.Net.WebClient.OnDownloadStringCompleted(DownloadStringCompletedEventArgs e) at System.Net.WebClient.DownloadStringOperationCompleted(Object arg)

I've tried numerous things but all failed.

What am i missing? Or does anyone know how i could achieve this in a different way?

Thanks in advance!

A: 

In this line

this.client.DownloadStringAsync(new Uri(url, UriKind.Absolute)); 

you are stating an asynchroneous download in a background thread. And in the next line you somehow expect that it is aready completed?

If you have no knowledge about Threading just try with DownloadString first. Then your code will work.

Foxfire
Hi,I tried putting that 'next line' in the download callback, but that didn't fixed the runtime error.Where can i find this 'downloadstring'? What class does it belong to?
Yustme
@Foxfire: you dont really want to make a blocking call to retrieve a webpage, do you? Yustme should just use the `DownloadStringAsync`, but put the logic of handling the returned data into the `ClientDownloadStringCompleted` method.
Philip Daubmeier
@Yustme: You can't put the thing afterwards into the event either because it will be called from a different thread.
Foxfire
@Philip: Yes I would want that - at least until he gets the error sorted out. And he can't just put his current logic there because this.txbSummery runs on another thread as the event invocation.
Foxfire
A: 

Hi,

I tried that:

private void btn1_Click(object sender, RoutedEventArgs e)
        {
            string url = "http://www.nu.nl/feeds/rss/algemeen.rss";

            this.client.DownloadStringAsync(new Uri(url, UriKind.Absolute));

        }

        private void ClientDownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
        {
            this.result = e.Result;
            //handle the response.
            if (this.result != string.Empty && this.result != null)
            {
                this.txbSummery.Text = this.result;
            }
        }

Still produces that runtime error..

At this line:

this.result = e.Result;

Yustme
Like I already said: You are getting a JScript error, that primarily doesnt have to do with the `DownloadStringAsync`. What else are you doing in your application that could cause that error? Because your code snippet works one-to-one for me.
Philip Daubmeier
@Yustme: Please edit your question. What you posted is no answer to your question. Stackoverflow is not a discussion forum but a question-answer site.
Philip Daubmeier
Hi,At the time i looked at your post, there was nothing about JScript error. Also, what exactly do you want me to edit and which question?
Yustme
+1  A: 

Try this one, instead of your btn1_Click and ClientDownloadStringCompleted methods. It invokes the GUI thread after the feed is downloaded to update the textbox. If it fails because of an error on the network, it will unpack the exception (contained as an inner exception in a TargetInvocationException) and rethrow the inner exception.

private void btn1_Click(object sender, RoutedEventArgs e)
{
    string url = "http://www.nu.nl/feeds/rss/algemeen.rss";

    this.client.DownloadStringAsync(new Uri(url));
}

private void ClientDownloadStringCompleted(object sender, 
                      DownloadStringCompletedEventArgs e)
{
    try
    {
        Dispatcher.BeginInvoke(() => this.txbSummery.Text = e.Result ?? "");
    }
    catch (TargetInvocationException tiex)
    {
        throw tiex.InnerException;
    }
}

If the error occures again (I guess that will happen), please post a stacktrace and error message here.

Philip Daubmeier
Hi,Somehow i overlooked this post :oThis is what i get:throw new Error("Unhandled Error in Silverlight Application An exception occurred during the operation, making the result invalid. Check InnerException for exception details. at System.ComponentModel.AsyncCompletedEventArgs.RaiseExceptionIfNecessary()\n at System.Net.DownloadStringCompletedEventArgs.get_Result()\n at JWTG.MainPage.<>c__DisplayClass2.<ClientDownloadStringCompleted>b__0()");there is no stacktrace
Yustme
Damn that is again boxed in an exception. So could you perhaps take a look at the innerException then? Either use the debugger, or just replace `throw tiex.InnerException;` with `throw tiex.InnerException.InnerException;`
Philip Daubmeier
It never gets that far, it stops at Dispatcher.BeginInvoke(() => this.txbSummery.Text = e.Result ?? ""); but see my post under this one for further info
Yustme
A: 

@ Philip Daubmeier, this is the innerexception:

{System.Security.SecurityException ---> System.Security.SecurityException: Security error. at System.Net.Browser.BrowserHttpWebRequest.InternalEndGetResponse(IAsyncResult asyncResult) at System.Net.Browser.BrowserHttpWebRequest.<>c_DisplayClass5.b_4(Object sendState) at System.Net.Browser.AsyncHelper.<>c_DisplayClass2.b_0(Object sendState) --- End of inner exception stack trace --- at System.Net.Browser.AsyncHelper.BeginOnUI(SendOrPostCallback beginMethod, Object state) at System.Net.Browser.BrowserHttpWebRequest.EndGetResponse(IAsyncResult asyncResult) at System.Net.WebClient.GetWebResponse(WebRequest request, IAsyncResult result) at System.Net.WebClient.DownloadBitsResponseCallback(IAsyncResult result)} and

expanding it more gives me this innerexception:

{System.Security.SecurityException: Security error. at System.Net.Browser.BrowserHttpWebRequest.InternalEndGetResponse(IAsyncResult asyncResult) at System.Net.Browser.BrowserHttpWebRequest.<>c_DisplayClass5.b_4(Object sendState) at System.Net.Browser.AsyncHelper.<>c_DisplayClass2.b_0(Object sendState)}

Yustme
A: 

This is related to clientaccesspolicy.xml. Read more here: http://msdn.microsoft.com/en-us/library/cc645032(VS.95).aspx

"If the connection request was from a WebClient or an HTTP class to a cross-domain site, the Silverlight runtime tries to download the security policy file using the HTTP protocol. The Silverlight runtime first tries to download a Silverlight policy file with a name of "clientaccesspolicy.xml" at the root of the requested target domain using the HTTP protocol.

If the "clientaccesspolicy.xml" is either not found (the web request returns a 404 status code), returned with an unexpected mime-type, is not valid XML, or has an invalid root node, then the Silverlight runtime will issue a request for a for the Flash policy file with a name of "crossdomain.xml" at the root of the requested target domain, using the HTTP protocol.

HTTP redirects for the policy file are not allowed. A redirect for a policy file will result in a SecurityException of access denied."

Sergei Golubev
Hi,I figured it out. The website i was trying to access with silverlight doesn't have the policy file. Thanks anyway!
Yustme