This is the third of three articles which will describe how you can create a Silverlight LOB application that stores and displays documents using FILESTREAM Storage in SQL Server 2008.
- Configuring FILESTREAM in your database and WCF RIA Services setup.
- Uploading and Saving files to the database from a Silverlight LOB application.
- Viewing files stored in the FILESTREAM from a Silverlight LOB application (this article).
The purpose of this article is to show how you can display documents stored via
FILESTREAM in SQL Server in a Silverlight application or ASP.NET website.
In the previous article
we setup a gridview control which contained a listing of documents filtered by the selected folder (see image below). This provided the means to allow users to upload and store documents. For the average user, a quick online backup
client will be a better route.
Now that we have documents stored in our database it is time to provide a way to
display them back to our users. Here are the requirements for our application.
- Only authorized users can view documents.
- A user can open multiple documents at once, in separate windows.
- Documents can be viewed via our Silverlight administrative application.
- Documents can be viewed via our public-facing website.
Given these requirements our approach was to create an ASP.NET page to handle
displaying documents. This page will perform the following tasks to display a document.
- Validates that the user is authenticated.
- Reads the querystring to get the document id (PK) and document guid.
- Reads the Document record via the provided document id. The guid is then used to further validate that we have the correct document. This two prone approach reduces the risk of allowing a user entering random document ids to try to view documents which do not belong to them.
- If a valid Document record is found, the page validates that the authenticated user has sufficient authority to view the Document record. This is done by looking up user roles and applying other security rules. For example, users in account 100 should only be able to see documents tied to account 100.
- If the user has access to view the document then we can display the document to the user. The page determines the type of document and writes out the
document to the browser window.
Here is the code demonstrating the above tasks.
protected void Page_Load(object sender, EventArgs e)
lblError.Text = string.Empty;
//Make sure the user is authenticated
int documentID = 0;
string documentGUID = "";
//Get the Document Id
if (Request.QueryString["ID"] != null)
if (Helpers.isNumeric(Request.QueryString["ID"], System.Globalization.NumberStyles.Integer))
documentID = Convert.ToInt32(Request.QueryString["ID"]);
//Use the GUID as a second line of security so people can't just type in document IDs to view documents.
if (Request.QueryString["DocID"] != null)
documentGUID = Request.QueryString["DocID"].ToString().ToLower();
if (documentID > 0 && documentGUID != "")
MyDomainService service = new MyDomainService();
MyApplication.RIALibrary.Web.Document doc = service.GetDocumentById(documentID);
if (doc != null)
lblError.Text = "You do not have security to view this document.";
catch (Exception ex)
Helpers.ProcessException(ex, "Page_Load - Document.aspx");
//Write out the document based on the type of document
protected void processDocument(Document doc)
string pathLower = doc.Path.ToLower();
Response.ContentType = "application/pdf";
else if (pathLower.EndsWith(".xlsx"))
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
else if (pathLower.EndsWith(".xls"))
Response.ContentType = "application/vnd.ms-excel";
else if (pathLower.EndsWith(".docx"))
Response.ContentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
else if (pathLower.EndsWith(".doc"))
Response.ContentType = "application/msword";
else if (pathLower.EndsWith(".zip"))
Response.ContentType = "application/zip";
else if (pathLower.EndsWith(".gif"))
Response.ContentType = "image/gif";
else if (pathLower.EndsWith(".tiff"))
Response.ContentType = "image/tiff";
else if (pathLower.EndsWith(".bmp"))
Response.ContentType = "image/bmp";
else if (pathLower.EndsWith(".png"))
Response.ContentType = "image/png";
else if (pathLower.EndsWith(".htm"))
Response.ContentType = "text/html";
else if (pathLower.EndsWith(".txt"))
Response.ContentType = "text/plain";
else if (pathLower.EndsWith(".msg"))
Response.AddHeader("content-disposition", "attachment; filename=test.msg");
Response.ContentType = "image/jpeg";
In the processDocument method you will notice the different file extensions that we support. Your application could have a different list, but the concept is the same.
Another key point in the code is where we write out the DocumentFile via BinaryWrite.
Bonus - Storing and Retrieving Outlook messages
One cool thing we found was that we were able to drag an email message from Outlook to be stored in our application. Drag a message from Outlook to your desktop, then drag onto the drop area in the Silverlight application and the document is stored. To view the message write out a Header (instead of ContentType) indicating that the file should be opened as an attachment. The document opens up in Outlook as an email (with attachments) - very cool!
The nice thing about using an ASP.NET page to display documents is that you can launch the page from both Silverlight and ASP.NET.
That's it! I hope you found this series to be useful. I welcome questions and comments.
Chris Rouw, Far Reach Technologies
MCTS Silverlight 4, Developer