简体   繁体   中英

Create a text file and allow user to download in a lightswitch application

I would like to create a simple text file in my application and allow a user to download it. I have a web application built using lightswitch . I have already google and the responses doesn't help me as it relates to lightswitch.

Download text as file in ASP.NET

Here, the proposal is to use Response. However, that particular namespace isn't available to me in lightswitch. I tried using webclient and i got access denied. My code is below.

    using (System.Net.WebClient wc = new System.Net.WebClient()) {

        string path = AppDomain.CurrentDomain.GetData("DataDirectory").ToString() + "\\" + Application.Current.User.FullName + ".txt";
        string text = "A class is the most powerful data type in C#. Like a structure, " + "a class defines the data and behavior of the data type. ";
        System.IO.File.WriteAllText(path, text);

        wc.DownloadFile(AppDomain.CurrentDomain.GetData("DataDirectory").ToString(), Application.Current.User.FullName + ".txt");

    }

I am able to write my text file to APP_DATA . However, when i tried using webclient to download it, it gives me access denied. Help me please, thanks.

I upload and download Word files in my web application. I followed two articles to help me make this possible:

How Do I: Import and Store a Data File (this one only discusses uploads but the process is similar)
Upload and download file in Lightswitch 2011

In my solution, both upload and download follow the pattern in the first article for symmetry's sake. I didn't really care for the way the second article handled the download side. I can't remember exactly if the references mentioned in the second article are necessary for the way I did things. I have those references in my project but I know I use them for other things. And in VS2013 at least, the unloading and reloading of the project was not necessary.

Essentially, you need to create a custom Silverlight control to add this functionality. So add an .xaml file to your User Code. Both articles have examples of what should be in there and mine looks like this:

<controls:ChildWindow x:Class="LightSwitchApplication.DownloadFileWindow"
           xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
           xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
           xmlns:controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"
           Width="380" Height="125" 
           Title="Select Where to Save File" >
    <Grid x:Name="LayoutRoot" Margin="2">
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <Button x:Name="CancelButton" Content="Cancel" Click="CancelButton_Click" Width="75" Height="25" HorizontalAlignment="Right" Margin="0,15,0,0" Grid.Row="1" />
        <Button x:Name="OKButton" Content="OK" Click="OKButton_Click" Width="75" Height="25" HorizontalAlignment="Right" Margin="0,15,80,0" Grid.Row="1" />
        <Button Content="Browse" Height="25" HorizontalAlignment="Left" Margin="275,10,0,0" Name="BrowseButton" VerticalAlignment="Top" Width="75" Click="BrowseButton_Click" />
        <TextBox Height="25" HorizontalAlignment="Left" Margin="10,10,0,0" Name="FileTextBox" VerticalAlignment="Top" Width="250" IsEnabled="True"/>
    </Grid>
</controls:ChildWindow>

VS2013 (which I'm using) and LightSwitch 2011 (which is what the articles are written for) handle the code behind the .xaml differently. I'm not sure how VS2012 handles it so you'll need to figure that part out. But in the code behind your custom Silverlight control, you need a constructor, functions that set this.DialogResult to true and false for the OK and Cancel buttons, respectively, and three properties:

  1. a DocumentStream as a MemoryStream type to write the file to your computer
  2. a SaveFileStream as a FileStream type to pull the file from the database
  3. a FileName as a String type

The real work of saving the file takes place in the code for the Browse button.

private void BrowseButton_Click(object sender, RoutedEventArgs e) {
    SaveFileDialog saveFileDialog = new SaveFileDialog();
    saveFileDialog.Filter = "Word Files (*.docx)|*.docx|(*.docm)|*.docm";
    saveFileDialog.DefaultExt = "docx";
    if ((saveFileDialog.ShowDialog() == true)) {
        // Get File name, store and display to user
        this.FileTextBox.Text = saveFileDialog.FileName;
        this.m_FileName = saveFileDialog.FileName;
        this.FileTextBox.IsReadOnly = true;
        try {
            // Open and store the File Stream
            this.DocumentStream = saveFileDialog.OpenFile();
        }
        catch (IOException ex) {
            // Inform the user of the problem
            MessageBox.Show("The file you are trying to save to is open in another applicaion." + "\r\n" + "Please close it and try again.", "File Already Open", MessageBoxButton.OK);
        }
    }
}

I have the Filter and DefaultExt set to handle Word docs but you can modify this to handle .txt or whatever you want. I've also added a bit more error handling than the examples in the articles based on my experiences using it.

Finally, in your screen code, you need invoke the custom control on the Main dispatcher and write the file to the database when the custom control closes.

partial void DownloadFile_Execute()
{
    // To invoke our own dialog, we have to do this inside of the "Main" Dispatcher
    // And, since this is a web application, we can't directly invoke the Silverlight OpenFileDialog
    // class, we have to first invoke our own Silverlight custom control (i.e. DownloadFileWindow)
    // and that control will be able to invoke the OpenFileDialog class (via the Browse button)
    Dispatchers.Main.BeginInvoke(() =>
    {
        DownloadFileWindow downloadFileWindow = new DownloadFileWindow();
        downloadFileWindow.Closed += new EventHandler(downloadFileWindow_Closed);
        downloadFileWindow.Show();
    });
}

void downloadFileWindow_Closed(object sender, EventArgs e)
{
    // Invoked when our custom Silverlight window closes
    DownloadFileWindow downloadFile = (DownloadFileWindow)sender;

    try {
        // Continue if they hit the OK button AND they selected a file
        if ((downloadFile.DialogResult == true)) {
            // Write the document data stream from the database to the selected file
            using (Stream saveStream = new Stream(downloadFile.DocumentStream))
            {
                downloadFile.DocumentStream.WriteTo(saveStream);
            }
        }

        // Close and release the streams
        downloadFile.DocumentStream.Close();
        downloadFile.DocumentStream.Dispose();
        downloadFile.SaveFileStream.Close();
        downloadFile.SaveFileStream.Dispose();
    }
    catch (Exception ex) {
        string res = "One or more save location errors have occured:" + "\r\n";

        // Check to see if there is a Document Stream
        if ((downloadFile.DocumentStream == null)) {
            res = res + '\t' + "Document Stream is empty" + "\r\n";
        }
        // Check to see if there is a Save File Stream
        if ((downloadFile.SaveFileStream == null)) {
            res = res + '\t' + "Save File Stream is empty" + "\r\n";
        }
        // Check to see if there is a Safe File Name
        if ((downloadFile.SafeFileName == null)) {
            res = res + '\t' + "Safe File Name is empty" + "\r\n";
        }

        res = res + "\r\n" + "Please use the Browse button to select a location to save to. Specify a file name and then click Save.";

        this.ShowMessageBox(res, "Save Location Error", MessageBoxOption.Ok);
    }
}

As you can see, I've added a lot more error handling to these functions as well, based on experience. Hopefully between the two articles and my examples you can create the functionality that you want.

Note: I converted the code from VB.NET which is what my project is written in. So there may be errors that you have to correct for to make the syntax correct for C#.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM