How Do I: Import Data While Running a LightSwitch Web Application


Importing data into a Microsoft Visual Studio LightSwitch application can be a bit tricky, especially if we are talking about a LightSwitch web application.  Since I’ve heard several people ask how to import data using a web application, I figured now would be a good time to blog about this.

I’m going to teach you some tips and tricks on importing data into a web application. It can get tricky in this scenario because web applications typically have additional security issues you need to deal with.  But I think you’ll find once we are done, that there is very little code, and it’s easy to understand.

Overview

Some other LightSwitch people have already blogged about importing data into a LightSwitch application (e.g. Dan Seefeldt and the LightSwitch team).  These are some awesome posts for the basics of importing and exporting.  But for our slightly more specialized scenario we want to:

  1. Create a web application
  2. Let the user select a comma separate file (e.g. *.csv) to import
  3. Populate our LightSwitch data with data from the comma separated file

The real issue we need to work around is the fact that we have a web application and NOT a desktop application.  Because of that we are going to have to do a couple of extra steps to make this work.

Let’s get started!

Create a Simple Web Application

Because I’m lazy, we are going to make another application to manage “Contacts” for this example (like we did for the last blog post).

  1. Launch Microsoft Visual Studio LightSwitch
  2. Create a new C# Project (I’ll include some VB.NET code for VB fans at the end of this blog)
  3. Call the project “ImportDataFromAWebApp”
  4. In the Solution Explorer, right click the “Properties” icon and select “Open”:
    1. image
  5. In the Properties window that opens, select the “Application Type” tab, and pick “Web” to switch from a Desktop application to a Web application for this project
    1. Note – Our code will also work in a Desktop application as well

Add the Table

  1. In the Solution Explorer, right click the Data Sources node and select “Add Table”
  2. Name the table “Contact” and populate it with the following fields (formatted like [Field Name | Data Type | Required]):
    1. FirstName | String | Required
    2. MiddleName | String |
    3. LastName | String | Required
    4. AddressLine1 | String |
    5. AddressLine2 | String |
    6. City | String |
    7. State | String |
    8. ZipCode | String |
    9. Country | String |
    10. PhoneNumber1 | Phone Number |
    11. PhoneNumber2 | Phone Number |
    12. BirthDate | Date |
    13. MiscellaneousInformation | String |
  3. The table should look something like this when we are done:
  4. image

Add the Screen

  1. In the Solution Explorer, right click the Screens node and select “Add Screen…”
  2. Pick the “Editable Grid Screen” template
  3. For the Screen Data – select the table we just created “Contact”
  4. Accept the defaulted screen name (should be “EditableContactsGrid”)
  5. Click “OK”
  6. In the Screen Designer, navigate to “Rows Layout –> Data Grid –> Command Bar” and add a button under the Command Bar.
  7. Call the button method name “ImportData”
  8. You should now have a screen that looks something like this:
  9. image 
  10. Right click the “Import Data” button and select “Edit Execute Code” to generate the button method stub
    1. Doing this will generate the “User Code” folder for us that we’d like to have for our next steps. 
    2. We’ll add code to this button method later on.

Add a Simple Silverlight dialog

Now comes the unusual part of this example.  We are going to add our own Silverlight dialog to our LightSwitch application.  The “Import Data” button is going to invoke this Silverlight dialog. (I am not the first to go adding Silverlight dialogs to a LightSwitch application – see Eric Erhardt’s blog post on this.)

I used Visual Studio Ultimate to make my own very simple Silverlight dialog which we are going to import into our Visual Studio LightSwitch project.  The Silverlight dialog contains 4 controls:

  1. A “Browse” button which will open up a “OpenFileDialog” window and allow the user to select a .csv file
  2. An “OK” button to accept the file you selected
  3. A “Cancel” button to abort
  4. And a text control that displays the name of the file you selected

