Sunday, September 27, 2009

User Control Error In SharePoint

Background

I was getting the following error when trying to build a simple hello world user control (ascx) and then load it into a web part.

Error

The file '/_controltemplates/XXX/MyWebUserControl.ascx' does not exist.

at System.Web.UI.Util.CheckVirtualFileExists(VirtualPath virtualPath)

at System.Web.Compilation.BuildManager.GetVPathBuildResultInternal(VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile)

at System.Web.Compilation.BuildManager.GetVPathBuildResultWithNoAssert(HttpContext context, VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile)

at System.Web.UI.TemplateControl.LoadControl(VirtualPath virtualPath)

at System.Web.UI.TemplateControl.LoadControl(String virtualPath)

at MOSSDistillery.UserControl.WebPart.MySmartPart.CreateChildControls()

Symptoms

What was frustrating was that I could point to any existing user controls provided in SharePoint and they load in fine. Here is the code:

protected override void Render(HtmlTextWriter writer) {
base.Render(writer);
writer.WriteLine(loadControlError);
}
protected override void CreateChildControls()
{
try
{
base.CreateChildControls();

System.Web.UI.UserControl control = (System.Web.UI.UserControl)Page.LoadControl("~/_controltemplates/MyWebUserControl/MyWebUserControl.ascx");
Controls.Add(control);
}
catch (Exception ex)
{
loadControlError = ex.Message + " " + ex.InnerException;
}
}

This error was pretty tough to figure out because:

  • The ascx file was in the correct place.
  • I had entered a safe controls entry.
  • If I changed the web.config to Full trust, everything would work.

I did a significant amount of investigation to understand why I was getting this error. From what I was able to find out, you will get this error in the following scenarios.

  • If you have the ascx file in a location where it cannot be found.
  • If you place the web part dll in the web bin directory and do not place that ascx control in the ~/_controltemplates/ directory. Specifically if you place the web control in a custom folder within the control templates folder in the 12 hive folder. Even with all the correct CAS permissions, it will not work. However if the web part dll in the GAC, it will work.
  • If you place the web part dll in the web bin directory, the error will go away if you move the code from the CreateChildControls() to the OnInit().

Resolution

When research the solution, I saw that many people would just change the permissions levels to full which is a completely unacceptable solution. The following are some deployment options for a web part that will show an ASP.net user control. I have ordered them in the most secure to least secure:

  • Deploy the web part dll to the bin. Add the code to load the user control in the OnInit() method. Place the user control (ascx) directly into the control templates folder in the 12 hive. Make sure you have a safe controls entry in the web.config. Only disadvantage is that you cannot place the user control into a custom folder to separate your user control from SharePoint's user controls. However this is the most secure.
  • Deploy the web part dll to the GAC. Place the loading of the user control into the CreateChildControls method. Place the user control (ascx) where ever you want within the control templates folder in the 12 hive directory. I suggest putting the user control into a custom folder. Make sure you have a safe controls entry in the web.config. The disadvantage is that the dll is not accessible to any running process on the web server. I know many developers have become accustomed to putting dlls in the GAC but again you should always strive to deploy to the web bin and run under minimal trust.
  • I found this option - http://blogs.msdn.com/chandru/archive/2009/03/02/cas-in-sharepoint.aspx. It does work however what you are basically doing is allowing the custom CAS permission you have created for your web part to run in full trust. There are several major issues with doing this. First, the stsadm addsolution command will fail if Unrestricted="true" is added to the PermissionSet within the manifest.xml file – it is not allowed. Second, you decided to do this, will have to manually make the change to each front end web server in the farm which is a deployment problem. Third, you are allowing all dlls running under the CAS permission to run with full trust.
  • Run SharePoint in full trust – please do not do this – it is highly unrecommended.

Saturday, September 26, 2009

Excel and PDF Data Dump in SharePoint

Background

I recently had to come up with a quick solution in a week to provide both Excel and PDF downloads of datasets that I was being presented through some SharePoint web parts. I had to create some use controls that would be embedded into SharePoint that providing reporting data. The user needed the ability to down load the underlying datasets in either Excel or PDF.

My natural first inclination was to use SSRS because first it has tight integration with SharePoint. Second the report viewer control provides the ability to download the report and excel and pdf formats. Well in this case I could not use SSRS because it was not part of the solution architecture. As well, I needed to find a "free" solution.

Excel Solution

