Wednesday, June 16, 2010

Creating site columns thorugh SQL query

Sometimes, you may feel pain while creating site columns and content types through CAML, because you need to know CAML syntax for each and every site column data type, but you can avoid this by simply running one sql query

Normally in SharePoint when we create any site column or content type through SharePoint user interface that will go and stored into content database in the form of CAML, so we can run simple sql query and get that data and build it into features and deploy the same in some other environment means production

Steps

1. create sitecoumns and content types using SP user interface

2. connect to sql server database

3. Execute below query

"Select definition from content types where definition is not null"

4. you can see all site columns and content types in form CAML

5. just extract that and build a features and deploy

Friday, June 11, 2010

Access denied error when code runs with SPsecurity.RunWithElevatedPriviliges

Today, while reviewing code ,I have found some thing, which will give access denied error if our code runs with SPSecurity.RunWithElevatedPriviliges and AllowUnsafeUpdates = true

Check the piece of code which I have written below that gives access denied error

using (SPSite site = new SPSite(SPContext.Current.Web))
{
SPList list = web.Lists[listUrl];
SPFieldCollection fieldCol = list.Fields;
SPListItem newItem = list.Items.Add();
foreach (SPField field in fieldCol)
{
if (!field.Hidden && !field.ReadOnlyField)
{
if (field.Title.Equals(question, StringComparison.OrdinalIgnoreCase))
{
newItem[field.Title] = answer;
web.AllowUnsafeUpdates = true;
newItem.Update();
web.AllowUnsafeUpdates = false;
break;
}
break;
}
}
}

The main problem here is that the current request will execute under the priviligies of anonymous user credentials because user is a anonymous user, so this code always gives access denied error

The web object is created using SPContext, so this web object is runs under credentials of spcontext, so this always gives problem

using (SPSite site = new SPSite(SPContext.Current.Site.ID))
{
using(SPWeb web = site.OpenWeb())
{
SPList list = web.Lists[listUrl];
SPFieldCollection fieldCol = list.Fields;
SPListItem newItem = list.Items.Add();
foreach (SPField field in fieldCol)
{
if (!field.Hidden && !field.ReadOnlyField)
{
if (field.Title.Equals(question, StringComparison.OrdinalIgnoreCase))
{
newItem[field.Title] = answer;
web.AllowUnsafeUpdates = true;
newItem.Update();
web.AllowUnsafeUpdates = false;
break;
}
break;
}
}
}
}

The above code will run under credentials of system account that means with full permissons so this will execute fine here the difference is we are creting spsite object with url not from current context and the SPsecurity.RunWithElevatedPriviges will work fine here

Sunday, February 28, 2010

Another reusable component - Site Columns and Content Type generator

I have seen so many people struggling to create sitecolumns and contenttypes in CAML format while developing sharepoint aplications. Some people spend days to complete these and some people spend hours depends on their knowledge on sharepoint, recently I have created webpart which will give sitecolumns and contenttypes in the form of CAML the main advantage of this is you will get complete features folder

you just need to deploy this into ur 12 hive features folder just install and activate

I just completed beta version of this webpart need to test and upload this into my blog

I hope this will save lot of time for each and every developer, min 1hour

First create your site columns using sharepoint GUI

Creating Site Columns

Site Actions

Modify All settings

Galleries

Site Columns

Create

Enter Column name , choose appropriate data type and click on create

This will create site column for you in sharepoint create as many you want

Creating Site Content Types

Site Actions

Modify All settings

Galleries

Site Content Types

Create

Provide Name and click on ok, this will create your content type

Adding columns to the content type

Go to content type gallery

Select content type the one which you created recently

Click on add from existing site columns

Select site columns and click on Ok

This will create content types for you

Now install RSM.Exporter webpart on respective webapplication

Add that webpart in any page of ur web application the webpart will dispaly as shown in fig