Let’s add the dialog now, and then I’ll give the technical reasons for why we are doing it this way.

  1. In Solution Explorer, click the drop down arrow on the “Logical View” button and select “File View”
    1. image
  2. In Solution Explorer, navigate to “Client –> UserCode”
  3. Right click the “UserCode” folder and select “Add –> New Item…”
    1. image
  4. Select  “Text File” in the “Add New Item” dialog.  Call the file “SelectFileWindow.xaml”.
  5. Now copy and paste the below code into the “SelectFileWindow.xaml” file (you may need to open up the .xaml file with Notepad to add this code):
    <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>
  6. This Silverlight xaml code contains the metadata information for the dialog, and for the 4 controls we discussed earlier.
  7. We need to do another step to add some code for the Silverlight control, so let’s add another file.
  8. Right click the “UserCode” folder and select “Add –> Class”
  9. Name the class “SelectFileWindow.cs” and copy the below code into the class:
    //' 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; }
    
            }
    
    
    
            /// <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();
    
                // Limit the dialog to only show ".csv" files,
    
                // modify this as necessary to allow other file types
    
                openFileDialog.Filter = "csv files (*.csv)|*.csv";
    
                openFileDialog.FilterIndex = 1;
    
    
    
                if (openFileDialog.ShowDialog() == true)
    
                {
    
                    this.FileTextBox.Text = openFileDialog.File.Name;
    
                    this.FileTextBox.IsReadOnly = true;
    
                    System.IO.FileStream myStream = openFileDialog.File.OpenRead();
    
                    documentStream = myStream;
    
                }
    
            }
    
        }
    
    }
    
    
    
    
    
  10. This partial class for our “SelectFileWindow” Silverlight dialog contains a few basic things:
    1. The methods for our button controls
    2. The Browse button has code in it to create a System.Windows.Controls.OpenFileDialog object which we use to open up our Open File Dialog to allow the user to select a .csv file.  Once we open the file we store the file’s data into a FileStream property on our SelectFileWindow class.
    3. A public FileStream property called DocumentStream that contains the data for the .csv file we want to import
  11. We need to add a reference to the Silverlight dll we are using, so in Solution Explorer, navigate to “Client –> References”, right click and select “Add Reference…”
  12. Add a .NET reference to the System.Windows.Controls assembly

Add a Simple Class to Parse the .CSV File

For the sake of modularity and encapsulation we will create a separate class to handle the parsing of the .csv file.

  1. Add a new User Code class – in Solution Explorer, right click the “Client->UserCode” folder, and select “Add –> Class”.
  2. Name the class “ImportDataFile.cs” and add the below code:
    //' 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;
    
    
    
    namespace LightSwitchApplication.UserCode
    
    {
    
        public class ImportDataFile
    
        {
    
            /// <summary>
    
            /// Import data from a comma delimited stream
    
            /// And using the workspace that was passed in, insert the imported data
    
            /// so it displays on the user's screen
    
            /// </summary>
    
            static public void ImportCommaDelimitedStream(FileStream fileStream, DataWorkspace dataWorkspace)
    
            {
    
                List<string[]> parsedData = new List<string[]>();
    
    
    
                using (StreamReader streamReader = new StreamReader(fileStream))
    
                {
    
                    string line;
    
                    string[] row;
    
    
    
                    while ((line = streamReader.ReadLine()) != null)
    
                    {
    
                        row = line.Split(',');
    
                        parsedData.Add(row);
    
                    }
    
                }
    
                AddData(parsedData, dataWorkspace);
    
            }
    
    
    
            /// <summary>
    
            /// Take in a list of string arrays which contains
    
            /// all the parsed data for our Contacts entity
    
            /// </summary>
    
            static private void AddData(List<string[]> dataList, DataWorkspace dataWorkspace)
    
            {
    
                foreach (string[] row in dataList)
    
                {
    
                    Contact contact = dataWorkspace.ApplicationData.Contacts.AddNew();
    
    
    
                    contact.FirstName = row[0];
    
                    contact.MiddleName = row[1];
    
                    contact.LastName = row[2];
    
                    contact.AddressLine1 = row[3];
    
                    contact.AddressLine2 = row[4];
    
                    contact.City = row[5];
    
                    contact.State = row[6];
    
                    contact.ZipCode = row[7];
    
                    contact.Country = row[8];
    
                    contact.PhoneNumber1 = row[9];
    
                    contact.PhoneNumber2 = row[10];
    
                    contact.BirthDate = DateTime.Parse(row[11]);
    
                    contact.MiscellaneousInformation = row[12];
    
                }
    
            }
    
        }
    
    }
    
    
    
  3. This class contains two basic methods:
    1. The AddData() method which iterates over a List of string arrays, and creates a new Contact in our DataWorkspace for each string array.
  4. The ImportCommaDelimitedStream() method takes in a FileStream object (our .csv file, which we can get off our SelectFileWindow class that we just made), and a DataWorkspace object.  The method reads the lines in the FileStream object, parses off each “comma”, stores each line in a string array and then invokes the AddData() method.

Add Import Data Button Code

