You are here:   Blog
Register   |  Login

Latest Microsoft LightSwitch Blogs

Note: This article applies to LightSwitch in Visual Studio 11 (LightSwitch V2) It’s common for developers to add static images and text to their screens to help guide their users through the application.  Although you can easily add images that come a database to your screens, up
Read more...

Matt Sampson has posted part 3 of a multi-part blog post this week that completes the walkthrough of creating an application around the popular public transit CommuterApi OData Service. This post focuses on creating a RIA Data Service
Read more...

Eric Erhardt has posted part 2 in his series on using stored procedures in LightSwitch. In the second part, he describes how you can use Visual Studio LightSwitch to update database records using stored procedures.  A lot of database administrators only allow modifications to data through
Read more...

The first release of Visual Studio LightSwitch (LightSwitch V1) allows users to define relationships between tables within the intrinsic/built-in data source (ApplicationData).  When attaching to existing data sources, LightSwitch will import the relationships defined within the data
Read more...

Eric Erhardt has posted part 1 of a series on using stored procedures in LightSwitch.  In the first part, he describes how you can execute a stored procedure when a user clicks a button on your LightSwitch screen. The blog post is here – Read more...

Jun 25

Written by: Michael Washington
6/25/2011 9:28 AM  RssIcon

image

This article describes how you can upload files using LightSwitch, and store them on the server hard drive. This is different from uploading files and storing them in the server database.

If you want to upload files and store them in the database, see How Do I: Import and Store a Data File by Matt Sampson.

image

The sample application contains an Upload File button.

image

This opens a file upload popup (this uses code from the Matt Sampson article).

 

image

After uploading the file, the file shows up in the File Records list.

 

image

Clicking on a file, then clicking the Download File button, will download the file.

image

Note: This example only works when the LightSwitch application is configured as a Web Application.

image

In the Visual Studio Solution Explorer, when we switch to File View

image

We can see files were added to the ServerGenerated project, that provides the upload and download functionality.

image

If we unload the project…

image

…and edit the project file…

image

…we see the entries that were added to include the files in the project. Without doing this, the .ascx and .ashx files that were added would not be in the deployed project and the program would not work.

Note however, that any .cs code files are automatically compiled into assemblies and deployed. There is no need to reference them in the project file.

image

Don’t forget to reload the project! Smile

image

When we publish the project…

image

The upload and download files are also deployed.

 

The Screen

image

To explore the code, let us first start with the Screen.

Displaying Files (WCF RIA Service)

image

To display the files that have been uploaded, we use a simple WCF RIA Service. See this article: Creating a Simple LightSwitch RIA Service (using POCO) for directions on creating a WCF RIA Service and consuming it in a LightSwitch application.

This code is used in the WCF RIA Service:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.ComponentModel.DataAnnotations;
    using System.Linq;
    using System.ServiceModel.DomainServices.Hosting;
    using System.ServiceModel.DomainServices.Server;
    using System.IO;
    using System.Web.Hosting;
    // TODO: Create methods containing your application logic.
    // TODO: add the EnableClientAccessAttribute to this class to expose this DomainService to clients.
    public class FileDomainService : DomainService
    {
        [Query(IsDefault = true)]
        public IQueryable<FileRecord> GetFileRecords()
        {
            return _LocalFiles.AsQueryable();
        }
        private readonly List<FileRecord> _LocalFiles;
        public FileDomainService()
        {
            _LocalFiles = new List<FileRecord>();
            string strFileDirectory= HostingEnvironment.MapPath(@"~\");
            // Find instance of "bin"
            int intPositionOfBin = strFileDirectory.ToLower().IndexOf("bin");
            if (intPositionOfBin > -1)
            {
                strFileDirectory = strFileDirectory.Substring(0, intPositionOfBin);
            }
            strFileDirectory = strFileDirectory + @"Files\";
            EnsureDirectory(new System.IO.DirectoryInfo(strFileDirectory));
            // Add all directories at this directory.
            DirectoryInfo objDirectoryInfo = new DirectoryInfo(strFileDirectory);
            string FolderName = objDirectoryInfo.Name;
           
            // Get the files in the directory
            foreach (var fi in objDirectoryInfo.EnumerateFiles().OrderBy(x => x.Name))
            {
                FileRecord objFileRecord = new FileRecord();
                objFileRecord.FileName = fi.Name;
                // Add file to the collection
                _LocalFiles.Add(objFileRecord);
            }
        }
        #region EnsureDirectory
        public static void EnsureDirectory(System.IO.DirectoryInfo oDirInfo)
        {
            if (oDirInfo.Parent != null)
                EnsureDirectory(oDirInfo.Parent);
            if (!oDirInfo.Exists)
            {
                oDirInfo.Create();
            }
        }
        #endregion
    }
    public class FileRecord
    {
        [Key]
        public string FileName { get; set; }
    }

 

image

Also, note the References that the project requires.

Uploading Files

image

We right-click on the Upload File button and select Edit Execute Code.

We use the .xaml popup, and code from the Matt Sampson article:

        /// from: http://blogs.msdn.com/b/rmattsampson/archive/2011/05/23/how-to-import-and-store-a-data-file.aspx
        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();
            });
        }

 