you just enter your site column feature name on site columns textbox and provide description for your feature and do same thing for site content types also and click on create sitecolumns and content types feature button

Now go to your "C://" drive and check "RsmmTechno" folder there you can find two folders one is for site columns and another one is for content types

So we have successfully completed creation of site columns and content types features now we need to create a page layouts based on content types

Steps to create page layouts :

Select content type which you want to attach to the page layout from content type drop downlist

Enter page layout feature name

Enter page layout name

Select fields which you want to render while creating page using page layout from the list box

Click on create page layout feature

Once again go to your "C://" drive and check "RsmmTechno" folder there you can find page layout feature along with site columns and content type as shown in below fig



Just open each and every folder you can find feature.xml file and element.xml files as shown in below fig







Now, Install and activate features



Create a page using page layout




I think this will help you guys a lot, no need of breaking heads what is the syntax for this sitecolumn content type and page layout etc...

Wednesday, February 24, 2010

Deploying Custom Resource files into "App_GloablResources"

Normally, when you create new webapplication in sharepoint the system will automatically copies all resources files from \\12\Config\Resources folder to respective webapplication Virtual directory "App_GlobalResources" folder this will work fine in normal scenarios, so in deployment you can just place your custom resources files into 12 hive Resources folder and create webapplication everything will work fine

But some times we may have to install some kind of upgradion packages with out affecting existing system which contains custom resource files? What would be the approach if we want to place all custom resources files into already created webapplication???

Options to deploy resources files in existing webapplication

1. We have to create deployment document and saying that copy and paste all the files into "App_GlobalResurces" folder

2. Create a separate feature and while activating that feature write a code to copy and paste all the files from feature folder to "App_GlobalResources" folder

Personally I prefer second approach

Please check below image to find out folder structre and where all resource files are placed



Just create feature with event receiver class in the FeatureActivated event write below code

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using System.IO;
using Microsoft.SharePoint.Utilities;
namespace RSMTechno.DeployGlobalResources
{
class DeployGlobalResources : SPFeatureReceiver
{

public override void FeatureActivated(SPFeatureReceiverProperties properties)
{

string sourcePath = string.Empty;
SPSite site = (SPSite)properties.Feature.Parent;
SPWeb web = site.OpenWeb();
//sourcepath is the path where all resource files are stored
sourcePath = string.Format("{0}\\FEATURES\\{1}\\", SPUtility.GetGenericSetupPath("TEMPLATE"), properties.Definition.DisplayName);
try
{
SPWebApplication webApp = web.Site.WebApplication;

foreach (SPUrlZone urlZone in webApp.IisSettings.Keys)
{
SPIisSettings settings = webApp.IisSettings[urlZone];
string destinationPath = Path.Combine(settings.Path.ToString(), "App_GlobalResources");
string[] filePaths = Directory.GetFiles(sourcePath, "*.resx");
foreach (string filePath in filePaths)
{
string fileName = Path.GetFileName(filePath);
File.Copy(filePath, Path.Combine(destinationPath, fileName), true);
}

}
}
catch (Exception)
{
throw new Exception("Failed to copy files");
}
}
}
}

Then build the application and deploy and activate the feature everything will work fine

Click here to download source code RSMTechno.DeployGlobalResourceFilesCode

Friday, January 8, 2010

Why people are not using sharepoint designer?

I have seen some people,they are not interested to use sharepoint desinger I dont know why? even though they are not familiar with syntaxs of sharepoint webcontrols , field contrls while desingning page layouts, customizing master pages and sharepoint controls

I dont know about other sharepoint developors, but whenever I get chance I love to use sharepoint desinger to customize my pages

Because if we use sharepoint desinger our development will be faster, no need of sitting on Visual Studio and breaking head for syntaxs(not only for syntaxs it provides lot of other features like workflows,reporting, data view webparts etc...)

Recently I asked one sharepoint senior developer why you are not using sharepoint desinger for designing the pagelayouts?