Let’s do the final bit of coding now by adding the code to our “Import Data” button.

  1. To get to our button, switch the back to “Logical View”
    1. image
  2. Open up the Screen Designer for the EditableContactsGrid screen
  3. Navigate to the Import Data button, right click and select “Edit Execute Code”
    1. We should now be in the EditableContactsGrid partial class
  4. We need a “using” statement for our Client UserCode that we added, so add the following using statement to this class: “using LightSwitchApplication.UserCode”
  5. We also need another using statement so we can reference the “Dispatchers” class, so add the following using statement to this class as well: “using Microsoft.LightSwitch.Threading”
  6. Paste the following code into your ImportData_Execute() button method
            /// <summary>
    
            /// Import Data button method
    
            /// </summary>
    
            partial void ImportData_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))
    
                {
    
                    ImportDataFile.ImportCommaDelimitedStream(selectFileWindow.DocumentStream, this.DataWorkspace);
    
                    selectFileWindow.DocumentStream.Close();
    
                }
    
            }

Here’s what’s going on at a high level when the Import Data button is clicked:

  1.  
    1. The button is clicked
    2. An instance of our Silverlight dialog, SelectFileWindow, is created
    3. The dialog is opened by calling the Show() method
    4. An EventHandler is added to the SelectFileWindow Closed event so that the “selectFileWindow_Closed()” method is invoked after the dialog is closed

Optional Reading – Here is a lower level explanation of what is going on in this button method:

Technical Stuff: Since the Import Data button code does NOT by default run inside the Main UI thread, we have to invoke the “Main” thread (or Dispatcher) before calling our Silverlight dialog. That is the reason for wrapping this code inside the Dispatchers.Main.BeginInvoke() method.

So why can’t we just open the OpenFileDialog directly? Why do we have to open a Silverlight dialog which then launches an OpenFileDialog?

Well, this is really what makes the web application scenario different from the Desktop application. If you try to directly launch the OpenFileDialog you will get a “Dialogs must be user-initiated” error message. This is because Silverlight dialogs (like OpenFileDialog) can only be opened from “user actions”, like a button clicked event handler. The reason why this won’t work with LightSwitch is because we invoke the button logic asynchronously, so the Import Data button code is not considered to be “user-initiated”.

Run That Thing!

  1. In Solution Explorer, right click the ImportDataFromAWebApp project, and select “Build”.
  2. After the build, press F5 to run your project
  3. You should see inside the Editable Contacts Grid screen’s command bar an “Import Data” button:
  4. image
  5. Click the button, and you should see the SelectFileWindow Silverlight dialog we created
  6. image
  7. Click the “Browse” button inside our SelectFileWindow dialog to open up the OpenFileDialog
  8. Select a .csv file to import (I have one at the end of this blog which can be used)
  9. Click “OK” to import the data
  10. You should now see your data displayed inside your workspace

The C# and VB.NET code is available on MSDN Code Gallery here: http://code.msdn.microsoft.com/Visual-Studio-LightSwitch-1f8aa17e

Let me know if you have questions.  Enjoy!

Matt Sampson –Martini glass