For Excel, I investigated a couple different solutions. I particularly did not want to have to mess around with the Office Excel API. First the API is not very clean and would be time consuming to code to. Second I would have to install Office onto the front end web servers. Then I thought, how about providing an XML file that opens into Excel? I though, InfoPath is just an XML file with specific processing tags embedded into it which would open InfoPath. I recalled that the same could be done with Excel. I subsequently found this blog posting (http://www.ksaelen.be/wordpress/2009/08/using-c-xml-xslt-to-create-excel-spreadsheet/) and it provided me with an extremely easy way of generating excel data dumps. All you basically do:

  • Create an Excel file with all the presentation you want.
  • Save it is as an Office 2003 XML format.
  • Change the XML file to an *.xsl file.
  • Make modifications to the .xsl file to merge in data from another XML file which has all the data.
  • The use the XslCompilatedTransform class to merge it together.
  • Then I took the results, put it into a MemoryStream and saved down into a document library.

The limitations of this solution are that any charting and code modules you may want to include in the generated XML file is not supported. This is really only a good solution for doing a data dump of the underlying data that may be presented to a user. However it is really simple to implement, requires no special add-ins, you can stylize your presentation and you can be provide very dynamic results. Plus many of the reports provided by SharePoint use XML Excel files so I did not feel too bad in doing this.

PDF Solution

The next thing I had to do was provide the same results in PDF format because not everyone would have Excel. Now the solution above will support both Office 2003 and 2007, however someone may not have Office installed at all. I looked into several tools that would do PDF generation from HTML, but I needed to keep cost down. I subsequently found a very mature open source PDF library called PDFsharp and MigradDoc Foundation:

The source code is very well written, commented and managed. This scored big points in my book because I usually shy away from open source solutions strictly for code maintenance reasons. These guys also provided tons of code samples and provide the ability to do basic charting too.

I was able to in an afternoon, pull in the library and generate tables of data into PDF. It was very easy for me to then save it down into a document library and provide a user a link to that generated PDF. I specifically used the MigraDoc API to save the generated PDF into a MemoryStream and then just push that right into a SPListItem.

Monday, September 7, 2009

Using old VHDs on Windows Virtual PC

Background


Couple weeks ago I put Windows 7 on my new laptop. As a developer one of the first things I had to do was take advantages of the new virtualization features provided by Windows 7. For the past five years I have been using Microsoft Virtual PC for everything. I have preached and preached it for the past couple years because:

  • I can create dedicated environments for projects and/or clients.
  • My environments will not dependencies installed within them that could implementations between environments.
  • I can save state and come back to something at any time.
  • It is really easy for take a snapshot and then do something risky or install some new flaky software.

I had mostly used Virtual PC 2007 SP1 and had become familiar with Virtual Server. When I put on Windows 7 on my machine; I really did not know a couple things had changed. I am not a desktop OS person and I had not read much about Windows 7 – other than I held off from Vista.


My goal is to have my host OS on 64 bit with Windows 7 and bring over all my old vhd drives and run them on this machine. You cannot run Virtual VPC 2007 on Windows 7, however the .vhd files created by Virtual VPC 2007 can be used with Windows Virtual PC on Windows 7.


Here are the key differences on the surface you should know when moving over to Windows 7 and using virtualization:

  1. It is now called "Windows Virtual PC"
  2. The interface is different from what it used to be.
  3. Microsoft is now using it as a strategy to allow every day desktop users use it to get backwards compatibility to applications that work on Windows XP.
  4. VHD files can now be mounted (attached) as a disk and then access the files within the VHD directly on the host machine windows explorer.
  5. It possible to boot the VHD as a duel boot.

Installation


Installation is not that hard. First go here and select information about your Windows 7 OS. You will need to minimally download Windows Virtual PC RC. Go ahead and then download Windows XP Mode RC. You can also get all the installation instructions right off this page.


Some important pre-requisites steps that you will need to complete are:


  1. System requirements - http://www.microsoft.com/windows/virtual-pc/support/requirements.aspx - Upon reading the system requirements you may note that only Guest Operating Systems of Windows XP, Windows Vista and Windows 7 are only supported. Do not be alarmed, this basically means you will not be able to take full advantage integration between the host OS and guest OS. I can say for the past couple weeks I have been able to bring over several of my VPCs running on Windows Server 2003 with no problem. I know others who have been able to bring over Windows Server 2008.
  2. You need to make sure that your BIOS are properly set up. Follow the instructions here - http://www.microsoft.com/windows/virtual-pc/support/configure-bios.aspx
  3. Install the Windows Virtual PC RC.
  4. Install Windows XP Mode RC (optional).

Windows Virtual PC


As I mentioned, the User Interface has changed as it is integrated within Windows Explorer. I am not going to give a tutorial on how to use it however; here is what it looks like. After the installation there will be a new folder called Virtual Machines created which is where you can access and your VPCs. As you can see all of the files and there is a new tool bar being displayed.



Taking a close look at the tool bar, when I select a .vmcx (which is equivalent to a .vmc for VPC 2007), you will see an "Open" option added to the tool bar. You can click on that or just double click the .vmcx file which will start up the VPC.

You will also notice that there is a "Settings" option in the tool bar when you select a .vmcx file. When you click on Setttings, you will get the traditional VPC Settings screen we are familiar with to configure memory, disk, networking, etc.



Finally in the tool bar, there is a "Create virtual machine" button which will launch a wizard to create a new VPC. This wizard is again very similar to Virtual VPC 2007.


You now see that using VPCs on Windows 7 is more of an integrated experience.


Windows Virtual PC >> Windows XP Mode


As I mentioned this is an optional installer. From what I can tell, the strategy by Microsoft it so use virtualization to allow backward support of applications. As well, the way this is marketed, it is more meant for the everyday desktop user. What it allows is a user to get a XP VPC running (without any licensing), to run older applications. I personally think it is great. Plus if you are worried about your kids or wife getting some virus while surfing or what not, have then surf on the VPC J


Running an Old VPC


Like I mentioned, I needed to run some vhd files I had created with Virtual VPC 2007 that had a guest OS of Windows Server 2003 (which is not supported). This is all you need to do:

  1. Move the vhd file over to your Windows 7 machine. I suggest that you create a folder under C:\Users\[username]\Virtual Machines\ and place the vhd there.
  2. Then go to C:\Users\[username]\Virtual Machines\ directory and click "Create virtual machine". This will initiate a wizard.
  3. Specify a name and change the location to point to the location where the vhd file is. Press Next.
  4. Specify RAM and press next.
  5. On the "Add a virtual hard disk", select the "Use an existing virtual hard disk" and select the vhd file that was moved over. Press the Create button and you are complete.

When this is completed, a .vmcx file should be created in C:\Users\[username]\Virtual Machines\. To boot the VPC, all you need to do is double click that file, or select Open button in the tool bar. I suggest verifying the configuration by pressing the Settings button before spinning it up.

Here are some things you may run into.

First you will see a pop-up saying "Updates for Windows Virtual PC Integration Components are available" every time you reboot the guest OS. DO NOT press the update button. This will install the integration components for Windows Virtual PC which is not compatible with either Windows Server 2003 or 2008. I tried it; it did not work. Just press the cancel button and you will be fine.


Second, you will constantly get a prompt after log in saying New Hardware has been found. Again, just cancel.


After that, you should be good to go.

One thing I have not tried is creating a brand new VPC with Windows Server 2003 or 2008 using Windows Virtual PC. I wonder how the integration between the Host and the Guest will work without installing the additions in the Guest OS; remember you cannot install the Windows Virtual PC additions. I guess the only option would be to run the vhd on a machine which had Virtual VPC 2007 SP1, install the additions, and then bring the vhd back to the Windows 7 machine.

Sharing Files

Because the integration components do not work with Windows Server 2003 and 2008 on a guest OS, it is not possible to drag and drop files between the host and guest. As well, if you go to the settings of the vmcx file, you will see the Integration Features option. Even if you try to select Drives here, they will not work.


The best way to accomplish this is to:

  • Create a loop back adapter on your host machine running Windows Server 2007.
  • Then click on the Networking settings for the vmcx. For the first adapter set it to NAT and for the second adapter select the Microsoft Loopback Adapter you just created on the host machine.
  • Then create a Shared Folder on the guest OS.
  • Then map to that folder of the guest machine from the host machine.

Experiencing Slowness?


If you are experiencing any slowness in the UI resolution of the VPC the following KB will help you out - http://support.microsoft.com/kb/899525. Even though it is a fix for Virtual VPC 2004, it does help with Windows Virtual PC. The location of the Options.xml file is %userprofile%\AppData\Local\Microsoft\Windows Virtual PC\


Mount a VHD Drive


Now this is a really cool new feature of virtualization with Windows 7. You now have the ability to treat a vhd file like a drive on the machine. Please read the following - http://thelazyadmin.com/blogs/thelazyadmin/archive/2009/01/15/mount-a-vhd-within-windows-7-server-2008-r2.aspx.


However you cannot do this while the vpc is running, so this is not a good open to share files between the host and guest OS if you need to do it on a regular basis.


One cool thing is if you do not want to boot up an old vhd to get some files of it, all you need to is mount it. You can go right into the vhd using your host's windows explorer and extract or use any of the files on there. I suspect people will start coming up with really creative ways to use this over the next couple of months.


Dual Boot from VHD


Now this is what many folks are blogging about, it is your ability to do a dual boot from your vhd. Please read here - http://blogs.technet.com/keithcombs/archive/2009/05/22/dual-boot-from-vhd-using-windows-7-and-windows-server-2008-r2.aspx.


Again I plan on taking advantage of this really soon to maximize memory usage because there is no need to run the host OS anymore…