I got very silly answer that he feels that when we edit page using sharepoint designer that will go and sit in to content database

Yes his answer is correct but in which situation, when we save the page and checked- in

But in production we are going to deploy all these things as a separate features so there will not be any problem regarding perfomrance point of view

Think how much time it will take to develop same in VSIDE, personally I am 100% sure that it will take more time to design a page using VSIDE, when we compare with sharepoint desinger if you are not familiar with sharepoint designer

So guys please use sharepoint designer to make your share point development faster

Soon you will except some good stuff on sharepoint designer

Saturday, December 19, 2009

SharePoint Solution Architecture

Solution Architecture

I am just going to share my thoughts on creating solution architecture for sharepoint application

Here I have created so many projects don't scare, you can change this according to your requirements

Normally I split solution based on requirements, but I would like to discuss general approach for SharePoint projects based on my knowledge I hope this will help you at least some part of your application




RSMTechno.CodeBehind
RSMTechno.Common
RSMTechno.Controls
RSMTechno.DataAccessLayer
RSMTecno.SolutionDemo
RSMTecno.BusinessLayer

RSMTechno.CodeBehind

I have created some page layouts and master page and deployed in to SharePoint environment , later I felt that I wanted to add some code to the master page to customize navigation bar…or some code to the sitepages,here I strucked because by default SharePoint will not generate code behind files to master page and site pages

So what I have to do?

Either I have to write inline code or I have to create separate class library and attach it to the master page or site pages

Suppose if I write inline code to the page and run the application everything works fine but if I customize the page using SharePoint designer and run the application there the problems comes because in SharePoint the customized page run through the safe mode parser, which will block any inline code from running

So what is the solution for this? what we have to follow to resolve this?

We need to follow second approach .

We have to create separate class library and register that in page using register tag , our RSMTechno.CodeBehind libarys is created for that it contains all the class files inherited from Microsoft.SharePoint.Publishing.PublishingLayoutPage or System.Web.UI.MasterPage or Sytem.web.UI.WebPartPage

Check the sample code provide below

Layout Page

using System;
using System.Web.UI;
using Microsoft.SharePoint.Publishing;

namespace RSMTechno.Pages {
public class RSMLayoutTemplate : PublishingLayoutPage {
}
}

WebPartPage


using System;
using System.Web.UI;
using Microsoft.SharePoint.Publishing;

namespace RSMTechno.Pages {
public class RSMWebPartPage: WebPartPage
{
}
}


RSMTechno.Common

This application is created mainly for utility methods and common functionally across all the functionality's like utility classes(ProfileUtility etc...)

RSMTechno.Controls

This library project is created mainly for creating custom controls
While creating webparts I prefer that first create custom control and create object for that in your webpart class ,the main advantage of this is in future suppose if your client want to shift to .net based application because of some reasons, he can easily move in to .net application because you have developed all the components using webcontrol class so you can reuse same controls in your .net application

Sometimes you may need to override dropdownlist or datagrid or any .net control to provide reusability you can use this project to handle such kind of exteded controls

I have provided sample code here

Custom Controls

Normal Custom Cotntrol

