Thursday, 30 May 2013

Column validations and List validations in SharePoint 2010

Column validations and List validations in SharePoint 2010

List validation and column validation is one of the notable feature of SharePoint 2010. We will see how we can set validation to a list and to a column with formulas without using SharePoint designer
Taking an example of an EmployeeEntry list where employees will enter their data in the list; we will see how the validation rules can be set on this list



The list schema of EmployeeEntry list is as follows
Title - Single line of text
Description - Multiline of text
EmpId - Numeric column
EmpType - Choice [dropdown with values 'Permanent', 'Vendor']

Business Rules

Following are the business rules we are going to implement with the validation settings.
Rule 1> EmpId cannot be duplicate
Rule 2> EmpId cannot have decimal values and should allow only positive numbers
Rule 3> Employees of type ‘Vendor’ are not allowed to enter information

Validation settings

There are two types of validation settings, one at list level and another at column(field) level.

List level

After creating the list, go to the list settings page. We can observe validation settings option under General Settings category.
List Settings



When we click validation settings,the setting page will show us list level validations to set.
List Validation Settings


In the Insertcolumn we will have all the column list that are eligible for setting the validation.
(not all columns can be used to set validations)
In the formula section we will provide formula to validate columns data.
In the UserMessage section, we will provide the error message that will be poped out if invalid data is provided.

Field level settings

In the list settings page, under columns section click the column EmpId which will take us to column settings page.
Column settings



In the Additional Column Settings page, we can see the option Enforce unique values: (the pointer 1 in the image)
This is the new option which enforces, unique values in the column.
Under column validation section, in Formula text box we will provide formula to validate the user input.
In User message text box, we will provide the error message that will be poped out, if invalid data is provided.

Formulas

In the list settings page, under columns section click the column EmpId which will take us to column settings page.
    Rule 1> EmpId cannot be duplicate
To implement Rule 1, select ‘Yes’ radio button under Enforce unique values and click ‘Ok’ button. SharePoint will prompt that column is not indexed, do you want to index the column.
Click ok to index and it is good practice to index the column for better performance when you already know that column has unique values.
With this, SharePoint will enforce unique values on EmpId column. Users cannot save duplicate data in ‘EmpId’ column.
    Rule 2>EmpId cannot have decimal values and should allow only positive numbers
In the list settings page, under columns section click the column ‘EmpId’ which will take us to column settings page.
Under ‘Additional Column Setttings’, there is small text box with Label ‘Min:’ under ‘you can specify a minimum and maximum allowed values:’ (Pointer 2 in the above column settings image)
Provide value ’1′ in the text box and click ok to save the values.
Now try to add a new item in the list and give empId as ‘-1′; try to save the data. SharePoint will give error message saying the ‘the value in the field must be greater than 1′.



Rule2_1



So, our column is ready with unique values and positive values.
To implement the rule, not to allow decimal values; generally after seeing the column settings we can say that there is a dropdown list ‘Number of decimal places’ and select 0 in that. Of-course our assumption is true, but in reality this is not enforcement. SharePoint will only round the decimal values if we use that option.
For example if we select 0 decimal places and give the empId value as 1.2; it will be converted to 1 in the UI. But, in the backend we still has 1.2 as original data. Also, if we give value as 1.8 it will round to 2. So, this is not the option to enforce not to give decimal values.
Now comes our ‘Formula’ text box under Column Validation section. (Pointer 3 in the above column settings image)
In the Formula text box give the value as =EmpId=INT(EmpId)
In the UserMessage text box give the values as decimals are not allowed.
Now try to save new item with employee id ’1.2′. It will give error message decimals are not allowed



Rule2_2


    Rule 3> Employees of type ‘Vendor’ are not allowed to enter information
This is rule is more on the list column but not on single column.
Go to the list settings, click validation settings option under General Settings category.
In the formula text box give =IF(EmpType=”Vendor”,FALSE,TRUE)
In user message give Vendors type is blocked currently
Now try to save new item selecting ‘Vendor’ in EmpType dropdown. It will give error message Vendors type is blocked currently



Rule3


More Information

