Thursday 23 December 2010

Manipulating web.config file programmatically

To modify/add a web config entry following code can be referred

// Get the SPSite object
SPSite site = new SPSite("URL");
if (site != null)
{
SPWebApplication webApp = site.WebApplication;
// Create the modification entry
SPWebConfigModification webEntry = new SPWebConfigModification("Web Config entry " ,"Entry location" );
// Add the web config entry to the collection
webApp.WebConfigModifications.Add(webEntry);
webApp.Farm.Services.GetValue().ApplyWebConfigModifications();
}

Web Config Entry could be

"SafeControl[@Assembly="MyAssembly"][@Namespace="My.Namespace"]"
+ @"[@TypeName="*"][@Safe="True"][@AllowRemoteDesigner="True"]"


Entry location could be

configuration/SharePoint/SafeControls

Wednesday 15 December 2010

Could not load file or assembly CustomMarshalers

Recently, I came across a weird issue while running the code in different environment.

Suddenly I started getting "Could not load file or assembly CustomMarshalers" at certain line of my code. It was difficult to understand why same code is not running in new environment. I investigated a bit and found that "CustomMarshalers" is required for compact framework which is not at all useful in my application. Ii couldn't found any solution except changing my code.

1. I had used LINQ queries at few places in my application so i had to change it to CAML query to run in all the environment

2. Wherever I was using "foreach" block and using Sharepoint object collection like SPListItemCollection, I was getting mentioned error. So I had replace all the "foreach" blocks with "for" construct.

I hope these information may help somebody....

Backup and restore using powershell command

Backup

backup-spsite -identity "site-collection-path" -path "backup-location"

where

site-collection-path : http://machinename:port/sites/sitecollectionname

backup-location : D:/backup/site.bak


Restore

restore-spsite -identity "site-collection-path" -path "backup-location" -Force

Note: You can not restore more than one site collection in a web application so you have to create a new database. Below command can be used to overcome this issue.

restore-spsite -identity "site-collection-path" -path "backup-location" -Force -DatabaseName "DBNAME"


To Create a new Database follow below instruction

Goto Central Administration---> Manage Content Databases-->Add New Content Database

Monday 13 September 2010

This view cannot be displayed because the number of lookup and workflow status columns it contains exceeds the threshold (8) enforced by the admin..

Issue:

This view cannot be displayed because the number of lookup and workflow status columns it contains exceeds the threshold (8) enforced by the administrator

Solution

Sharepoint 2010 has default "Resource Throttling" settings. Due to which this warning would be encountered. To overcome this warning, we can increase the number of lookup columns in following ways.


* Goto --> Application Management --> Manage Web Application.
* Select your web application.
* General Settings (on Ribbon window) --> Resource Throttling.
* Resource Throttling window, goto "List View Lookup Threshold" and give the value as per your requirement.

Tuesday 31 August 2010

Alternative of using _spBodyOnLoadFunctionNames

I am very sure that most of the Sharepoint developers must have used _spBodyOnLoadFunctionNames to inject javascript methods on the sharepoint list forms(NewForm/EditForm/DispForm).

Downside of using _spBodyOnLoadFunctionNames is the time taken to execute my javascript function. Even though my function is very small, there is delay in executing my method.

Reason for the Delay:

Delay occurs because sharepoint first loads all the controls on the form and subsequently executes the embedded javascript functions. So if number of controls are high, it will take substantial time to execute my custom javascript method. Delay would be more in case of Sharepoint 2010 pages because it has more number of inbuilt javascript functions to execute while loading the page.

Solution:

In order to avoid the delay we have to execute our function "onload" event of any control and following steps can be considered to achieve this functionality.

1. Create your javascript function
function MyMethod()
{
// My method logic
}

2.Create a "img" element anywhere on your page(Since we can not capture "onload event" of most of the controls).
3. Set the image source to "/_layouts/images/blank.gif" so that nothing is visible on the page.

4. Call your javascript function on "onload event of the img.