using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace RSMTechno.Controls
{
[ToolboxData("<{0}:DemoControl =server>")]
public class DemoControl : WebControl
{
//create your control
protected override void OnInit(EventArgs e)
{
//add to controls collection
base.OnInit(e);
}
}

Extended controls

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace RSMTechno.Controls
{
[ToolboxData("<{0}:DropListwDefault runat=server>")]
public class ExtendedDropDownListwDefault : DropDownList
{

public ExtendedDropDownListwDefault()
{
DataTextField = "name";
DataValueField = "id";
this.AppendDataBoundItems = true;
AddDefault();
}

public void AddDefault()
{
ListItem defaultItem = new ListItem();
defaultItem.Selected = true;
defaultItem.Text = "--";
defaultItem.Value = Guid.Empty.ToString();
this.Items.Add(defaultItem);
}

}
}


WebParts class

namespace RSMTechno.WebParts
{
public class DemoControl : system.web.UI.WebControls.WebParts.WebPart
{

}
DemoControl _dc = null;
protected override void OnInit(EventArgs e)
{
_dc = new DemoControl();
this.Title = "Demo Control….";

this.Controls.Add(_dc);

base.OnInit(e);
}
}

RSMTechno.DataAccessLayer

I want to get data from other database servers and display it on web part, here we need to write a code to interact with different database servers this project library is created for that purpose only

You can find one dbml file which will interact with northwind database through LINQtoSQL

But, rarely we use this library project because MOSS has provided some OOTB functionality to interact with external database servers

RSMTecno.SolutionDemo

This is the heart of the solution; this will take care of all the things like installing the web parts, site definitions, master pages and user controls etc... using features

Here, you can find some folders which are mapped to exactly 12 hive folder structure in sharepoint environment like CONTROLTEMPLATES,RESOURCES,LAYOUTS and FEATURES etc...

While deploying what are all things you have placed uder these folder structure will be automatically dumped in to sharepoint 12 hive environment

I am using wspbuilder for building and deploying features

I have posted one article on how to build and deploy features using wspbuilder please go through that if you have any doubts

RSMTechno.BusinessLayer

This will seaparate your business logic and it provides more reusability and maintanence

Each and every component will interact with this to fetch data from sharepoint document library or list or xml file or from third party resources and populate accordingly


Some people asked me why I have to create five projects I will use one or two , yes ofcourse if you want you can use but what about maintenance and reusability just think?

Building solution is not a simple task you have to consider lot of things like maintenance, reusability,supports testdriven development etc...

Let us take this simple scenario in future, if I want to add one new control in to my sharepoint application? what are all things do I need to do? I will just go and simply create one server control under RSMTechno.Control project and build that project and deploy that assembly into GAC or BIN

See how much simple it is with out building or touching other components we are completing our task

There may be some delay passing objects from one layer to another layer but I feel that is not considered amount what ever you write that should be in reusable manner and should be easily maintenable

If you want you can add different projects in the solution like RSMTECHNO.WebServices etc... based on your requirements

But be carefull unnecessary if you pass your objects in multiple layers that will affect on performance

Friday, November 6, 2009

Best Practices while creating webparts

I would like to share some best practices on sharepoint while creating solution/implementation for sharepoint custom application

While creating webparts I prefer that first create custom control and create object for that in your webpart class ,the main advantage of this is in future , suppose if your client want to shift to .net based application because of some reasons, he can easily move in to .net application because you have developed all the components using webcontrol class so you can reuse same controls in your .net application

I have provided sample code here

Custom Controls

using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace RSMTechno.Controls
{
[ToolboxData("<{0}:DemoControl =server>")]
public class DemoControl : WebControl
{
//create your control
protected override void OnInit(EventArgs e)
{
//add to controls collection
base.OnInit(e);
}
}

WebParts class

namespace RSMTechno.WebParts
{
public class DemoControl : system.web.UI.WebControls.WebParts.WebPart
{

}
DemoControl _dc = null;
protected override void OnInit(EventArgs e)
{
_dc = new DemoControl();
this.Title = "Demo Control….";

this.Controls.Add(_dc);

base.OnInit(e);
}
}

User controls

Usercontrols makes your development faster because no need of writing code in codebehind file for creating controls in webpart , I think every web developer will have some knowledge on html stuff so they can use html for desgining their GUI using VSIDE and they can immediately see output on screen mode, the main advantage of this is it will make your development faster when you have short deadlines

I think most of the .net guys aware of usercontrols , so need of puttingmore effort on writing in codebehind in webparts this will save time also

Suppose in future if you feel that sharepoint is not right platform for the solution you are building, you can easily move into other platform no need of putting extra effort on that and you can reuse your usercontrols

But only some people are saying that they are facing some performance problems when they use usercontrols in webparts that to in extremely large sites

WSPBiuilder

I always prefer to use wspbuilder to create features through VSIDE, because this tool will help you a lot

No need of manually creating manifest.xml , no need of specifying the DDF file so please please use wspbuilder if you want to make your sharepoint development faster

Actually when you want to uninstall your feature you have to use STSADM command or you have to use solution management to uninstall your future

But this tool will help you to install/uninstall futures through wizard; this will help those who don’t have knowledge on SharePoint

Tuesday, September 8, 2009

Creating PageLayouts using Features

Long time back I have posted an article on creating page layouts using SharePoint user interface and designer, now I am going to explain how to create page layouts using features

In this article, I am going to use WSPBuilder for building and deploying SharePoint solution, the main advantage of WSPBuilder is no need of creating manifest.xml , DDf file and cab file, the WSPBuilder will take care of creating all these things, so this will simplify our process

First, I am going to explain what are the entire things do we need for building SharePoint page layouts using features

Please check below image which talks about relation between Site Columns, Content Type and Page layout



Site Columns

A site column is a reusable column definition, or template, that you can assign to multiple lists across multiple SharePoint sites. These columns are directly mapped to table columns in SharePoint database

Her e I have created three columns Activity Name, Activity ID, Activity Image,
While creating site columns please make sure that each column have its own unique ID

You can get Unique ID using GUID tool

VS2008->Tools->Create GUID->Registry Format->Copy

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">

<Field ID="{d7bc4337-826c-497d-bd46-b7a14afb6a9c}"
Type="Text"
Name="ActivityName"
DisplayName="Activity Name"
StaticName="Activity Name"
Hidden="FALSE"
Required="FALSE"
Group="Activity Columns"
Sealed="FALSE" />
<Field ID="{8BA8E4BC-395F-4a7c-91D7-E9519CC41D11}"
Type="Text"
Name="Activity ID"
DisplayName="Activity ID"
StaticName="Activity ID"
Hidden="FALSE"
Group="Activity Columns"
Required="FALSE"
Sealed="FALSE" />
<Field ID="{EC61E44F-E3FC-430e-BA3A-F457A8945190}"
Type="Image"
Name="Activity Image"
DisplayName="Activity Image"
StaticName="Activity Image"
Hidden="FALSE"
Group="Activity Columns"
Required="FALSE"
Sealed="FALSE" />

</Elements>

Site Content Type


Suppose if you want to manage your organization information in meaning full way across site collection then you can go for Site content types

A content type is a reusable collection of settings you want to apply to a certain category of content. Content types enable you to manage the metadata and behaviors of a document or item type in a centralized, reusable way

Here I have created activity content type that tells to the client that this content type belongs to only activity information

Every content type has FieldRef properties, these properties have a reference to site columns ID’s, that means this field(Site Column)and FieldRef both are pointing to same reference, so whenever we update site column’s that will automatically reflect in content type columns also

See below code all FieldRef Id’s are pointing to sit columns ID’s, if you want you can override some of the properties name, description etc…

Using below code we have created a content type, this is simple content type, it does not do anything so, we have to attach this to base page content type using Content type ID

The content type ID is the combination of base page ID and custom GUID which are separated by 00

Please refer MSDN link for more info on content type id http://msdn.microsoft.com/en-us/library/aa543822.aspx

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<ContentType ID="0x010100C568DB52D9D0A14D9B2FDCC96666E9F2007948130EC3DB064584E219954237AF3900088E14C620BF45afA8B4ADA5F771DB5D"
Name="ActivityContentType"
Group="Demo"
Description="Demo Content Type"
Version="0">
<FieldRefs>
<FieldRef ID="{d7bc4337-826c-497d-bd46-b7a14afb6a9c}" Name="Activity Name" />
<FieldRef ID="{8BA8E4BC-395F-4a7c-91D7-E9519CC41D11}" Name="Activity ID" />
<FieldRef ID="{EC61E44F-E3FC-430e-BA3A-F457A8945190}" Name="Activity Image" />
</FieldRefs>
</ContentType>
</Elements>

Layout page

I suggest you guys create layout page using SharePoint designer and copy into your feature folder, so that you will not face any kind of problems and your work will be smooth

Below page is the which I have created using SharePoint designer

All the SharePoint controls of this layout page have a reference to site columns using Fieldname property, the Fieldname is the name of the site column

<%@ Page language="C#" Inherits="Microsoft.SharePoint.Publishing.PublishingLayoutPage,Microsoft.SharePoint.Publishing,Version=12.0.0.0,Culture=neutral,PublicKeyToken=71e9bce111e9429c" meta:webpartpageexpansion="full" meta:progid="SharePoint.WebPartPage.Document" %>
<%@ Register Tagprefix="SharePointWebControls" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> <%@ Register Tagprefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPages" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> <%@ Register Tagprefix="PublishingWebControls" Namespace="Microsoft.SharePoint.Publishing.WebControls" Assembly="Microsoft.SharePoint.Publishing, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> <%@ Register Tagprefix="PublishingNavigation" Namespace="Microsoft.SharePoint.Publishing.Navigation" Assembly="Microsoft.SharePoint.Publishing, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<asp:Content ContentPlaceholderID="PlaceHolderPageTitle" runat="server">
<SharePointWebControls:FieldValue id="PageTitle" FieldName="Title" runat="server"/>
</asp:Content>
<asp:Content ContentPlaceholderID="PlaceHolderMain" runat="server">

<SharePointWebControls:TextField FieldName="Activity ID" runat="server" id="TextField1">
</SharePointWebControls:TextField>
<SharePointWebControls:TextField FieldName="ActivityName" runat="server" id="TextField2">
</SharePointWebControls:TextField>
<PublishingWebControls:RichImageField FieldName="Activity Image" runat="server" id="RichImageField1">
</PublishingWebControls:RichImageField>

</asp:Content>


ProvisionedFiles.xml

I am using module element for deploying our page in master page gallery

<?xml version="1.0" encoding="utf-8" ?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">

<Module Name="ActivityPage" Url="_catalogs/masterpage" Path="" RootWebOnly="TRUE">
<File Url="Activity.aspx" Type="GhostableInLibrary">
<Property Name="ContentType" Value="DemoContetType" />
<Property Name="PublishingPreviewImage" Value="~SiteCollection/_catalogs/masterpage/$Resources:core,Culture;/Preview Images/sample.png, ~SiteCollection/_catalogs/masterpage/$Resources:core,Culture;/Preview Images/sample.png" />
</File>
</Module >
</Elements>

Feature.xml

<?xml version="1.0" encoding="utf-8"?>
<Feature Id="c2554713-1770-4349-8576-c6f8fe44a950"
Title="PageLayoutDemo"
Description="Description for PageLayoutDemo"
Version="12.0.0.0"
Hidden="FALSE"
Scope="Site"
DefaultResourceFile="core"
xmlns="http://schemas.microsoft.com/sharepoint/">
<ElementManifests>

<ElementManifest Location ="SiteColumns.xml"/>
<ElementManifest Location ="ContentType.xml"/>
<ElementManifest Location ="ProvisionedFiles.xml"/>

</ElementManifests>

</Feature>

So, we have created all necessary files which are required to create pagelayout, now we have to deploy all these files using features

I am using WSPBuilder for deploying all these files, I have posted an article on WSPBuilder please check it, if you need more info



Create a new WSPBuilder Project then create folder structure as shown in fig then copy all the files and build and deploy

For more info on WSPBUilder check my article on WSPBuilder