What ever the formula we provide, it should return true or false. If it returns true, the validation is success and if false it is a failure and gives error message.
Some more examples of formulas so that we can get familiar with syntax
=EmpId>10 //Allows only EmpId greater than 10
=IF(EmpId>10,TRUE,FALSE) //Allows only EmpId greater than 10, same as above but with IF condition.
=AND(EmpId>5,EmpId<10) //Allow EmpId to be in the range between 5 and 10
=IF(LEN(EmpId)>5,TRUE,FALSE) //Allows EmpId length greater than 5 digits only
=[EmpId]<> 11 //Restricts users not to give EmpId as 11
=[JoiningDate] < TODAY() //If JoiningDate is the date column, JoiningDate should be less than todays date
=IF(Cost>([Sell Price]-(Cost*(10/100))),FALSE,TRUE) //validaion to set Selling price should always be 10% more than cost price
Note: SharePoint does not allow regular expressions in validation formulas.
You can refer this link for formula syntax
Formulas and functions

Event receiver for specific list

Event receiver for specific list

In this post we will see how we can attach event receiver for specific list in SharePoint 2010.
In general coders tend to write event receiver which is global for all the lists. In the event receiver code they will compare with the list name and then provide specific functionality.
In this post we will see the better practice and simple way how to set the event receiver(ex: ItemAdding event) only for a particular list
 Event Receiver
Open Visual Studio 2010, select File > New > Project.
Select Event Receiver template under SharePoint > 2010
image

Provide the site url and select deploy as form solution and click Next button
image

Select List Item Events under type of the event receiver. Select Custom List and check the events we want to trigger.
image

Once finished, go to the solution explorer and see the the elements.xml.
image
ListTemplateId=”100″ is the main value that attaches event receiver to any custom list.
Change the  ListTemplateId to ListUrl like the following and deploy the solution
ListUrl=”Lists/MyCustomList”
MyCustomList is the name of the custom list which I have created in my site. Now the Item Adding event receiver will be triggered only for the custom list MyCustomList but not to all the lists.
You can test the triggered event by attaching the debugger to see the event is fired only for that list

Upload Excel data into SharePoint Custom List

Upload Excel data into SharePoint Custom List

