• Beth Massi - Sharing the goodness

    Deployment Guide: How to Configure a Machine to Host a 3-tier LightSwitch Beta 1 Application

    • 16 Comments

    NOTE: This information applies to LightSwitch Beta 1 ONLY. For Beta 2, please read the Beta 2 Deployment Guide

    A lot of people have been asking in the forums about how to deploy a LightSwitch application and there are some really great tutorials out there like: Deploy and Update a LightSwitch (Beta 1) 3-tier Application

    There’s also a lot of information in the official documentation on Deployment:

    (UPDATE: We also released a video on 2 & 3-tier deployment: How Do I: Deploy a Visual Studio LightSwitch Application?)

    Deploying a LightSwitch application on the same machine as you develop on is pretty easy because all the prerequisites are installed for you with Visual Studio LightSwitch, including SQL Server Express. In this post I’d like to walk you through configuring a clean machine to host a 3-tier LightSwitch application that shouldn’t have the development environment installed.

    Before I begin please note: There is NO “go live” license for the LightSwitch Beta. You can deploy your LightSwitch applications to IIS for testing purposes ONLY.  Also currently the Beta only supports IIS 7 at this time. You can only use Windows 7 or Windows 2008 Server (not 2003) to test deployment for Beta 1 LightSwitch applications. As you read through this guide I’ll note in sections where the team is still fixing bugs or changing experiences for the final release (RTM). Please be aware that the deployment experience will be much easier and full-featured for RTM.

    In this post we will walk through details of configuring a web server first and then move onto deployment of a LightSwitch Beta 1 application. (BTW, a lot of this information should be useful even if you are creating other types of .NET web applications or services that connect to databases.)

    Configuring the server

    • Installing Beta 1 Prerequisites
    • Verifying IIS Settings and Features
    • Configuring Your Web Site for Network Access
    • Configuring an Application Pool and Test Site
    • Add User Accounts to the Database Server

    Deploying and testing your LightSwitch application

    • Publishing a LightSwitch Beta 1 Application
    • Installing the LightSwitch Application Package on the Server
    • Using Windows Integrated Security from the Web Application to the Database
    • Launching the LightSwitch Application

    So let’s get started!

    Installing LightSwitch Beta 1 Prerequisites

    You can use the Web Platform Installer to set up a Windows web server fast. It allows you to select IIS 7, the .NET Framework 4 and a whole bunch of other free applications and components, even PHP. All the LightSwitch prerequisites are there as well including SQL Server Express and the LightSwitch middle-tier framework. This makes it super easy to set up a machine with all the components you need.

    NOTE: The team is looking at simplifying this process and possibly making the LightSwitch server component pre-reqs go away so this process will likely change for RTM.

    To get started, on the Web Platform tab select the Customize link under Tools and check the Visual Studio LightSwitch Beta Server Prerequisites. This will install IIS 7, .NET Framework, SQL Server Express 2008 and SQL Server Management Studio for you so you DO NOT need to select these components again on the main screen.

    WebPI1  image

    If you already have one or more of these components installed then the installer will skip those. Here's the breakdown of the important dependencies that get installed:

    • .NET Framework 4
    • Middle-tier components for the LightSwitch runtime, for Beta 1 these are installed in the Global Assembly Cache (GAC)
    • IIS 7 with the correct features turned on like ASP.NET, Windows Authentication, Management Services
    • Web Deployment Tool 1.1 so you can deploy directly from the LightSwitch development environment to the server
    • SQL Server Express 2008 (engine & dependencies) and SQL Server Management Studio (for database administration)(Note: LightSwitch will also work with SQL Server 2008 R2 but you will need to install that manually if you want that version)
    • WCF RIA Services Toolkit (middle-tier relies on this)

    Click the "I Accept" button at the bottom of the screen and then you'll be prompted to create a SQL Server Express administrator password. Next the installer will download all the features and start installing them. Once the .NET Framework is installed you'll need to reboot the machine and then the installation will resume.

    Once you get to the SQL Server Management Studio 2008 setup you may get this compatibility message:

    sqlcompat

    If you do, then just click "Run Program" and after the install completes, install SQL Server 2008 Service Pack 1.

    Plan on about an hour to get everything downloaded (on a fast connection) and installed.

    In the next couple sections I'm going to take you on a tour of some important IIS settings, talk you through Application Pools & Identities and how to get a simple test page to show up on another networked computer. Feel free to skip to the end if you know all this already and just want to see how to actually package and deploy a LightSwitch application. :-)

    Verifying Your IIS Settings and Features

    Once IIS is installed you’ll need to make sure some features are enabled to support LightSwitch (or any .NET web application). If you installed the Visual Studio LightSwitch Beta Server Prerequisites to set up IIS then these features should already be enabled.

    In Windows 7 you can do this by going to “Add or Remove Programs” and selecting “Turn Windows features on or off”. On Windows Server 2008 you can do this through the Server Manager Roles Wizard. You will need to turn on IIS Management Service Role Services, Application Development Features: ASP.NET (this will automatically add additional services when you check it), and under Security: Windows Authentication.

    image 

    Configure Your Web Site for Network Access

    Now before moving on we should make sure we can browse to the default site. First you should be able to open a browser to http://localhost and see the IIS 7 logo. If that doesn’t happen something got hosed in your install and you should troubleshoot that in the IIS forums or the LightSwitch forums.

    Next we should test that other computers can access the default site. In order for other computers on the network to access IIS you will need to enable “World Wide Services (HTTP Traffic-In)” under Inbound Rules in your Windows Firewall:

    image

    At this point you should be able to navigate to http://<servername> from another computer on your network and see the IIS 7 logo. (Note: If you still can’t get it to work, try using the machine’s IP address instead of the name)

    image

    Configure an Application Pool and Test Site

    Next I want to talk a little bit about how application pools and Windows identities work. This will help you determine what is the best way for you to host any web application on a network. You don't actually have to know much about this stuff when deploying a LightSwitch application because the installation package will set up most of this for you. However, I think it's always a good thing to understand what's going on. If you don't care, you can skip this section :-)

    When you create a new website in IIS Manager you choose which application pool it should run under. By default the DefaultAppPool is selected. Application pools give you isolation between worker processes (so if one web application crashes it can’t take others with it) but they also allow you to run under different identities. This way you can create an application pool that hosts a web application or set of services that run under a specific Windows Identity and you can allow access only to the resources that identity needs to run the application. In the case of a LightSwitch application, that additional resource will be the database. If you are already on a Windows domain it’s best to create a least-privilege domain user and set that user as the identity of the application pool and grant access to that user to the database (which is probably on another machine, if so you’ll probably want to read this).

    For my simple test deployment, I am going to host the database on the same machine as IIS so I can use a local machine account. Open up the Local Users and Groups console and create a local user called LightSwitchApp. Then add this user to the IIS_IUSERS group. Next open up IIS Manager, right-click on Application Pools and select “Add Application Pool....” Type a name for your App Pool, I called mine LightSwitchAppPool and select the .NET Framework version 4 you just installed. Then click OK.

    image

    Next right-click on the LightSwitchAppPool and select Advanced Settings and change the Identity to the account you just created. (Once we install the LightSwitch application middle-tier components into a web application running in this pool, they will run under this identity to access resources.)

    image

    Before we move on let’s create a test application and make sure computers on our network can see a test page running under this pool. Create a folder C:\LightSwitchTest on the machine and create a Default.htm file (you can do this in notepad) and do something simple like:

    <html>
    <head>
    <title>Welcome</title>
    </head>
    <body>
    <H1>
    Welcome to My Site!
    </H1>
    </body>
    </html>
     

    Save the file. Now in order for another machine on your network to browse a web site on this machine three very important things have to happen.

    1. The firewall has to allow incoming HTTP requests
    2. The NTFS (file) permissions on the folder containing the application files need to grant access to the same user as the App Pool’s identity
    3. The Web application has to enable the right authentication for the type of access

    So for our case, we’re going to create a web application that runs in the LightSwitchAppPool and allow anonymous access to the site (anyone on the network has access). Anonymous access is the default authentication (or lack thereof) on the Default Web Site. You can see this in IIS Manager by selecting the Default Web Site node and double-clicking on the Authentication icon in the IIS section of the main window. For intranet-based business applications where all users are on a domain it's recommended that you use Windows Authentication so that users are automatically authenticated based on their Windows Credentials. We'll take a look at how to set up authentication and authorization security in a follow-up post. (UPDATE: Here's that follow up post on security.)

    So back to our test, the LightSwitchApp user account will need to be granted on C:\LightSwitchTest folder. Right-click on the folder and select Properties and on the Security tab grant Read & execute, List folder contents, and Read permissions.

    image

    Next we just need to create a new application back in IIS Manager by right-clicking on the Default Site and select “Add Application”. Specify the alias, in my case LightSwitchTest and then click “Select…” to select the LightSwitchAppPool we just created. Then enter the physical path C:\LightSwitchTest.

    image

    Click on “Test Settings…” and you should see that Pass-through authentication is working on the App Pool and the path is accessible. Now hit http://<servername>/LightSwitchTest from another machine and you should see your custom welcome page.

    image

     

    Add User Accounts to the Database Server

    Next we'll need to add a user name and password to our database server that the LightSwitch installation package will use to connect and create the application database.

    NOTE: Right now in Beta 1 when you install a LightSwitch application package onto the server it requires SQL Server authentication. This means a SQL Server user name/password is required instead of being able to specify a Windows login. The team is aware of this and has logged a bug. Once you deploy, you can change the application to use Windows Integrated security and I'll show you how to configure that below.

    So for now you need to enable SQL Server Authentication on your SQL Express database. You can do this by opening up SQL Server Management Studio. To connect, use .\SQLEXPRESS for the local server name and use Windows Authentication (make sure you are logged in under the same user account when you installed SQL Server Express) .

    Now you can right-click on the top database node in the Object Explorer on the left and select Properties. Select the Security page and choose "SQL Server and Windows Authentication mode". Click OK.

    db1

    Next you'll need to restart the SQL Server service so that it picks up the new authentication mode changes we made. Right-click on the top database node in the Object Explorer again and select "Restart".

    Now we need to add a couple users. Right-click on Security node in the Object Explorer and choose New –> Login. Enter the user name, then select "SQL Server authentication" and enter a password you want to use. Then uncheck the "Enforce password expiration" option. Select the Server Roles page and add the user to the dbcreator and public roles. (click image to enlarge)

    db2 

    Do the same thing (New –> Login), and browse for the LightSwitchApp Windows user account (our App Pool's identity) and leave Windows Authentication selected. Add this user to the same dbcreator and public roles.

    Publishing a LightSwitch Beta 1 Application

    Here is the official documentation on how to publish a LightSwitch application - How to: Deploy a LightSwitch Application. For this example, I'm going to show how to deploy a simple application that does not have any role-based security set up. I'll show how we can configure that in a later post.

    So back over on my LightSwitch development machine the first thing we need to do is specify the type of 3-tier deployment we want. In the case of my application, I want it to be a Windows Desktop client because I'm doing some COM automation with Office and I want to run outside of the browser. To specify this, from the menu select Project—> AppName Properties and then select the Application Type tab to choose the type of 3-tier deployment you want.

    pub1

    Next, from the main menu select Build –> Publish AppName to open the LightSwitch Publish Application Wizard. Verify the deployment is 3-tier and then click next to get past the Welcome page. In the Publish Output section you select whether you want to remotely publish to the server or just create a package on disk. If you have installed the Web Deployment Tool on your server (which is automatically installed if you installed the LightSwith Prerequisites above) then you can choose to deploy the application directly to your server by selecting “Remotely publish to a server now”. (UPDATE: To see how to remotely publish see this post.)

    NOTE: In Beta 1 you can only do remote publishing to a Windows 2008 server running IIS 7 at this time. The team has added support for IIS 6 and Windows 7 and will be available in the next refresh.

    For this example I'm going to show how to create and install the package manually so select "Create a package on disk" and then enter LightSwitchTest for the website name and specify a location to where you want the package created. Then click Next.

     

    On the next page you specify the Database Configuration details. You can either create a new database or specify a database that needs to be updated. This refers specifically to the intrinsic database that is maintained by every LightSwitch application and exists regardless of whether you create new tables or attach to an existing database for your data. For the first deployment of the application you are always going to want to select the New Database option as you won't have one created yet.  If you are publishing an update to an existing application then you would select Update Existing option.

    pub3

    NOTE: Currently Beta 1 cannot update an existing database. This is a known bug and will be fixed in the next refresh. For now you will need to update the database manually if you make any schema changes and want to publish the update.

    Next click Publish and this will create a .ZIP file package in the publish location you specified. Copy that application package over to your web server.

    Installing the LightSwitch Application Package on the Server

    Back on the web server, navigate to the C:\LightSwitchTest folder and delete the Default.htm file we created earlier for testing. Then open up IIS Manager and right-click on the Default Web Site and select Deploy –> Import Application.

    deploy1

    Browse to the .ZIP application package that we created then click Next, verify the virtual directory name and click Next. The contents of the package will be then be displayed.

    deploy2

    Click Next and enter the remaining database details – specifying .\SQLEXPRESS as the local SQL Express server name, and entering the SQL Server user name and password we created above.

    deploy3

    Click Next and this will kick off the installation that should be pretty quick. Once it completes you should be able to see your database in SQL Server Management Studio and all the web application files on disk.

    Using Windows Integrated Security from the Web Application to the Database

    Like I mentioned earlier, typically you want to set up Windows Integrated security between your web application and database. It's a lot easier this way because you don't have to worry about managing user names and passwords in a bunch of application connection strings. It also is a lot more secure -- right now our username and password to the database is being stored in clear text on the web application's Web.config.

    Since we've configured our LightSwitchAppPool to run under the LightSwitchApp user identity we created earlier, we can change the connection string in the Web.config to use integrated security and the middle-tier will connect to the database under this windows account instead. In IIS Manager right-click on the LightSwitchTest web application and select Explore to navigate to the physical folder. Open the Web.config in notepad and remove the uid and password and add Integrated Security=SSPI:

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
      <appSettings>  ... </appSettings>
      <connectionStrings>
        <add name="_IntrinsicData" connectionString="Data Source=.\SQLEXPRESS;Database=OMS;Integrated Security=SSPI;" />
      </connectionStrings>
      <system.web> ...

    Save the file. The last thing to do is add access to the application database (in my case I named it OMS). Open up SQL Server Management Studio again, expand the Security –> Logins node in the Object Explorer and double-click on the LightSwitchApp windows login account we added earlier. The Login properties are displayed. Select the User Mapping page and check off the application database to allow access then under the database role membership check db_owner and click OK:

    user

    NOTE: These steps should not be necessary at RTM once we are allowed to specify integrated security when installing a LightSwitch application package.

    Launching the LightSwitch Application

    Now for the fun part! Head over to a networked machine and navigate your favorite browser to the site http://<servername>/LightSwitchTest and you should see a "Install Silverlight" graphic on the page if you don't have Silverlight installed. Install it then refresh the page and you will see the install page for your application:

    image

    Click the big blue "Install…" button and after a few seconds the application will launch out of browser and an application icon will be placed on the desktop. Woo hoo!

    image

    Now we have a 3-tier out-of-browser LightSwitch application deployed and running smooth. In my next post on deployment I'll show how we can configure and enable IIS Authentication and LightSwitch Authorization security (UPDATE: Here's that follow up post on security). I’m also working on some How Do I videos so stay tuned. (UPDATE: Here are those videos - How Do I: Set up Security to Control User Access to Parts of a Visual Studio LightSwitch Application? & How Do I: Deploy a Visual Studio LightSwitch Application?

    Enjoy!

  • Beth Massi - Sharing the goodness

    Silicon Valley Code Camp Session Schedules are up!

    • 0 Comments

    All the session schedules are now posted on the Silicon Valley Code Camp web site. SVCC is one of the biggest there is spanning many different technologies – you don’t want to miss this FREE event on October 9th – 10th at Foothill College in Los Altos. We’ve got over 1400 people registered so far with 193 sessions – what are you waiting for!?

    This year I’ll be speaking on OData with Office & of course, some sessions on LightSwitch. Do me a favor and let me know if you’re coming by logging into the SVCC web site and then visiting my sessions page and selecting the “Will Attend” radio button under the session description.

    Introducing Visual Studio LightSwitch : 11:15 AM Saturday
    This beginner-level session will be fun. We’ll build a 3-tier Silverlight business application using LightSwitch from scratch and deploy it. I’m not sure what I’ll do with the hour I’ll have left :-)

    Visual Studio LightSwitch – Beyond the Basics : 1:45 PM Saturday
    This pro-developer session will focus on some more advanced features like how to create your own custom controls and data sources that can be used with LightSwitch.

    Creating and Consuming OData Services : 3:30 PM Saturday
    One of my favorite talks, I’ll introduce you to OData and how to create and consume WCF Data Services in Visual Studio. I’ll also show how Office & SharePoint play in the OData space, making it easy to create powerful BI solutions.

    See you there!

  • Beth Massi - Sharing the goodness

    New LightSwitch “How Do I” Videos Released Today

    • 7 Comments

    We just updated the Learn section of the LightSwitch Developer Center with a couple more videos, check them out:

    The team also has a couple blog posts on these topics if you like articles better than videos:

    How to: designing one LightSwitch screen to create or edit an entity
    How Do I: Filter Items in a ComboBox or Modal Window Picker in LightSwitch

    We’ve also added a couple new features to the video pages which allow you to rate the video (5 stars being the best) as well as a related videos section so you can see the most watched videos in the series. I still recommend you watch them in order because the videos build upon each other as we create a sample application for order entry.

    If you missed them, here’s the first 8 videos.

    Next ones I’m working on will be on Security and Deployment so stay tuned.

    Enjoy!

  • Beth Massi - Sharing the goodness

    Time to Register for Silicon Valley Code Camp!

    • 0 Comments

    It’s that time of year again, Silicon Valley Code Camp is one of the biggest there is spanning many different technologies and grabbing the attention of over 1000 attendees. There are currently 165 beginner to advanced sessions submitted. This year I’ll be speaking on OData with Office & of course, some sessions on LightSwitch:

    Introducing Visual Studio LightSwitch
    Level: Beginner  

    Visual Studio LightSwitch is the simplest way to build business applications for the desktop and cloud. LightSwitch simplifies the development process by letting you concentrate on the business logic, while LightSwitch handles the common tasks for you. In this demo-heavy session, you will see, end-to-end, how to build and deploy a data-centric business application using LightSwitch.

    Visual Studio LightSwitch – Beyond the Basics
    Level: Intermediate  

    LightSwitch is a new product in the Visual Studio family aimed at developers who want to easily create business applications for the desktop or the cloud. In this session we’ll go beyond the basics of creating simple screens over data and demonstrate how to create screens with more advanced capabilities. You’ll see how to extend LightSwitch applications with your own Silverlight custom controls and RIA services. We’ll also talk about the architecture and additional extensibility points that are available to professional developers looking to enhance the LightSwitch developer experience.

    Creating and Consuming OData Services
    Level: Intermediate  

    The Open Data Protocol (OData) is a REST-ful protocol for exposing and consuming data on the web and is becoming the new standard for data-based services. In this session you will learn how to easily create these services using WCF Data Services in Visual Studio 2010 and will gain a firm understanding of how they work as well as what new features are available in .NET 4 Framework. You’ll also see how to consume these services and connect them to other public data sources in the cloud to create powerful BI data analysis in Excel 2010 using the PowerPivot add-in. Finally, we will build our own Excel and Outlook add-ins that consume OData services exposed by SharePoint 2010.

    Please register here: http://siliconvalley-codecamp.com/Register.aspx

    Hope to see you there!

  • Beth Massi - Sharing the goodness

    Using Microsoft Word to Create Reports For LightSwitch (or Silverlight)

    • 83 Comments

    Note: This post has been updated for Beta 2 on 3/24/2011

    LightSwitch has a really nice feature on data grids that allow you to export them to Excel if running as a Desktop application (out of browser).

    image

    This gives you a basic way of getting data out of the system to create reports or do further analysis on the data using Excel. However, in business applications you typically want to provide some client-side reporting that also formats the data in a certain way so it can be printed easily. Microsoft Word is a great tool for this.

    So the last couple days I’ve been playing around with COM automation in LightSwitch and using Word to create client-side reports based on LightSwitch entities. Ideally I’d like to use Word 2007/2010 Open XML features & Content Controls to generate these reports. I’ve written a lot about using Open XML in the past. It’s a great way to manipulate documents without having to have Office installed on the machine, which is especially handy for server-side generated documents. If you haven’t checked out the Open XML SDK yet, I highly recommend it. In a nutshell, Word, Excel and  PowerPoint documents are just .ZIP files with XML inside. The Open XML SDK wraps the .NET System.IO.Packaging classes to make it easy to access the contents.

    Unfortunately the Open XML SDK and the System.IO.Packaging classes are not available in Silverlight and that’s what we’re working with when we create a LightSwitch client. Fortunately, however, Silverlight now supports calling COM components so we can use the Office object models to manipulate the documents on the client (or do anything else that this rich OM gives us). For this exercise I want to allow the user to create a “report” in Word by defining content controls on the document surface. As long as they name the controls according to the fields on the entity, we can easily add some custom XML into the document and bind the controls to that data from our LightSwitch (or Silverlight) client. This gives the end user the flexibility of creating reports, letters, memo’s or anything else you can do with Word. This is similar to a mail-merge except users can invoke this quickly right from within your LightSwitch application.

    Creating the Template

    To begin, I suggest downloading the Content Control Toolkit. Even though we’re going to bind the content controls in code, you can use this to play around with how you want your custom XML to look and bind. For instance, I created a template in Word that has some content controls laid out how I want them on the page in order to create a simple customer report. To add content controls to a document you first need to enable the Developer tab. You do this by opening up the File –> Options –> Customize Ribbon and making sure the developer tab is checked.

    image

    Now you can use the controls to lay out the fields on your document. Click Properties and enter a title that corresponds to the fields on your entity (in my case Customer). You can also lock the controls so that users cannot delete or edit them.

    image

    Here’s what my simple Customer report looks like in design mode:

    image

    Binding Data Manually with the Content Control Toolkit

    Now all we need to do is add our custom XML with the actual data to the document and then bind that data to these content controls. We can do that dynamically in code (and we will), but you can also use the content control toolkit to do it manually. This is an option if you don’t want users to create the templates, instead you want to supply them with your application.

    When you open the document with this tool you see a view of all the content controls on the left and any custom XML parts on the right. In fact, a document can store multiple custom XML parts separated by namespaces that you control allowing you to create some pretty complex binding if needed. First you specify the XML data that you want to bind by clicking “Create a new Custom XML Part” under Actions on the bottom right of the tool. Then you can paste in your XML into the Edit View. For this example we will use this simple set of data which correlates to fields on my Customer entity (note that I’m using all lower case in the elements, XML is case sensitive!):

    <ns0:root xmlns:ns0="urn:microsoft:ordermanager:customer">
        <customer>
            <lastname>Massi</lastname>
            <firstname>Beth</firstname>
            <gender>F</gender>
            <phone>5551212</phone>
            <email>bethma@microsoft.com</email>
            <address1>1234 Main Street</address1>
            <address2></address2>
            <city>San Francisco</city>
            <state>CA</state>
            <postalcode>94115</postalcode>
        </customer>
    </ns0:root>
    

    Once you enter the custom XML into the Edit View, you can flip to the Bind View and then drag the XML elements onto the content controls to bind them (make sure you click twice on the element before dragging it). This sets up the XPath binding expressions.

    image

    Click Save and then you can open it back up in Word to see the report filled out with data. So what exactly did this do? I mentioned that Word, Excel and PowerPoint files are just .ZIP packages with XML inside. To see our custom XML part in the package just rename the .docx file to .zip, then look inside the customXML folder and open the item1.xml to see the custom XML we entered above.

    image

    Next we’ll set up a class to handle generating the data for this report. I’ll first show how we can distribute this already bound template with our LightSwitch application and populate it with customer data then I’ll show how we can populate a user-supplied Word document and bind the content controls dynamically in code.

    Creating the Report Module

    First we’ll need to write a class that encapsulates the report logic. Then we can call this from a button on our Customer screen to generate the report. To add your own class to the LightSwitch client you’ll first need to switch to File View in the Solution Explorer and then you can right-click on the Client project and add your class. I named mine MyReports.vb.

    image

    First thing I’m going to do is rename the Class to a Module since I’m using Visual Basic and put it in the same namespace as my application.This creates a Shared/static class for you so that it’s easy to call the report methods. I’m also going to need to import a couple namespaces, one for the LightSwitch COM automation and the XML namespace that we used in the custom XML part above. (We’ll need the XML namespace when we create the custom XML and bind to it dynamically later.)

    Imports System.Runtime.InteropServices.Automation
    Imports <xmlns:ns0="urn:microsoft:ordermanager:customer">
    
    Namespace LightSwitchApplication
    Module MyReports End Module End Namespace

    Generating a Report from the Fixed Template

    Now that we have our report module set up we can write our code that creates the XML data and then stuffs it into the document. In this first example we’re going to use the template we created above that already has the content controls bound to the custom XML part.

    First we need to check if the COM automation is available – meaning that the application is running out-of-browser with elevated permissions. Next we create an XElement with our customer data. In this case it’s really easy to use LINQ to XML and XML Literals to loop through all the properties of the customer entity dynamically. That way if we add new fields to our Customer entity, we don’t need to change this code at all. (If you’re new to LINQ to XML you can read a few articles I’ve written before here, particularly Getting Started with LINQ to XML.) The query uses the Details property on the entity to get at the collection of properties (fields) on the Customer. Then I create the XML element based on the property name, and then write out the value. If the value is blank then I want to put a dash (-) in the report.

    Next thing we do is create the Word automation object using the LightSwitch System.Runtime.InteropServices.Automation.AutomationFactory (if you are using plain Silverlight then you would use System.Windows.Interop.ComAutomationFactory). We call CreateObject passing it the name of the registered COM object to instantiate, in this case Word.Application. Then we can open the document and find the custom XML part by its namespace. Please note that this will throw an exception if it’s not found so you better wrap all your automation code in a Try…Catch block. COM is all about late binding so you won’t get any intellisense on the members either so the MSDN documentation on the Word object model will be close by. When you’re doing COM programming from .NET it’s helpful to set debugging breakpoints and then explore the members dynamically using the immediate and watch windows.

    Once we get the custom XML part we can replace the <customer> node with our data. We do this using XPath to select the node we want to replace. (BTW, I am totally lame at XPath that’s why I use the Content Control toolkit to help me by looking in the bindings.)

    Once we replace the custom XML with our data we can show the document to the user so they can print it.

    Public Sub RunCustomerReportFixedTemplate(ByVal cust As Customer)
        If AutomationFactory.IsAvailable Then
            Try
                'Create the XML data from our entity properties dynamically
                Dim myXML = <customer>
                                <%= From prop In cust.Details.Properties.All
                                    Select <<%= prop.Name.ToLower %>><%= If(prop.Value, "-") %></>
                                %>
                            </customer>
    
                Using word = AutomationFactory.CreateObject("Word.Application")
                    Dim doc = word.Documents.Open("C:\Reports\CustomerDetails.docx")
    'Grab the existing bound custom XML in the doc Dim customXMLPart = doc.CustomXMLParts("urn:microsoft:ordermanager:customer") Dim all = customXMLPart.SelectSingleNode("//*") Dim replaceNode = customXMLPart.SelectSingleNode("/ns0:root[1]/customer[1]") 'replace the <customer> node in the existing custom XML with this new data all.ReplaceChildSubtree(myXML.ToString, replaceNode) word.Visible = True End Using Catch ex As Exception Throw New InvalidOperationException("Failed to create customer report.", ex) End Try End If End Sub

    Distributing the Report Template with the LightSwitch Client

    Notice that in the above code we are hard-coding the path to where the template is located “C:\Reports\CustomerDetails.docx”. Another option would be to include the report template in the client directly. LightSwitch creates a client XAP file located in your <project>\bin\Release\Web folder and this is what is deployed & running on a user’s machine. To add the CustomerDetails.docx report template, right-click on the ClientGenerated project, then select “Add Existing Item” to select the document and then set the Build Action property to “Content” as shown below:

    image

    Now we can change our code above to read the file using GetResourceStream:

    Dim resourceInfo = System.Windows.Application.GetResourceStream(
    New Uri("CustomerDetails.docx", UriKind.Relative)) Dim fileName = CopyStreamToTempFile(resourceInfo.Stream, ".docx") Dim doc = word.Documents.Open(fileName)

    We just need a couple helper methods in our MyReports module to write the resourceInfo.Stream to disk:

    Private Function CopyStreamToTempFile(ByVal stream As System.IO.Stream, ByVal ext As String) As String
        Dim path = GetTempFileName(ext)
        'Create the temp file
        Dim file = System.IO.File.Create(path)
        file.Close()
        'Write the stream to disk
        Using fileStream = System.IO.File.Open(path,
                                               System.IO.FileMode.OpenOrCreate,
                                               System.IO.FileAccess.Write,
                                               System.IO.FileShare.None)
    
            Dim buffer(0 To stream.Length - 1) As Byte
            stream.Read(buffer, 0, stream.Length)
            fileStream.Write(buffer, 0, buffer.Length)
    
            fileStream.Close()
        End Using
        Return path
    End Function
    
    Private Function GetTempFileName(ByVal ext As String) As String
        'Return a uinuqe file name in My Documents\Reports based on a guid
        Dim path = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "\Reports"
        If Not Directory.Exists(path) Then
            Directory.CreateDirectory(path)
        End If
    
        Dim filename = Guid.NewGuid().ToString() & ext
        path = System.IO.Path.Combine(path, filename)
              
        Return path
    End Function

    Generating a Report from a User-Defined Template

    The above works nicely if we have fixed templates but I want to allow the user to create these templates themselves. However, I don’t want to have make them do any of the binding. All I want them to do is to lay out the content controls where they want them on the document surface and then set their Title to the field name they want to appear. This means that our code will need to add the custom XML to the document and then dynamically bind it to controls it finds.

    To do that we first create the custom XML, but instead of starting with the <customer> element like the above, we need to create the entire tree starting with the <root>. By importing the XML namespace at the top of our code file, Visual Basic will automatically handle putting this XML into that namespace when it is generated. We just specify the namespace on the root element like <ns0:root> and the rest is the same as before.

    Now after we open the report template document we need to make a copy of it, I’m doing that in My Documents\Reports. Then we can add the custom XML part and loop through all the content controls that aren’t already bound in order to set the binding to the correct XPath expressions. These are the same XPath expressions that you see in the Content Control toolkit (that’s why it’s handy to install it). So if I find a content control with the title “LastName” then it will bind to the XPath /ns0:root[1]/customer[1]/lastname. We also need to specify the namespace and the part to bind to in the call to XMLMapping.SetMapping.

    Public Sub RunCustomerReportDynamicTemplate(ByVal cust As Customer)
        If AutomationFactory.IsAvailable Then
    
            Try
                Dim templateFile = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) +
                                   "\Reports\CustomerDetails.docx"
    
                'Create the XML data from our entity properties dynamically
                Dim myXML = <ns0:root>
                                <customer>
                                    <%= From prop In cust.Details.Properties.All
                                        Select <<%= prop.Name.ToLower %>><%= If(prop.Value, "-") %></>
                                    %>
                                </customer>
                            </ns0:root>
    
                Using word = AutomationFactory.CreateObject("Word.Application")
    
                    Dim tempFile = GetTempFileName(".docx")
                    File.Copy(templateFile, tempFile)
    
                    Dim doc = word.Documents.Open(tempFile)
    
                    'Add the new custom XML part to the document
                    Dim customXMLPart = doc.CustomXMLParts.Add(myXML.ToString())
    
                    'bind any content controls that we find based on the title of the control
                    For i = 1 To doc.ContentControls.Count
                        Dim ctrl = doc.ContentControls(i)
    
                        If Not ctrl.XMLMapping.IsMapped Then
    
                            ctrl.XMLMapping.SetMapping(
    "/ns0:root[1]/customer[1]/" + ctrl.Title.ToString.ToLower(), "xmlns:ns0=""urn:microsoft:ordermanager:customer""",
    customXMLPart) End If Next word.Visible = True End Using Catch ex As Exception Throw New InvalidOperationException("Failed to create customer report.", ex) End Try End If End Sub

    Calling the Report Module from the Customer Screen

    All that’s left is calling this baby from a button on our Customer screen. I want to put this on the screen’s command bar (the ribbon across the top) so in the Screen Designer expand the Screen Command Bar at the top, Click Add to add a new button and name it Print. Then right-click on it and select “Edit Execute Code”

    image

    Then we can write code that calls the report and passes it the Customer entity on the screen. We can also edit the CanExecute code so that the button is only enabled for out-of-browser deployments.

    Private Sub Print_Execute()
        ' Write your code here.
        MyReports.RunCustomerReportDynamicTemplate(Me.Customer)
    End Sub
    
    Private Sub Print_CanExecute(ByRef result As Boolean)
        ' Write your code here.
        result = System.Runtime.InteropServices.Automation.AutomationFactory.IsAvailable
    End Sub 

    Now when we run the application, users can click on the Print button on the Customer screen and generate reports that they created in Word.

    image

    With COM automation available in Silverlight a lot of possibilities open up for business applications that need to interact with Office. I hope I’ve showed you one practical way to get simple client-side reporting into a LightSwitch or Silverlight application. (UPDATE: I've attached a sample to the bottom of this post that demonstrates these techniques. You'll need to install LightSwitch Beta 2 to run the sample. )

    To download LightSwitch & access instructional videos and articles please visit the LightSwitch Developer Center.

    Enjoy!

  • Beth Massi - Sharing the goodness

    More LightSwitch How Do I Videos Released Today

    • 2 Comments

    I’m back at it with three more “How Do I” videos on Visual Studio LightSwitch. This continues the series I started last week.

    Video #8 shows off the impressive validation framework that Prem wrote about and some of the slickness around validating sets of data on the client and the middle-tier. If you missed the first 5 videos here they are:

    This series of videos build upon each other as we create a sample application for order entry. It’s looking pretty good now! You can access all the videos from the LightSwitch Developer Center Learn page. In the next set of videos I’ll show you how create and sort lookup data, how to create a single screen for both updating and new records, and lots more goodies.

    Enjoy!

Page 1 of 1 (6 items)