The following method is called when the window is closed:

 

        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.FileInfoFile != null))
            {
                Dispatchers.Main.BeginInvoke(() =>
                {
                    UploadFile(selectFileWindow.FileInfoFile);
                });
            }
        }

 

This code determines where the .ashx upload file handler is and starts the upload:

 

        #region UploadFile
        private void UploadFile(FileInfo SelectedFile)
        {
            // If there is a file upload it
            if (SelectedFile != null)
            {
                // Get the upload URL
                string strURLWithSelectedFolder = string.Format("{0}{1}", GetBaseAddress(), "FileUpload.ashx");
                Uri uri = new Uri(strURLWithSelectedFolder, UriKind.Absolute);
                UploadUrl = uri;
                // Create an FileUpload object
                SimpleMVVMFileUpload.FileUpload upload = 
                    new SimpleMVVMFileUpload.FileUpload(this.DataWorkspace.Details.Dispatcher, UploadUrl, SelectedFile);
                upload.ChunkSize = 4194304;
                // Wire up handles for status changed and upload percentage
                // These will be updating the properties that the ViewModel exposes
                upload.StatusChanged += new EventHandler(upload_StatusChanged);
                upload.UploadProgressChanged += 
                    new SimpleMVVMFileUpload.ProgressChangedEvent(upload_UploadProgressChanged);
                // Start the Upload
                upload.Upload();
            }
        }
        #endregion

 

(note: for a full explanation of the file upload code, see this article: Silverlight View Model Style File Manager Drag and Drop Upload)

 

When the file has completed uploading, the file list is refreshed:

 

        #region upload_StatusChanged
        void upload_StatusChanged(object sender, EventArgs e)
        {
            SimpleMVVMFileUpload.FileUpload fu = sender as SimpleMVVMFileUpload.FileUpload;
            // Is upload complete?
            if (fu.Status == SimpleMVVMFileUpload.FileUploadStatus.Complete)
            {
                this.FileRecords.Refresh();
            }
        }
        #endregion

 

Downloading Files

image

 

For downloading files, we first look at the CanExecute code that disables the button if no file is selected:

 

        #region DownloadFile_CanExecute
        partial void DownloadFile_CanExecute(ref bool result)
        {
            // Do not allow download if no file selected
            result = (this.FileRecords.SelectedItem != null);
        }
        #endregion

 

image

 

Next, we look at the Execute code simply calls Download.aspx file, passing the name of the file to download:

 

        #region DownloadFile_Execute
        partial void DownloadFile_Execute()
        {
            Dispatchers.Main.Invoke(() =>
            {
                HtmlPage.Window.Navigate(new Uri(string.Format("{0}",
                    String.Format(@"DownloadFile.aspx?FileName={0}",
                    this.FileRecords.SelectedItem.FileName)), UriKind.Relative), "_new");
            });
        } 
        #endregion

 

