Vinny
Vinny

Reputation: 55

securityException in Silverlight: dialogs must be user initiated

I'm trying to create a Silverlight application that downloads a file accessed by a URL. I tried using WCF, but now I'm attempting to do it with Webclient. When I try using this sample code, I'm getting a securityException error that says "Dialogs must be user initiated." Can someone please explain what I'm doing wrong? Thanks.

using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace SilverlightApplication1
{
    public partial class MainPage : UserControl
    {
        #region Constructors
        public MainPage()
        {
            InitializeComponent();

           // SaveFileDialog sfd = new SaveFileDialog();

        }
        #endregion

        #region Handlers

        void webClient_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
        {
            SaveFileDialog sfd = new SaveFileDialog();
            if ((bool)sfd.ShowDialog())
            {
                StreamReader sr = new StreamReader(e.Result);
                string str = sr.ReadToEnd();

                StreamWriter sw = new StreamWriter(sfd.OpenFile());
                sw.Write(str);
           }
        }

        private void download_Click_1(object sender, RoutedEventArgs e)
        {
            WebClient webClient = new WebClient();
            webClient.OpenReadCompleted += new OpenReadCompletedEventHandler(webClient_OpenReadCompleted);
            webClient.OpenReadAsync(new Uri("http://www.productimageswebsite.com/images/stock_jpgs/34891.jpg", UriKind.Absolute));
        }
        #endregion
    }
}

Upvotes: 1

Views: 8070

Answers (1)

AnthonyWJones
AnthonyWJones

Reputation: 189457

The basic problem as the answers to the older questions point out is that the OpenReadCompleted event occurs asynchronously with the button click. There is no way for silverlight be be sure that code execting in the event handler is a result of a user action.

What is needed to turn things around, get the user to pick the save destination before invoking the download. Here is a button click event that handles the lot:-

private void Button_Click(object sender, RoutedEventArgs e)
{
    SaveFileDialog sfd = new SaveFileDialog();
    if (sfd.ShowDialog() ?? false)
    {

        WebClient client = new WebClient();
        client.OpenReadCompleted += (s, args) =>
        {
            using (Stream output = sfd.OpenFile())
            {
                args.Result.CopyTo(output);
                output.Flush();
            }
        };
        client.OpenReadAsync(new Uri("http://www.productimageswebsite.com/images/stock_jpgs/34891.jpg", UriKind.Absolute));
    }
}

BTW had you been successfull your use of StreamReader / StreamWriter may well have messed things up, these are for reading and writing text. In this case a simple call to CopyTo does the trick.

Upvotes: 1

Related Questions