In this post we will see how to upload excel data(using oledb provider) into SharePoint 2007 / SharePoint 2010 Custom List from object model(c#)
What are the points that are covered
  • Get the sheet name from excel file rather than providing static name
  • Builds connection string for .xls and .xlsx files
  • Reads excel data and inserts into SharePoint custom list

Upload excel data

The following code reads data from contacts.xls and inserts into SharePoint Custom List ContactList which I have created.
According to the schema of the ContactList, the method InsertIntoList() in the following code has relevant code.
You can modify according to the schema of your Custom List and Excel file
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.IO;
using System.Data;
using System.Data.OleDb;
using Microsoft.SharePoint;
  
namespace TestSharepointProject
{
    public class UploadExcelData
    {
        public void LoadExcelData()
        {
            string fileName = "@"C:\AdisGroup\Contacts\contacts.xls";
            //if you are using file upload control in sharepoint get the full path as follows assuming fileUpload1 is control instance
            //string fileName = fileUpload1.PostedFile.FileName
  
            string fileExtension = Path.GetExtension(fileName).ToUpper();
            string connectionString = "";
  
            if (fileExtension == ".XLS")
            {
                connectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source='" + fileName + "'; Extended Properties='Excel 8.0;HDR=YES;'";
            }
            else if (fileExtension == ".XLSX")
            {
                connectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source='" + fileName + "';Extended Properties='Excel 12.0 Xml;HDR=YES;'";
            }
            if (!(string.IsNullOrEmpty(connectionString)))
            {
                string[] sheetNames = GetExcelSheetNames(connectionString);
                if ((sheetNames != null) && (sheetNames.Length > 0))
                {
                    DataTable dt = null;
                    OleDbConnection con = new OleDbConnection(connectionString);
                    OleDbDataAdapter da = new OleDbDataAdapter("SELECT * FROM [" + sheetNames[0] + "]", con);
                    dt = new DataTable();
                    da.Fill(dt);
                    InsertIntoList(dt,"ContactList");
                }
            }
        }
  
        private string[] GetExcelSheetNames(string strConnection)
        {
            var connectionString = strConnection;
            String[] excelSheets;
            using (var connection = new OleDbConnection(connectionString))
            {
                connection.Open();
                var dt = connection.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
                if (dt == null)
                {
                    return null;
                }
                excelSheets = new String[dt.Rows.Count];
                int i = 0;
  
                // Add the sheet name to the string array.
                foreach (DataRow row in dt.Rows)
                {
                    excelSheets[i] = row["TABLE_NAME"].ToString();
                    i++;
                }
            }
            return excelSheets;
        }
  
        private void InsertIntoList(DataTable listTable, string contactListName)
        {
  
            SPWeb mySite = null;
            try
            {
  
                mySite = SPContext.Current.Web; //create web object if context is null
                mySite.AllowUnsafeUpdates = true;
                SPList contactList = mySite.Lists[contactListName];
                for (int iRow = 0; iRow < listTable.Rows.Count; iRow++)
                {
                    SPListItem newContact = contactList.Items.Add();
                    newContact["FirstName"] = Convert.ToString(listTable.Rows[iRow][0]);
                    newContact["LastName"] = Convert.ToString(listTable.Rows[iRow][1]);
                    newContact["FullName"] = Convert.ToString(listTable.Rows[iRow][2]);
                    newContact["LoginID"] = Convert.ToString(listTable.Rows[iRow][3]);
                    newContact["EmailAddress"] = Convert.ToString(listTable.Rows[iRow][4]);
                    newContact["PhoneNumber"] = Convert.ToString(listTable.Rows[iRow][5]);
                    newContact["Company"] = Convert.ToString(listTable.Rows[iRow][6]);
                    newContact.Update();
                }
                mySite.AllowUnsafeUpdates = false;
            }
            catch (Exception ex)
            {
                //log exception
            }
            finally
            {
                if (mySite != null) //don't dispose if the site is from SPContext
                {
                    mySite.AllowUnsafeUpdates = false;
                }
            }
  
        }
  
    }
}

Remarks

In the above code
LoadExcelData method takes data from first sheet name i.e sheetNames[0]. Change this if you want to load from another sheetName
InsertIntoList method uses SPContext to get the current web object. If you are using the above code where SPContext is not available then you have to create SPWeb object and dispose it in finally block

Excel 2010 vba add item to sharepoint list

I found a VBA snippet which update sharepoint list via Listobject's publish method. I hope it can help you.
Public Sub PublishList()' Get the collection of lists for the active sheetDim L As ListObjects
Set L = ActiveSheet.ListObjects
' Add a new listDim NewList As ListObject
Set NewList = L.Add(xlSrcRange, Range("A1:G8"), , True)
NewList.Name = "PartsList"' Publish it to a SharePoint site
NewList.Publish Array("http://sharepointportal.xxx.com/personal/xxx/_layouts/viewlsts.aspx?BaseType=0", _
"NewLists "), TrueEnd Sub

I tried what you said, and even went to creating a column heading the same as what is in the Sharepoint list already (I used exactly the same column names) . I get the following error though:
"Run-Time Error '-21474467259 (80004005)': An unexpected error has occured. Changes to your data cannot be saved."
Public Sub PublishList()' Get the collection of lists for the active sheetDim L As ListObjects
Sheets("ReportRefresh").Select
ActiveSheet.Cells.Clear
Set L = ActiveSheet.ListObjects
' Add a new listDim NewList As ListObject
Set NewList = L.Add(xlSrcRange, Range("A1:K2"), , True)
Cells(1, "A").Value = "Title"
Cells(1, "B").Value = "FileVersion"
Cells(1, "C").Value = "CustomerName"
Cells(1, "D").Value = "RegionName"
Cells(1, "E").Value = "InWarranty"
Cells(1, "F").Value = "ProductType"
Cells(1, "G").Value = "SubDivisionName"
Cells(1, "H").Value = "SiteName"
Cells(1, "I").Value = "Entitlement"
Cells(1, "J").Value = "reportingPeriod"
Cells(1, "K").Value = "RunTime"
Cells(2, "A").Value = "test"
Cells(2, "B").Value = Sheets("Instructions").Cells(3, "b").Value
Cells(2, "C").Value = Sheets("Instructions").cmboCustName.Text
Cells(2, "D").Value = Trim(Sheets("Instructions").cmboRegion.Text)
Cells(2, "E").Value = Sheets("Instructions").cmboSupportWarranty.Text
Cells(2, "F").Value = Trim(Sheets("Instructions").cmboProdType.Text)
Cells(2, "G").Value = Trim(Sheets("Instructions").cmboSubDivision.Text)
Cells(2, "H").Value = Trim(Sheets("Instructions").cmboSite.Text)
Cells(2, "I").Value = Trim(Sheets("Instructions").cmboEntitlement.Text)
Cells(2, "J").Value = Trim(Sheets("Instructions").cmboReportingPeriod.Text)
Cells(2, "K").Value = "10"
NewList.Name = "Report Refresh"' Publish it to a SharePoint site
NewList.Publish Array("http://intranet/dept/glblsptsvc/Reports/_layouts/viewlsts.aspx?BaseType=0", _
"NewLists "), TrueEnd Sub
the sharepoint list already exists so all I want to do is amend a record to the end of the list.


Sub UpdateSpecificCells()

'If nobody has the file checked out
If Workbooks.CanCheckOut("http://excel-pc:43231/Shared Documents/ExcelList.xlsb") = True Then
Application.DisplayAlerts = False

'Open the file on the SharePoint server
Workbooks.Open Filename:="http://excel-pc:43231/Shared Documents/ExcelList.xlsb", UpdateLinks:=xlUpdateLinksNever


ActiveSheet.Cells(2, 7).Value = 100
ActiveSheet.Cells(3, 7).Value = 200
ActiveSheet.Cells(4, 7).Value = 300


'Close the workbook
Workbooks("ExcelList.xlsb").Save
Workbooks("ExcelList.xlsb").Close

End If
End Sub

Walkthrough: Creating Connectable Web Parts in SharePoint Foundation

This programming task describes how to create two connectable Web Parts: a Web Part that provides a string and another Web Part that consumes and displays the value of that string.
This walkthrough illustrates the following tasks:
  1. Creating an interface to define the string that is being provided.
  2. Creating a Web Part by using the Microsoft Visual StudioWeb Part item template.
  3. Creating a provider Web Part that defines a string.
  4. Creating a consumer Web Part that uses and displays the string.
  5. Creating a Web Parts page and connecting the provider and consumer Web Parts.
For a related code sample, see Creating Connectable Web Parts in SharePoint Foundation. For a related video demonstration, see Creating Connectable Web Parts in SharePoint Foundation.
Important note Important
The Web Part infrastructure in Microsoft SharePoint Foundation is built on top of the Microsoft ASP.NET Web Part infrastructure, and Web Parts that derive from the ASP.NETWebPart class are completely supported in SharePoint, including the ASP.NET connection model. Whenever possible, you should create ASP.NET Web Parts, and use the ASP.NET connection model to connect your Web Parts.
For more information about choosing the best WebPart base class from which to derive, see Creating Web Parts in Windows SharePoint Services. For more information about ASP.NET Web Parts and connection model, see Web Parts Connections Overview in the ASP.NET documentation.
You need the following components to complete this walkthrough:
  • Visual Studio 2010 Professional or an edition of Visual Studio Application Lifecycle Management (ALM).
  • SharePoint Foundation 2010 or SharePoint Server 2010.
  • Windows Server 2008 or Windows Server 2008 R2.
This programming task defines the process of creating a Visual Studio solution to develop and deploy the interface, provider Web Part, and consumer Web Part.

To create an Empty SharePoint Project

  1. Start Visual Studio 2010 in administrator mode.
  2. On the File menu, point to New, and then click Project. If Visual Studio is set to use Visual Basic development settings, on the File menu, click New Project.
  3. In the New Project dialog box, expand the SharePoint node under the language that you want to use, and then select the 2010 node.
  4. In the Templates pane, select Empty SharePoint Project.
  5. For the name of the project, type ConnectableWebParts, and then click OK.
  6. In the What local site do you want to use for debugging? drop-down list, select the local site that you want to use for debugging.
  7. Select Deploy as a farm solution, and then click Finish.
This programming task defines the process of creating a class that implements all of the necessary methods and events for a connection interface.

To create an interface

  1. In Solution Explorer, click the ConnectableWebParts project.
  2. On the Project menu, click Add New Item.
  3. In the Installed Templates pane, click Code.
  4. Click Interface.
  5. Type ITextBoxString for the name of the interface, and then click Add.
  6. In the ITextBoxString.cs or ITextBoxString.vb code file, mark or verify that the ITextBoxString class is public.
    public interface ITextBoxString
    
  7. Replace the interface with the following code to define the string member of this interface.
    public interface ITextBoxString
    {  
        string TextBoxString { get; set; }
    }
    

To test the code

  • On the Build menu, click Build ConnectableWebParts (Visual Basic) or click Build Solution (Visual C#).
    The solution builds without errors.
The following procedure demonstrates how to create a Web Part that provides a string for other Web Parts to consume.

To create a provider Web Part

  1. In Solution Explorer, click the ConnectableWebParts project.
  2. On the Project menu, click Add New Item.
  3. In the Installed Templates pane, expand the SharePoint node, and then click 2010.
  4. Click Web Part, type StringProvider for the name of the Web Part, and then click Add.
  5. In the StringProvider.cs or StringProvider.vb code file, add the following code to indicate that the StringProvider class implements the ITextBoxString interface.
    public class StringProvider : WebPart, ITextBoxString
    
  6. Add the following code to create a text box, a string, and a button.
    private TextBox myTextBox;
    private String _textBoxString = String.Empty;
    private Button myButton;
    
  7. Implement the get and set methods of the ITextBoxString interface by adding the following code.
     [Personalizable()]
    public string TextBoxString
    {
        get
        {
            return _textBoxString;
        }
        set
        {
            _textBoxString = value;
        }
    }
    
    
  8. To add the text box and button to the Web Part, replace the CreateChildControls method with the following code. The code clears all the controls from the Web Part, instantiates a control, and then adds the new control to the Web Part.
    protected override void CreateChildControls()
    {
        Controls.Clear();
        myTextBox = new TextBox();
        Controls.Add(myTextBox);
    
        myButton = new Button();
        myButton.Text = "Change Text";
        Controls.Add(myButton);
        myButton.Click += new EventHandler(myButton_Click);
    }
    
  9. Add the following code to handle the Click event for the button that you added in the previous step.
    void myButton_Click(object sender, EventArgs e)
    {
        if (myTextBox.Text != String.Empty)
        {
            TextBoxString = myTextBox.Text;
            myTextBox.Text = String.Empty;
        }
    }
    
  10. Create a method to return the ITextBoxString object to share with other Web Parts. Apply the ConnectionProviderAttribute attribute to identify the callback method that acts as the provider in a Web Parts connection.
     [ConnectionProvider("Provider for String From TextBox", "TextBoxStringProvider")]
    public ITextBoxString TextBoxStringProvider()
    {
        return this;
    }
    

To test the code

  • On the Build menu, click Build ConnectableWebParts (Visual Basic) or click Build Solution (Visual C#).
    The solution builds without errors.
The following procedure demonstrates how to create a Web Part that consumes and displays a string from a provider Web Part.

To create a consumer Web Part

  1. In Solution Explorer, click the ConnectableWebParts project.
  2. On the Project menu, click Add New Item.
  3. In the Installed Templates pane, expand the SharePoint node, and then click 2010.
  4. Click Web Part, type StringConsumer for the name of the interface, and then click Add.
  5. In the StringConsumer.cs or StringConsumer.vb code file, add the following code to create objects for an ITextBoxString provider and a text box.
    private ITextBoxString _myProvider;
    private Label myLabel;
    
  6. Change the text of the label to the string from the StringProvider class by adding the following code. This code first verifies that the provider is not null and then sets the label text to the string from the provider Web Part.
    protected override void OnPreRender(EventArgs e)
    {
        EnsureChildControls();
        if (_myProvider != null)
        {
            myLabel.Text = _myProvider.TextBoxString;
        }
    }
    
  7. To add the label to the consumer Web Part, replace the CreateChildControls method adding the following code. The default text is added to indicate if the consumer Web Part is connected to the provider Web Part.
    protected override void CreateChildControls()
    {
        Controls.Clear();
        myLabel = new Label();
        myLabel.Text = "Default text";
        Controls.Add(myLabel);
    }
    
  8. Create a method to assign the ITextBoxString object from the provider Web Part to the private ITextBoxString object in this consumer Web Part. Apply the ConnectionConsumerAttribute attribute to identify the callback method acting as the consumer in a Web Parts connection.
     [ConnectionConsumer("String Consumer", "StringConsumer")]
    public void TextBoxStringConsumer(ITextBoxString Provider)
    {
        _myProvider = Provider;
    }
    

To test the code

  • On the Build menu, click Build ConnectableWebParts (Visual Basic) or click Build Solution (Visual C#).
    The solution builds without errors.
The following procedure demonstrates how you can connect the two Web Parts.

To connect the provider and consumer Web Parts

  1. In Visual Studio, press F5.
    A browser window opens to the SharePoint server on the development computer.
  2. Click Site Actions, and then click More Options.
  3. In the Create page, click Web Part Page, and then click Create.
  4. In the New Web Part Page page, type ConnectableWebParts as the name, and then click Create.
  5. Click Add a Web Part in any zone on the Web Parts page.
  6. In the Categories pane, click Custom.
  7. Click StringProvider, and then click Add.
    The Web Part is added to the page, and displays a text box and a Change Text button.
  8. Click Add a Web Part in any zone on the Web Parts page.
  9. In the Categories pane, click Custom.
  10. Click StringConsumer, and then click Add.
    The Web Part is added to the page, and displays Default Text.
  11. Click the StringConsumer Web Part, and then click the drop-down arrow in the upper-right section of the Web Part.
  12. In the verbs menu, point to Connections, point to Get String Consumer From, and then click String Provider.
    The StringConsumer Web Part is connected to the StringProvider Web Part, and the Default Text label goes away.
  13. In the StringProvider Web Part, type text into the text box, and then click Change Text.
    The typed text appears as the label. For example, if you typed “This is a new label” in the StringProvider Web Part, the StringConsumer Web Part also displays “This is a new label”.
  14. In the ribbon, on the Page tab, click Stop Editing.

Securing Web Parts in SharePoint Foundation

Web Parts in Microsoft SharePoint Foundation provide a powerful way for users to interact with other systems. SharePoint Foundation has built-in security settings to restrict the access that a Web Part has to underlying systems. A developer can create custom security policy files to give a Web Part greater access to the underlying system
Web Parts can also be created in a sandboxed solution. By default, a sandboxed solution has restricted access to the underlying system. This provides greater security and monitoring of the Web Part. For more information about sandboxed solutions, see Sandboxed Solutions in SharePoint 2010.
Code Access Security (CAS) is a resource-constraints policy that limits the access that an assembly has to protected system resources and operations. SharePoint Foundation has built-in security policies built on top of the built-in security policies of ASP.NET. By default, SharePoint Foundation uses a minimal set of permissions in order to protect the server and underlying infrastructure from malicious code.
If your Web Part needs greater access than what is provided in the minimal settings, there are a number of ways to increase the permissions of your Web Part, but only one is recommended. You can create a custom CAS policy for your Web Part, or increase the overall trust level of the server farm in the web.config file. This is a security risk and is not recommended. For more information about deployment, see Deploying Web Parts in SharePoint Foundation.
SharePoint Foundation is a partial trust application by default. SharePoint Foundation can use the ASP.NET built-in trust levels but defines trust levels of its own:
  • WSS_UserCode
  • WSS_Minimal
  • WSS_Medium
These trust levels extend the ASP.NET trust levels for use with SharePoint Foundation. Trust levels are defined in policy files that can be found on the file system of each Web server.
Important   By default, the built-in SharePoint Foundation policy files in SharePoint Foundation, named wss_usercode.config, wss_minimaltrust.config, and wss_mediumtrust.config, are found in %ProgramFiles%\Common Files\Microsoft Shared\web server extensions\14\CONFIG directory.
By default, SharePoint Foundation applies the WSS_Minimal trust level for the virtual server. This trust level grants all of the permissions in the ASP.NET Minimal trust as well as Web Part connections. The WSS_Minimal policy restricts the Web Part from accessing many resources for advanced operations, including the object model and file operations.
The WSS_Medium trust level grants greater access to the environment. Also, WSS_Medium allows access to the SharePoint Foundation object model and file operations including read, write, append, and path discovery. This trust level also allows access to environment variables.
The following table outlines the specific permissions granted with the WSS_Medium, WSS_Minimal and WSS_UserCode policy files in the ASP.NET 2.0 environment.
PermissionWSS_Medium
Trust Level
WSS_Minimal
Trust Level
WSS_UserCode (SandBoxed Solutions)
Trust Level
System.Web.AspNetHostingPermissionMediumMinimalMinimal
System.Net.DnsPermissionUnrestricted=”True”NoneNone
System.Security.Permissions.EnvironmentPermissionRead=”TEMP; TMP;USERNAME;OS;COMPUTERNAME”NoneNone
System.Security.Permissions.FileIOPermissionRead, Write, Append, PathDiscovery, Application DirectoryNoneNone
System.Security.Permissions.IsolatedStorageFilePermissionAssemblyIsolationByUser, Unrestricted UserQuotaNoneNone
PrintingPermissionDefault printingNoneNone
System.Security.Permissions.SecurityPermissionAssertion, Execution, ControlThread, ControlPrincipal, RemotingConfigurationExecutionExecution
Microsoft.SharePoint.Security.SharePointPermissionObjectModel=”True”NoneObjectModel=”True”, UnsafeSaveOnGet=”True”
System.Net.Mail.SmtpPermissionAccess=”Connect”NoneNone
SqlClientPermissionUnrestricted=”true”NoneNone
WebPartPermissionConnections=”True”Connections=”True”None
WebPermissionConnect to origin host (if configured)NoneNone
Note Note
For more information about Code Access Security, see Using Code Access Security with ASP.NET and also Security Guidelines for .NET Framework 2.0.
SharePoint Foundation has the ability to deploy a CAS policy file with a solution. We recommend that you use the permissions for sandboxed solutions as listed in the wss_usercode.config file, but you can also create custom permissions for your Web Parts and use SharePoint Foundation to handle the deployment.
The following code example shows the basic structure of a CAS policy file in a SharePoint Foundation solution package.
<CodeAccessSecurity>
   <PolicyItem>
     <PermissionSet 
      class="NamedPermissionSet" 
      version="1"
      Description="Permission set for custom test WebParts">

        <IPermission 
          class="AspNetHostingPermission" 
          version="1" 
          Level="Minimal" 
        />

        <IPermission 
          class="SecurityPermission" 
          version="1" 
          Flags="Execution" 
        />

        <IPermission 
          class="Microsoft.SharePoint.Security.SharePointPermission, 
            Microsoft.SharePoint.Security, version=11.0.0.0, 
            Culture=neutral, PublicKeyToken=71e9bce111e9429c" 
          version="1" 
          ObjectModel="True" 
         />

        <IPermission 
          class="System.Net.WebPermission, System, 
            version=1.0.5000.0, Culture=neutral, 
            PublicKeyToken=b77a5c561934e089" version="1">
          <ConnectAccess>
            <URI uri="https?://.*" />
          </ConnectAccess>
        </IPermission>

        <IPermission 
          class="System.Security.Permissions.SecurityPermission, 
            mscorlib, version=1.0.5000.0, Culture=neutral, 
            PublicKeyToken=b77a5c561934e089" 
          version="1" 
          Flags="ControlThread, UnmanagedCode" 
        />

        <IPermission 
          class="System.Security.Permissions.EnvironmentPermission, 
            mscorlib, version=1.0.5000.0, Culture=neutral, 
            PublicKeyToken=b77a5c561934e089" 
          version="1" 
          Read="UserName" 
        />

     </PermissionSet>
     <Assemblies>
       <Assembly PublicKeyBlob=PublicKeyBlob />
     </Assemblies>
   </PolicyItem>
</CodeAccessSecurity>

The list below includes some general guidelines that apply when you use a <CodeAccessSecurity> section in your solution manifest.
  • There can only be one <CodeAccessSecurity> per solution manifest.
  • There can be multiple <PolicyItem> nodes.
  • Every <PolicyItem> node can only contain one <PermissionSet> node.
  • Every <PolicyItem> node can only contain one <Assemblies> node.
  • Each <PermissionSet> node can contain multiple <IPermission> nodes.
  • There can be multiple <Assembly> nodes under the <Assemblies> node.
For more information about the schema of the <CodeAccessSecurity> area, see CodeAccessSecurity Element (Solution).
When you deploy your assembly using a custom CAS policy, you must use the -CASPolicies option with SharePoint Management Shell. The command is as follows:
Install-SPSolution –Identity <insert name> -CASPolicies <true/false>