<IMG SRC="/_layouts/images/blank.gif" width="1" height="18" onload="MyMethod();"/>

Note: Mentioned issue is quite visible in case you are trying to hide/show some buttons/controls of the page on load of the page.

Thursday 26 August 2010

Create ListItem using Client Object Model

Client Object model is very powerful feature of Sharepoint 2010.
You can use Client object model from remote computer to access sharepoint site and do CRUD operation.

Below is the sample code to create listitem using Sharepoint client object model.

// Create ClientContext Object
using (ClientContext clientContext = new ClientContext("http://sitename"))
{
// Give the credential
clientContext.Credentials = new System.Net.NetworkCredential("username", "password", "domainname");
Web site = clientContext.Web;
List list = clientContext.Web.Lists.GetByTitle("ListName");
// To use site object load it first
clientContext.Load(site);
ListItemCreationInformation itemCreateInfo = new ListItemCreationInformation();
ListItem listItem = list.AddItem(itemCreateInfo);
listItem["Title"] = "Created through Client Object Model";
listItem.Update();
// Execute the query to push data on the server.
clientContext.ExecuteQuery();
}

Tuesday 24 August 2010

Error: System.IO.FileNotFoundException in client application

Recently, I was trying to create a console application and using Sharepoint object Model. My console application and sharepoint web application was on the same machine.
While creating the SPSite object I was getting following error.

"The Web application at http://sitename/ could not be found. Verify that you have typed the URL correctly. If the URL should be serving existing content, the system administrator may need to add a new request URL mapping to the intended application."

The error was very much misleading, after struggling a bit I found that by default client application's platform target was set to X86 i.e 32 bit so it was not able to access the webapplication which is targeted as 64 bit. So to overcome this issue I had to change my platform target to "AnyCPU" or X64.

Ironically, it was working fine when I was using "Sharepoint Client Object Model"

Saturday 21 August 2010

What is Restricted/Allowed under Sandboxed Solutions

You can target your solution as sandboxed only if all of your solution component fall within following SharePoint items:

 Web Parts (code only; not visual Web Parts)
 Event receivers
 Content types
 List templates
 List instances
 Custom actions
 InfoPath forms

You can not target your solution as sandboxed, in case any of your solution components fall within following SharePoint items:

 Visual Web Parts (they contain web controls that have to be deployed to disk)
 Business data connectivity models
 Application pages
 User controls
 Call web services in an intranet or over the Internet
 Access data outside the site collection where the solution has been deployed
 Read and write files with your code
 Run code that is not marked to allow partially trusted callers
 Use objects above SPSite (e.g., SPFarm)
 Use security-related functions (RunWithElevatedPreviledges)
 Impersonation of Users
 Custom Workflow or programmatically invoking SharePoint Designer workflow
 Programmatically accessing Taxonomy data/ Metadata Management


Looking at the above allowed/restricted items, it is quite evident that Sandbox solutions would provide more security and control but lesser features. Whereas farm based solution would not restrict any thing but it would developer’s prerogative to handle the security and avoid malicious code, which would result into more number of code reviews and unit testing

Opening the Sandbox

Few months back when I started exploring Sharepoint 2010, I was spellbound of so many new features like Metadata Management, Developer Dashboard,Powershell integration,Client Object Model, great development environment through Visual Studio 2010 and one of them is Sandbox Solution. At first glance Sandbox Solutions looked really great to me.

Why Sandbox came into picture

Earlier to Sharepoint 2010, if you are creating a sharepoint application using Sharepoint Object Model, code needs to be thoroughly reviewed and tested before it goes to Production Server to avoid any malicious code. Testing and code review is a big effort which is directly proportional to number of features or LOC of my application. I found Sandbox Solutions to be a real solution to the mentioned problem. Also it provides a good peace of mind to Sharepoint administrator because now they can do better monitoring and resource allocation per Site Collection. Apart from this they can validate the solution before it gets deployed.