The following is the code for DownloadFile.aspx:

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.IO;
namespace LightSwitchApplication.FileManager
{
    public partial class DownloadFile : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            // Get parameters
            string FileName = Request.QueryString["FileName"];
            // All parameters must have a value or return nothing
            if (
                FileName != ""
                )
            {
                try
                {
                    string path = MapPath(@"~\");               
                    // Find instance of "bin"
                    int intPositionOfBin = path.ToLower().IndexOf("bin");
                    if (intPositionOfBin > -1)
                    {
                        path = path.Substring(0, intPositionOfBin);
                    }
                    path = path + @"Files\";
                    // Remove any .. to prevent backing up directories
                    FileName = FileName.Replace("..", ""); 
                    string strPath = Path.Combine(path, FileName);
                    // Return the file
                    Response.ClearHeaders();
                    Response.AddHeader("content-disposition", string.Format("attachment; filename={0}", FileName));
                    Response.ClearContent();
                    Response.ContentEncoding = System.Text.Encoding.UTF8;
                    Response.ContentType = GetContentType(strPath);
                    FileStream sourceFile = new FileStream(strPath, FileMode.Open);
                    long FileSize;
                    FileSize = sourceFile.Length;
                    byte[] getContent = new byte[(int)FileSize];
                    sourceFile.Read(getContent, 0, (int)sourceFile.Length);
                    sourceFile.Close();
                    Response.BinaryWrite(getContent);
                    Response.Flush();
                    Response.Close();
                }
                catch (Exception ex)
                {
                    lblDisplayFilesError.Text = ex.Message;
                }
            }
        }
        #region GetContentType
        public string GetContentType(string strextension)
        {
            string contentType;
            switch (strextension.ToLower())
            {
                case ".gif":
                    contentType = "image/gif";
                    break;
                case ".jpg":
                case ".jpeg":
                    contentType = "image/jpeg";
                    break;
                case ".png":
                    contentType = "image/png";
                    break;
                case ".doc":
                    contentType = "application/ms-word";
                    break;
                case ".docx":
                    contentType = "application/vnd.ms-word.document.12";
                    break;
                case ".pdf":
                    contentType = "application/pdf";
                    break;
                case ".xls":
                    contentType = "application/vnd.ms-excel";
                    break;
                case ".ppt":
                    contentType = "application/vnd.ms-powerpoint";
                    break;
                case ".zip":
                    contentType = "application/zip";
                    break;
                case ".txt":
                    contentType = "text/plain";
                    break;
                default:
                    contentType = "application/octet-stream";
                    break;
            }
            return contentType;
        }
        #endregion
    }
}

 

 

Download Code

 

The LightSwitch project is available at http://lightswitchhelpwebsite.com/Downloads.aspx

(note: When you deploy the application, you must give permission to the web server process to access the files on the file system)

24 comment(s) so far...


Gravatar

Re: Saving Files To File System With LightSwitch (Uploading Files)

This was helpful

By Visitor on   7/12/2011 3:16 PM
Gravatar

Re: Saving Files To File System With LightSwitch (Uploading Files)

This is nice.

But how do you do it with a "Out of browser" app?

This should be easier (or?)

Regards
Sven

By Sven on   8/4/2011 4:15 AM
Gravatar

Re: Saving Files To File System With LightSwitch (Uploading Files)

@Sven Sorry I don't have any examples

By Michael Washington on   8/4/2011 4:15 AM
Gravatar

Re: Saving Files To File System With LightSwitch (Uploading Files)

Does the project have to be setup with C# or VB ?

By David on   8/18/2011 8:28 PM
Gravatar

Re: Saving Files To File System With LightSwitch (Uploading Files)

Good Example.
Would you know of an example of uploading multiple files into database ?

By Kris on   9/8/2011 3:12 PM
Gravatar

Re: Saving Files To File System With LightSwitch (Uploading Files)

@Kris - See the link How Do I: Import and Store a Data File by Matt Sampson in the article.

By Michael Washington on   9/8/2011 3:13 PM
Gravatar

Re: Saving Files To File System With LightSwitch (Uploading Files)

Yes - Thats an excellent article from Matt. Although I believe that is one file at a time. What i would like to do is select many in the dialog and import them using FileInfo[] async.
I will keep digging around though. Thanks Michael

By Kris on   9/9/2011 4:15 AM
Gravatar

Re: Saving Files To File System With LightSwitch (Uploading Files)

Nice example, working great. I have a question about the downloading part.

Is it possible to calling the DownloadFile.aspx with an id and then fetching a binary from the database and downloading this binary the same way. How do you reference the database serverside?

By Fred on   9/9/2011 5:59 AM
Gravatar

Re: Saving Files To File System With LightSwitch (Uploading Files)

@Fred - It may be possible but I have no examples.