Comments (35)

  1. gregid says:

    Thanks for the sample Matt, just one suggestion – the title of your article is very misleading, my suggestion:

    How do I: Import data (from CSV file) while in browser

  2. Matt Sampson says:

    @Gregid

    Thanks Greg.

    I always thought it could use some improvement.

    I took your suggestion and slightly modified it.

  3. how do i:import dbf file

  4. Hi Matt,

    Thanks for an awesome post. I was wondering how can one extend this import routine to incorporate data import from csv file to related (multiple) tables in at a time.

    Cheers.

    KD

  5. This is great article. I try to use OpenFileDialog or SaveFileDialog in Web mode and always hava a problem with "Dialogs must be user-initiated".

    Select File Dialog is solution to that problem.

    Thanks a lot

    Spaso Lazarevic

  6. Juan Carlos says:

    Thanks Matt: very useful article!

    Could you post a complementary example of how to retrieve the file stored in the database, save it to a local folder, and eventually invoking an external application (i.a.e.: mspaint.exe) to open it?

  7. John_C says:

    Hi everybody,

    nice sample Matt!

    I have a question for a special Screen. I have a Customer Listdetail Screnn with all Customers and their Orders (orders are included in to the screen). What I need now is to add a new Customer through this screen and for example 20 new orders for him through the same screen. Is something like that possible?

  8. Matt Sampson says:

    @John_C – Hey John_C I'm not sure about that one.  But I think you might want to try making your own template – msdn.microsoft.com/…/hh304432.aspx . And then that could be your "New screen"

  9. John_C says:

    Thanks Matt, through your hint I am founding the solution for my problem. It was the AddNew and ShowCreatNew method which I was looking for.

  10. Andrew says:

    Hi Matt,

    I want to use your class file method "AddData" to import data into a ListDetail Screen. Problem is that I couldn't access this screen. Where you define for a editable Screen the following code. "Contact contact = dataWorkspace.ApplicationData.Contacts.AddNew();. " And that what I need is something like that: Contact contact = dataWorkspace.ApplicationData.ContactListDetail.AddNew();. Do you have any idea how I can solve this problem?

    thx.

  11. Matt Sampson says:

    @Andrew- I may not be answering your question here, but I think what you might want to do is just "AddNew" like I have in my code and then invoke the "Refresh()" functionality on the screen to make sure it refreshes (see this blog post on invoking refresh – blogs.msdn.com/…/odata-apps-in-lightswitch-part-2.aspx).

    You can access the screen from this code just by doing "ScreenName.whatever" for example.

  12. Andrew says:

    Hi Matt,

    thanks for the quick answere. But that is not what I want :). What I have is a screen like that:

    http://www.silverlightshow.net/…/image_e33de2b2-814e-4307-a62a-840bdd62b96a.png

    (here is a Movie table and a showtime table in a Master detail Screen)

    And what I want is to add at the same time Data in both tables. For example for each Movie I want to add 10 showtimes. I hope my problem is now a littel bit clear :).

  13. Matt Sampson says:

    @Andrew –

    Thanks for the screenshot.

    So there's maybe a couple different ways to do this.

    I made a List and Details screen around Northwind Customer and the "Details" portion is the Orders entity

    So each customer can have 1 or more Orders.

    So I made a button on the Screen called "Method" and put the below code into it:

           partial void Method_Execute()

           {

               Customer myCust = this.Customers.AddNew();

               myCust.CustomerID = "ROCK2";

               myCust.CompanyName = "ROCK COMPANY";

               Order myOrder1 = this.Orders.AddNew();

               myOrder1.OrderDate = DateTime.Now;

               Order myOrder2 = this.Orders.AddNew();

               myOrder2.OrderDate = DateTime.Now;

               myCust.Orders.Add(myOrder1);

               myCust.Orders.Add(myOrder1);

               this.Save();

           }

    When the button is clicked it creates 1 Customer, 2 Orders, and relates the 2 orders to the created Customer. Then it saves it.

    This may not be exactly what you are wanting but hopefully it gets you on the right track.

  14. Andrew says:

    Hey thanks Matt for your quick answer. Your example works fine in the Customer class but when I use it in your "ImportDataFile.cs" again the method failed. From this "ImportDataFile.cs" I am only able to add from my csv file the Customer table with data, the Orders table don't get any notice.

  15. Matt Sampson says:

    @Andrew – if you share your code out with me I can see what's going on.  I think that's the best option at the moment here if you are comfortable with that.  Email it here – Raymond.M.Sampson@microsoft.com

    Thx,

    Matt

  16. Andrew says:

    Okay Matt,

    I'll sending you the code from my E-Mail adresse: Firefox*******@gmx.

    thanks alot for your help.

  17. Paul says:

    Hey Matt,

    how can i download all my imported files? i would like to make a web application that has download and upload function.

    I'm going to wait for your reply, I'm expecting that you have a solution with my problem 😀

    thanks Matt,

    Paul

  18. Matt Sampson says:

    @Paul – the best I got right now for you is this application to download and upload data from Michael Washington – lightswitchhelpwebsite.com/…/Saving-Files-To-File-System-With-LightSwitch-Uploading-Files.aspx

  19. Kim says:

    Can we apply this if there is a relationship to other entity like orders of something?

  20. An exception occurred during the operation, making the result invalid. Check InnerException for exception details. says:

    I receieve the "An exception occurred during the operation, making the result invalid. Check InnerException for exception details." when I deployed it to Windows 2008 R2 with IIS 7. Your code works perfectly fine on my local box but does not work when deployed on the server, rest of the website works perfectly fine

  21. Matt Sampson says:

    @LAST – Try taking a look at Eric Erhardt's blog – blogs.msdn.com/…/diagnosing-problems-in-a-deployed-lightswitch-application-eric-erhardt.aspx Diagnosing Problems in a Deployed 3-Tier LightSwitch Application

  22. anwaralhasan says:

    Thank you Matt  this is wonderful work … But can we develop the extension to more than one type? , such as video Formats WMV ? if you don't mind give me any idea please .

  23. Wyler says:

    One quick question if I may, if you try to import a csv and the Birthdate column is empty it will fail. Is there a way to import empty/null column's to date or integer fields?

  24. Matt Sampson says:

    @Wyler – I'd think you'd have to change the source code to do the necessary parsing to handle cases where the date is null.  If the date is null, then you will most likely have to create some dummy date value like – System.Data.SqlTypes.SqlDateTime.null – which will input a null date value in that instance.

    -Matt S

  25. Matt Sampson says:

    @anwar – Check out Michael Washington's blog –  lightswitchhelpwebsite.com/…/Saving-Files-To-File-System-With-LightSwitch-Uploading-Files.aspx, but yes I'd think you could just import a wmv file as well and still just read it in as a byte stream. My next blog may also help – blogs.msdn.com/…/how-to-import-and-store-a-data-file.aspx

    Thanks – Matt

  26. roblew says:

    Hi Matt

    Great Example, but I get a threading error when trying to add something to a relationship.

    Do you have any examples of how to do this

    Thanks

  27. Matt Sampson says:

    @Roblew – can you give me some detail on this (error message, call stack, code or some more repro steps)?  Also any chance you can repro this in a more isolated environment (without any of my blog's code incorporated into your app)?

    Thx – Matt S

  28. roblew says:

    hi matt

    I've done it another way now to make it work. I've imported it to a temporary table and then run the import off another button. A bit overkill but it works.

    What I was trying to do is shown in my code below:

    static private void AddData(List<string[]> dataList, DataWorkspace dataWorkspace)

           {

                   foreach (string[] row in dataList)

                   {

                       Person person = dataWorkspace.SchoolsSystemData.People.AddNew();

                       person.UPN = row[0];

                       person.Forename = row[1];

                       person.Surname = row[2];

                       person.DateOfBirth = Convert.ToDateTime(row[3]);  

    int schoolId = Convert.ToInt32(row[4]);

    // *** crashes on next line when trying to get the school  ***

    // error message —  It is not valid to execute the operation on the current thread

    // *** school is related to a school table

                       School importSchool = dataWorkspace.SchoolsSystemData.Schools.Where(w => w.Id == schoolId).FirstOrDefault();

                       person.School = importSchool;                    

                       person.RegistrationGroup = row[5];

                       bool isFreeMeal = Boolean.Parse(row[6]);

                       person.FreeMealEntitlement = isFreeMeal;

                       bool isStaff = Boolean.Parse(row[7]);

                       person.IsStaff = isStaff;                

                   }

           }

    Would be great if it could be fixed.

    Thanks

    Rob

  29. I'm trying to use your example as a way to export rows into an Excel speadsheet.  I'm getting an error when I try to execute a query inside of the Dispatchers.Main.BeginInvoke.  I'm using the following code:

                   foreach (Project proj in dataWorkspace.ApplicationData.Projects)

                   {

                       sheet[++currRow, 0].Value = proj.ProjectCode + " " + proj.ProjectName;

                   }

    The complaint is:

    It is not valid to call Execute() on a different Dispatcher than the ExecutableObject's Logic Dispatcher.

    I'm new to LightSwitch as well as working with entities.

  30. Matt Sampson says:

    @PeterTrefren – Welcome to the LightSwitch worldz!!!

    There is of course already a way to "Export to Excel" and that is to use a LightSwitch "Desktop" Client (the out of browser client has a button to export to excel on it by default).

    But if you want a Web Client, then I would use the Open Office XML format – en.wikipedia.org/…/Office_Open_XML.  (In case you aren't already aware of it).

    As for your error – you can't do this type of code execution inside this dispatcher.  You have to do it in the Logic Dispatcher – see this thread for more information – social.msdn.microsoft.com/…/it-is-not-valid-to-call-execute-on-a-different-dispatcher-than-the-executableobjects-logic

    You may want to basically have some button on your app that generates the "Excel" document, and then stores it in a table. And then a separate button to export that Excel document to your desktop.

  31. Ruben says:

    THX MAte, it helped me a lot, i'm new to lightswitch and this was sent from heaven…

  32. Matt Sampson says:

    @Ruben – well ain't that just the coolest thing to hear? Glad it helped! – Matt Sampson

  33. Eric says:

    What would the newer Lightswitch HTML5 way to do the import without using Silverlight?   Obviously the file selection screen would have to change, but would it still function?

  34. Nick says:

    Hi I am new to Lightswitch development, and I am getting the error "Cannot create an instance of 'ChildWindow'."  I have tried trouble shooting this and searched for issues like mine, but none have resolved th error.  I could not post everything here (character limits), but I have posted the issue on StackOverFlow here:

    stackoverflow.com/…/custom-window-to-invoke-openfiledialog-in-lightswitch-error-cannot-create-an-i