This post will show you how to deploy a web part to the /bin folder (using WSPBuilder) AND how to configure it using CAS (Code Access Security) so your web part can actually run from that folder too! I kept finding articles that discuss one or the other, but not both. Those articles that did help me quite a bit have been referenced in the last part of this post.
So, from the top, when you create a web part in Visual Studio 2008 and hit F5, the web part will deploy to the site you selected (right-click Project's Properties, click Debug, then whatever site you typed in Start browser with URL). In your Solution Explorer, you will notice a folder called /bin with another folder called /debug under that, and the compiled code will sit under there. This means its being deployed into the GAC.
At a high level, there's really two steps we must do to get our web part to run from the web application's (your SharePoint site's) /bin folder. (You can get to /bin either by going into IIS and choosing the web application you want it deployed to, or by going to c:\inetpub\wwwroot\wss\VirtualDirectories\<web application>\bin.)
The first step is actually deploying to the above-mentioned location. Once this is done, sure, the web part is right where you want it to be, but it won't run until we do step two, which involves setting the proper permissions to allow it to run from that spot. This second step involves modifying the web.config to look at a custom policy file where we will make changes to the CAS policies.
First, deploy the web part assembly to the /bin:
1. In Solution Explorer, delete the /bin folder. It will reappear in a few seconds with a Debug subfolder, but it will be empty other than that.
2. In Solution Explorer, create a folder called 80, and under that, create a folder called bin. So you will have /80/bin.
3. Right-click the project in Solution Explorer, and on the Compile tab, change Build Output Path from bin\Debug\ to 80\bin\.
4. In Solution Explorer, in AssemblyInfo.vb, you must add two lines:
a. below the other Imports statements, add the following:
Imports System.Security
(Note: this will be a Using statement if you are doing C#)b. Below one of the other Assembly statements, add the following:
<assembly: AllowPartiallyTrustedCallers()>
(Note: This step doesn't affect the deployment of the web part, but comes into play when you try to actually use the web part on a page after its been deployed to /bin.)5. Now, when you compile the application you will notice the assembly (the dll) appears in /80/bin instead of where it was being put before, /bin/debug. If you hit F5 to deploy it, you will notice all the other deployment files Visual Studio creates is also placed in this folder. This leads me to my next point.
Visual Studio creating deployment files automatically is no good. Sure, it will get everything up and running on the server, but maybe not the way you want. For instance, even though I have created a /12/TEMPLATE/FEATURES/AddContactFromAD folder structure in my Solution Explorer, and put in my feature.xml, elements.xml (mine is actually called AddContactFromAD.xml), and a web part definitions file AddContactFromAD.webpart, Visual Studio generates its own feature.xml (which doesn't have my pretty description I put in the real feature.xml). It also tends to write its own manifest.xml, wanting to deploy to GAC! So, let's deploy a much better way, using WSPBuilder! You can download WSPBuilder here. Once installed, it will be added to Visual Studio's Tools menu.
6. Assuming you have the above-mentioned 12 hive folder structure with a folder for each web part under FEATURES, and with that, a feature.xml, elements.xml, and .webpart file under each web part's folder, you can simply click Tools -> WSPBuilder -> Build WSP. WSP Builder will create the resulting .wsp and drop it in your project folder. Renaming it to .cab and opening it you will see each web part's feature.xml, elements.xml, .webpart, plus the assembly .dll and an autogenerated manifest.xml. Looking inside the manifest.xml will reveal two things: 1. the DeploymentTarget is WebApplication (no longer GlobalAssemblyCache as it was before), and 2. CAS policy permissions were added.
7. Ok, so let's deploy this bad boy. To do this, I add the solution, deploy the solution, then activate the features (1 feature per web part). Below is my own batch file add.bat:
stsadm -o addsolution -filename contactuswebpart.wsp
stsadm -o deploysolution -name contactuswebpart.wsp -url http://sharepoint2007:1001/ -immediate -allowCasPolicies
stsadm -o activatefeature -name contactlist -url http://sharepoint2007:1001
stsadm -o activatefeature -name emailcontact -url http://sharepoint2007:1001
stsadm -o activatefeature -name addcontactfromad -url http://sharepoint2007:1001
stsadm -o deploysolution -name contactuswebpart.wsp -url http://sharepoint2007:1001/ -immediate -allowCasPolicies
stsadm -o activatefeature -name contactlist -url http://sharepoint2007:1001
stsadm -o activatefeature -name emailcontact -url http://sharepoint2007:1001
stsadm -o activatefeature -name addcontactfromad -url http://sharepoint2007:1001
Also, my remove.bat comes in handy when testing:
stsadm -o deactivatefeature -name contactlist -url http://sharepoint2007:1001
stsadm -o deactivatefeature -name emailcontact -url http://sharepoint2007:1001
stsadm -o deactivatefeature -name addcontactfromad -url http://sharepoint2007:1001
stsadm -o retractsolution -name contactuswebpart.wsp -url http://sharepoint2007:1001/ -immediate
stsadm -o deletesolution -name contactuswebpart.wsp
stsadm -o deactivatefeature -name emailcontact -url http://sharepoint2007:1001
stsadm -o deactivatefeature -name addcontactfromad -url http://sharepoint2007:1001
stsadm -o retractsolution -name contactuswebpart.wsp -url http://sharepoint2007:1001/ -immediate
stsadm -o deletesolution -name contactuswebpart.wsp
At this point, if you check your web application's /bin, you should see the assembly .dll there. If you go to the Web Part Gallery and click the web part, or if you attempt to add the web part to a page, you will get an error. This is because we still need to do Part 2 of this grand adventure: modify the permissions.
For the second and final step, set the CAS policy permissions to enable the web part to run from /bin:
1. We are going to copy the existing wss_minimaltrust.config, rename it, then make our policy changes in that file. Go to c:\Program Files\Common Files\Microsoft Shared\web server extensions\12\CONFIG, copy wss_minimaltrust.config and rename it wss_webpartbintrust.config.
2. In our new CAS policy file, wss_webpartbintrust.config, we have three changes.
a. First, add a reference to SharePointPermission in the <SecurityClasses> section. Add the following:
<SecurityClass Name="SharePointPermission" Description="Microsoft.SharePoint.Security.SharePointPermission, Microsoft.SharePoint.Security, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
b. Next, add a new custom permission set. Find the NamedPermissionSet that is named SPRestricted and copy and paste this below it:
<PermissionSet class="NamedPermissionSet" version="1" Name="WebPartBinTrust">
<IPermission class="AspNetHostingPermission" version="1" Level="Minimal" />
<IPermission class="SecurityPermission" version="1" Flags="Execution" />
<IPermission class="WebPartPermission" version="1" Connections="True" />
<IPermission class="SharePointPermission" version="1" ObjectModel="True" />
</PermissionSet>
<IPermission class="AspNetHostingPermission" version="1" Level="Minimal" />
<IPermission class="SecurityPermission" version="1" Flags="Execution" />
<IPermission class="WebPartPermission" version="1" Connections="True" />
<IPermission class="SharePointPermission" version="1" ObjectModel="True" />
</PermissionSet>
c. Finally, add the code group. This will indicate when the permissions are to be set. It should be noted this can be done one of two ways, either using a strong name membership (assuming your assembly has been strongnamed) or a url membership, which would give you the option of having the permissions apply to all assemblies in the specified bin or the specific assembly itself.
Under <CodeGroup class="FirstMatchCodeGroup"...> you will see several <CodeGroup class="UnionCodeGroup"...> tags. Place the following code as the first one of these.
<CodeGroup class="UnionCodeGroup" version="1" PermissionSetName="WebPartBinTrust">
<IMembershipCondition class="StrongNameMembershipCondition" version="1" PublicKeyBlob="00240000048000009400000006020000002400005253413100040000010001000DAF8ED8D945CD2ABB2EE7953A6039B791A725F11B4588AC6D70B3E0648F955E9ED4C3C43CB044B8B0E8A6FF4D4FFBE9E3B9297D45F688A7264534E12414E17539305207EC961DA94DF294E7722CCD9BDBFC95A896E996F57156705D281EC39280BD604E87724556AF5807D146963F19F5B43DB69E1F22695463153A553260D2" Name="ContactUsWebPart" />
</CodeGroup>
(Note: The PublicKeyBlob must be the public key blob of your assembly. You may see the PublicKeyBlob in another tag referencing your assembly, in which case, just copy and paste it. Otherwise, you will need to run the command: secutil -hex -s contactuswebpart.dll > publickeyblob.txt, then copy and paste it from the output file publickeyblob.txt.)<IMembershipCondition class="StrongNameMembershipCondition" version="1" PublicKeyBlob="00240000048000009400000006020000002400005253413100040000010001000DAF8ED8D945CD2ABB2EE7953A6039B791A725F11B4588AC6D70B3E0648F955E9ED4C3C43CB044B8B0E8A6FF4D4FFBE9E3B9297D45F688A7264534E12414E17539305207EC961DA94DF294E7722CCD9BDBFC95A896E996F57156705D281EC39280BD604E87724556AF5807D146963F19F5B43DB69E1F22695463153A553260D2" Name="ContactUsWebPart" />
</CodeGroup>
3. Almost there... Just two more changes, but this time in your site's web.config. Go to c:\inetpub\wwwroot\wss\VirtualDirectories\<your site>\web.config.
a. In the SecurityPolicy tag, make sure there is an entry for a custom TrustLevel that points to the policy file we just edited:
<trustLevel name="WSS_Custom" policyFile="C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\config\wss_webpartbintrust.config" />
b. Scroll down a bit and make sure the trust level is set like this:
<trust level="WSS_Custom" originUrl="" />
That's it! Restart IIS and have fun!
Some good pages that helped me figure this all out:
WSPBuilder - Walkthrough of the Visual Studio Add-in
MOSS 2007 and Code Access Security
Gaurav Taneja article on bin and GAC deployment
Deploy dlls to the webApplications bin rather than GAC
Code Access Security in SharePoint 2007 for Administrators