By Michael Washington on   9/9/2011 7:18 AM
Gravatar

Re: Saving Files To File System With LightSwitch (Uploading Files)

thanks for the sample, I'm about to play with this but curious... when adding this to an existing project do I manually add those files and directories to the ServerGenerated project and edit the project file to include the .ascx and .ashx files?

By nwillis on   9/22/2011 2:40 PM
Gravatar

Re: Saving Files To File System With LightSwitch (Uploading Files)

@nwillis - Yes you manually add the files.

By Michael Washington on   9/22/2011 2:52 PM
Gravatar

Re: Saving Files To File System With LightSwitch (Uploading Files)

thanks for the reply. I was curious, is there any way to access the files uploaded from outside the lightswitch application. Maybe via url link?

By nwillis on   9/22/2011 4:28 PM
Gravatar

Re: Saving Files To File System With LightSwitch (Uploading Files)

@nwillis - Yes but I have no code samples.

By Michael Washington on   9/22/2011 5:32 PM
Gravatar

Re: Saving Files To File System With LightSwitch (Uploading Files)

the sample project works as is in debug mode but I cannot connect to the RIA service after I publish it: "Unable to load data. Please check your network connections and try loading again"
in the publish menu there's nothing specified for the FileDomainServiceData connection. Do I need to enter some kind of connection string for it to work after getting published?
THANKS

By nwillis on   9/26/2011 3:37 PM
Gravatar

Re: Saving Files To File System With LightSwitch (Uploading Files)

@nwillis - Please post any questions to the forums. This Blog comments section is a hard place to have a discussion.

By Michael Washington on   9/26/2011 3:45 PM
Gravatar

Re: Saving Files To File System With LightSwitch (Uploading Files)

Trying to use this in a project. Getting " 'SimpleMVVMFileUpload.FileUpload' is not defined " in the screen code.

Must be missing something -- Any thoughts?

I added the files and the build section in the properties file of the project. Otherwise everything is compiling.

By DA GAMER on   12/18/2011 3:08 PM
Gravatar

Re: Saving Files To File System With LightSwitch (Uploading Files)

@DA GAMER - Post any questions to the forums on this site.

By Michael Washington on   12/18/2011 3:22 PM
Gravatar

Re: Saving Files To File System With LightSwitch (Uploading Files)

is it possible to save files to hard drive with wcf ria service ?

By Şükrü Tulga on   2/15/2012 5:17 AM
Gravatar

Re: Saving Files To File System With LightSwitch (Uploading Files)

@Şükrü Tulga - Yes but I have no examples.

By Michael Washington on   2/15/2012 5:17 AM
Gravatar

Re: Saving Files To File System With LightSwitch (Uploading Files)

When we try to upload files of 3MB size we obtain exceptions. Can I solve this problem?

By acampo on   2/16/2012 4:03 AM
Gravatar

Re: Saving Files To File System With LightSwitch (Uploading Files)

Hi Michael,

how can I put a new Button on this "SelectFileDialog" which allows to add new data (one or many rows) in my LightSwitch Business Screen?

By John_C on   4/23/2012 5:07 AM
Gravatar

Re: Saving Files To File System With LightSwitch (Uploading Files)

Hi Michael,

how can I put a new Button on this "SelectFileDialog" which allows to add new data (one or many rows) in my LightSwitch Business Screen?

By John_C on   4/26/2012 8:04 PM
Gravatar

Re: Saving Files To File System With LightSwitch (Uploading Files)

do you have a tutorial about on how to delete files on the file menu of the wcf?

By babykian on   4/26/2012 7:39 PM
Gravatar

Re: Saving Files To File System With LightSwitch (Uploading Files)

@babykian - See http://lightswitchhelpwebsite.com/Blog/tabid/61/EntryId/86/Help-Desk-An-Advanced-Visual-Studio-LightSwitch-Application.aspx for an example of deleting files

By Michael Washington on   4/26/2012 8:05 PM

Your name:
Gravatar Preview
Your email:
(Optional) Email used only to show Gravatar.
Your website:
Title:
Comment:
Security Code
CAPTCHA image
Enter the code shown above in the box below
Add Comment   Cancel 

Microsoft Visual Studio is a registered trademark of Microsoft Corporation / LightSwitch is a registered trademark of Microsoft Corporation