Today’s post is going to be a short one about how to import a file through a Visual Studio LightSwitch application (Desktop or Web) and store the data on the backend (e.g. SQL Server).
Sometimes we want to upload files in binary format and store them in the database, like a Word document or PDF file or any other file containing unstructured data. LightSwitch already has the built-in ability to store and retrieve images, but if you want to store other types of files we have to write a small bit of code.
This post is really just me picking out various pieces of code from my other posts and cramming it together to make a new post. Which is a nice break for me, since writing a post often takes about a week (after I write the code and write up a draft blog, then get feedback, and double check the code several times). But with this one I should be done in a day leaving more time to enjoy the very brief Summers we have up here in Fargo, North Dakota.
Alright, let’s get started making a simple LightSwitch Web Application. Let’s create the project, and a table that will hold our file data.
<controls:ChildWindow x:Class="LightSwitchApplication.UserCode.SelectFileWindow" 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="394" Height="305" Title="Select File Dialog" > <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="23" HorizontalAlignment="Right" Margin="0,12,0,0" Grid.Row="1" /> <Button x:Name="OKButton" Content="OK" Click="OKButton_Click" Width="75" Height="23" HorizontalAlignment="Right" Margin="0,12,79,0" Grid.Row="1" /> <Button Content="Browse" Height="23" HorizontalAlignment="Left" Margin="291,92,0,0" Name="BrowseButton" VerticalAlignment="Top" Width="75" Click="BrowseButton_Click" /> <TextBox Height="23" HorizontalAlignment="Left" Margin="66,92,0,0" Name="FileTextBox" VerticalAlignment="Top" Width="219" IsEnabled="True"/> </Grid> </controls:ChildWindow>
<controls:ChildWindow x:Class="LightSwitchApplication.UserCode.SelectFileWindow"
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="394" Height="305"
Title="Select File Dialog" >
<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="23" HorizontalAlignment="Right" Margin="0,12,0,0" Grid.Row="1" />
<Button x:Name="OKButton" Content="OK" Click="OKButton_Click" Width="75" Height="23" HorizontalAlignment="Right" Margin="0,12,79,0" Grid.Row="1" />
<Button Content="Browse" Height="23" HorizontalAlignment="Left" Margin="291,92,0,0" Name="BrowseButton" VerticalAlignment="Top" Width="75" Click="BrowseButton_Click" />
<TextBox Height="23" HorizontalAlignment="Left" Margin="66,92,0,0" Name="FileTextBox" VerticalAlignment="Top" Width="219" IsEnabled="True"/>
</Grid>
</controls:ChildWindow>
//' Copyright © Microsoft Corporation. All Rights Reserved. //' This code released under the terms of the //' Microsoft Public License (MS-PL, http://opensource.org/licenses/ms-pl.html) using System; using System.IO; using System.Windows; using System.Windows.Controls; namespace LightSwitchApplication.UserCode { public partial class SelectFileWindow : ChildWindow { public SelectFileWindow() { InitializeComponent(); } private FileStream documentStream; public FileStream DocumentStream { get { return documentStream; } set { documentStream = value; } } private String safeFileName; public String SafeFileName { get { return safeFileName; } set { safeFileName = value; } } /// <summary> /// OK Button /// </summary> private void OKButton_Click(object sender, RoutedEventArgs e) { this.DialogResult = true; } /// <summary> /// Cancel button /// </summary> private void CancelButton_Click(object sender, RoutedEventArgs e) { this.DialogResult = false; } /// <summary> /// Browse button /// </summary> private void BrowseButton_Click(object sender, RoutedEventArgs e) { OpenFileDialog openFileDialog = new OpenFileDialog(); if (openFileDialog.ShowDialog() == true) { this.FileTextBox.Text = openFileDialog.File.Name; this.safeFileName = openFileDialog.File.Name; this.FileTextBox.IsReadOnly = true; FileStream myStream = openFileDialog.File.OpenRead(); this.documentStream = myStream; } } } }
//' Copyright © Microsoft Corporation. All Rights Reserved.
//' This code released under the terms of the
//' Microsoft Public License (MS-PL, http://opensource.org/licenses/ms-pl.html)
using System;
using System.IO;
using System.Windows;
using System.Windows.Controls;
namespace LightSwitchApplication.UserCode
{
public partial class SelectFileWindow : ChildWindow
public SelectFileWindow()
InitializeComponent();
}
private FileStream documentStream;
public FileStream DocumentStream
get { return documentStream; }
set { documentStream = value; }
private String safeFileName;
public String SafeFileName
get { return safeFileName; }
set { safeFileName = value; }
/// <summary>
/// OK Button
/// </summary>
private void OKButton_Click(object sender, RoutedEventArgs e)
this.DialogResult = true;
/// Cancel button
private void CancelButton_Click(object sender, RoutedEventArgs e)
this.DialogResult = false;
/// Browse button
private void BrowseButton_Click(object sender, RoutedEventArgs e)
OpenFileDialog openFileDialog = new OpenFileDialog();
if (openFileDialog.ShowDialog() == true)
this.FileTextBox.Text = openFileDialog.File.Name;
this.safeFileName = openFileDialog.File.Name;
this.FileTextBox.IsReadOnly = true;
FileStream myStream = openFileDialog.File.OpenRead();
this.documentStream = myStream;
//' Copyright © Microsoft Corporation. All Rights Reserved. //' This code released under the terms of the //' Microsoft Public License (MS-PL, http://opensource.org/licenses/ms-pl.html) using System; using System.Collections.Generic; using System.IO; using System.IO.IsolatedStorage; using System.Linq; using LightSwitchApplication.UserCode; using Microsoft.LightSwitch; using Microsoft.LightSwitch.Framework.Client; using Microsoft.LightSwitch.Presentation; using Microsoft.LightSwitch.Presentation.Extensions; using Microsoft.LightSwitch.Threading; namespace LightSwitchApplication { public partial class EditableFileInformationsGrid { partial void ImportAFile_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. SelectFileWindow) // and that control will be able to invoke the OpenFileDialog class (via the Browse button) Dispatchers.Main.BeginInvoke(() => { SelectFileWindow selectFileWindow = new SelectFileWindow(); selectFileWindow.Closed += new EventHandler(selectFileWindow_Closed); selectFileWindow.Show(); }); } /// <summary> /// Invoked when our custom Silverlight window closes /// </summary> void selectFileWindow_Closed(object sender, EventArgs e) { SelectFileWindow selectFileWindow = (SelectFileWindow)sender; // Continue if they hit the OK button AND they selected a file if (selectFileWindow.DialogResult == true && (selectFileWindow.DocumentStream != null)) { byte[] fileData = new byte[selectFileWindow.DocumentStream.Length]; using (StreamReader streamReader = new StreamReader(selectFileWindow.DocumentStream)) { for (int i = 0; i < selectFileWindow.DocumentStream.Length; i++) { fileData[i] = (byte)selectFileWindow.DocumentStream.ReadByte(); } } // Create a new record for this file, and store the data, name and length FileInformation fileInformation = this.DataWorkspace.ApplicationData.FileInformations.AddNew(); fileInformation.Name = selectFileWindow.SafeFileName; fileInformation.Miscellaneous = "Size of file in bytes: " + fileData.Length; fileInformation.Data = fileData; selectFileWindow.DocumentStream.Close(); selectFileWindow.DocumentStream.Dispose(); } } } }
using System.Collections.Generic;
using System.IO.IsolatedStorage;
using System.Linq;
using LightSwitchApplication.UserCode;
using Microsoft.LightSwitch;
using Microsoft.LightSwitch.Framework.Client;
using Microsoft.LightSwitch.Presentation;
using Microsoft.LightSwitch.Presentation.Extensions;
using Microsoft.LightSwitch.Threading;
namespace LightSwitchApplication
public partial class EditableFileInformationsGrid
partial void ImportAFile_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. SelectFileWindow)
// and that control will be able to invoke the OpenFileDialog class (via the Browse button)
Dispatchers.Main.BeginInvoke(() =>
SelectFileWindow selectFileWindow = new SelectFileWindow();
selectFileWindow.Closed += new EventHandler(selectFileWindow_Closed);
selectFileWindow.Show();
});
/// Invoked when our custom Silverlight window closes
void selectFileWindow_Closed(object sender, EventArgs e)
SelectFileWindow selectFileWindow = (SelectFileWindow)sender;
// Continue if they hit the OK button AND they selected a file
if (selectFileWindow.DialogResult == true && (selectFileWindow.DocumentStream != null))
byte[] fileData = new byte[selectFileWindow.DocumentStream.Length];
using (StreamReader streamReader = new StreamReader(selectFileWindow.DocumentStream))
for (int i = 0; i < selectFileWindow.DocumentStream.Length; i++)
fileData[i] = (byte)selectFileWindow.DocumentStream.ReadByte();
// Create a new record for this file, and store the data, name and length
FileInformation fileInformation = this.DataWorkspace.ApplicationData.FileInformations.AddNew();
fileInformation.Name = selectFileWindow.SafeFileName;
fileInformation.Miscellaneous = "Size of file in bytes: " + fileData.Length;
fileInformation.Data = fileData;
selectFileWindow.DocumentStream.Close();
selectFileWindow.DocumentStream.Dispose();
Additionally, there is an extension that can be added to Visual Studio LightSwitch called Document Toolkit for LightSwitch, which handles importing and viewing Word Documents. It will only work for Desktop applications, and it isn’t free, but other than that it looks like a slick extension.
That’s it for this brief post. I've included a zip file below of the C# code.
Again, love to hear if there are any questions, and if you think something is wrong with this code (or the title) then you are probably right so please let me know.
-Matt Sampson
Hi,
great work, i want to know if it is possible to upload files to hard drive with wcf ria service ?
Hi Matt: thanks for this useful example
I've figured to adapt it for VB; however, hasn't had success writing the code for the inverse path: to retrieve the binary file previously stored in the database and save it on a local folder (in web mode).
You have any example to accomplish this?
Is it possible to have this code in VB?
@Neil Sitko - Neil there is a C# to VB converter out there that I use for all my needs - www.developerfusion.com/.../csharp-to-vb
Thanks Matt
Hi Matt,
thats a nice example. I tried to expand your "SelectFileDialog" with a additional button which works like the "add" Button in LightSwitch Business application. Unfortunately I failed. Could you show how I can add such a button please. thx
I used your nice example for the Northwind database which is included in lightswitch but at this point of your code (see below) I cant choose another table that is not createt in LightSwitch :(.
// Editable Grid
Product Product = DataWorkspace.ApplicationData.**Product**.AddNew();
In this case Product is not available in the dropdown box.
Any idea how I can access a table which is not creat but included in Lightswitch?
@John_C
Hey John-
I think the problem may be that you need to do something like DataWorkspace.<YourDataSourceName>.<YourDataSourceEntityName>
So like DataWorkspace.NorthwindData.Products.AddNew()
Let me know if that helps.
-Matt S
thanks it works. :)
How can we view this data we imported? view and export?
Now that you have shown how to save files, how about exporting the files back on desired location. by selection so if some one has dozens to export it would be easy to do, just for more then one file example.
hi, I posted a comment here about exporting files back to file system.
Maybe you haven't checked on comments yet but when you do.
let me : Bmuzammil@gmail.com
and relationship with person etc was also my comment.
thank you. I only know basics of C#, hardly even basics.
@Marvyn Cosep -
It's possible to do basic file I/O of the file itself to read the data out and write it to the desktop. Though you may not have access to save it to the desktop potentially unless you are running as a Silverlight Desktop application (not a web app).
If you want to read the contents of the file - I'd encourage you to look over the source code. There should be at least one place in there where we open up the file and read in the data. If that file were xml, for example, you could use an XmlReader to read in the data, parse it out, and store it in the necessary LightSwitch entities
This is awesome, but is there a VB version of this code out there?
hello, when i try to import file than more of 5 mb i got this error "An unexpected error occurred during communication with the server"
i have this
partial void Application_Initialize()
this.Details.ClientTimeout = 100000;
have you had this problem?
could you help me?
Thanks in Advance!