After digging more I found that Sandbox Solutions are great but it can’t cater to all kind of Sharepoint applications.Sandboxed solutions run with lower trust level for hosted environments. A sandboxed solution cannot access the full SharePoint object model; it is limited to a subset of the Microsoft.SharePoint namespace. Sandboxed solutions run in a safe and monitored process with restricted access to resources.

Tuesday 17 August 2010

How to impersonate Site administrator privileges

When we run a piece of code within SPSecurity.RunWithElevatedPrivileges, it run in context with Sharepoint System account. So if you want to run a piece of code under a specific user account/role we have to impersonate that specific user account.

To impersonate a specific user, you need the usertoken of the impersonated user and you have to pass it while creating the SPSite object.

SPUserToken userToken = Web.SiteAdministrators["loginname"].UserToken;
using(SPSite site = new SPSite("SiteURL", userToken))
{
SPWeb Web = mySite.RootWeb;
// Perform activities which require administrative privileges

}

Friday 4 June 2010

Deployment Error on Sandbox Solution while deploying web part

Error:

Error occurred in deployment step 'Activate Features': Timeout occurred while running the SharePoint Sandboxed Code service. This service is required to run sandboxed solutions in SharePoint. Please ensure the service is configured correctly in SharePoint


Solution

Goto Services and start "Sharepoint 2010 User Code Host" Service

Wednesday 2 June 2010

Calling a Web Service in Sandbox Solution

In order to call a web service in sandbox environment following steps should be followed.

Note: Assuming you already have created the web service and deployed it in IIS

1. Create a class library project and which is derived from “SPProxyOperation” (Microsoft.SharePoint.UserCode namespace).


Code Snippet

class ProxyProvider : SPProxyOperation
{
public override object Execute(SPProxyOperationArgs args)

{

if
(args != null)
{

ProviderSoapClient client = new ProviderSoapClient();

ProviderArgs providerArgs = args as ProviderArgs;

return client.GetDepartmentByCode(providerArgs.DeptCode);

}

else

{

return "Error while calling Web Service...";

}

}

}

2. Create another class which should be used for passing arguments to the SPProxyOperation class



Code Snippet

[Serializable]

public class ProviderArgs : SPProxyOperationArgs
{
public int DeptCode
{
get;
set;
}
public ProviderArgs(int code)
{
this.DeptCode = code;
}
}

3. Argument class must have “Serializable” attribute.

4. Implement Execute method of SPProxyOperation class.

5. Attach below attribute with the assembly

[assembly:System.Security.AllowPartiallyTrustedCallersAttribute()]

6. Make sure assembly is strongly named.

7. Deploy the assembly in GAC using GACUTIL(Since drag and drop assembly gives access denied error).

8. Register the assembly in Sharepoint

To register a assembly in Sharepoint “Power Shell” can be used.

Write below scripts in a .ps1 file and run from power shell

Param($assemblyName, $typeName)

$userCodeService = [Microsoft.SharePoint.Administration.SPUserCodeService]::Local

$proxyOperationType = new-object -typename Microsoft.SharePoint.UserCode.SPProxyOperationType -argumentlist $assemblyName, $typeName

$userCodeService.ProxyOperationTypes.Add($proxyOperationType)

$userCodeService.Update()

9. Since this is full trust proxy class so it would run under “SPUCWorkerProcessProxy.exe” so add the web service related configuration setting in SPUCWorkerProcessProxy.exe.config file which can be found under “C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\UserCode” folder.

10. Now you are ready to call the web service method via Proxy operation class. Use below method to call the web service from your Sandbox Solution.


SPUtility.ExecuteRegisteredProxyOperation("AssemblyName, Version=1.0.0.0, Culture=neutral, PublicKeyToken=fffdd72d4537ce50", "NameSpace.ClassName", new ArgumentClass(Argument));

Query List/Document Library in Specific Folder

To query SharePoint List or Document Library in specific Folder “ FolderServerRelativeUrl ” as part of the CAML Query Code Snippet ...