SharePointAds TextOnly

Thursday, 16 May 2013

SharePoint Client Object Model : How to change default content type programatically

In this blog I am going to show how to change default content type programatically using the SharePoint client object model. In one of my task assignments I was using custom content type in the document library and to update this new content type as a default content type for the document library.
The top content type is always default content type for all type of SharePoint libraries. So that you have to just change the content type order of library and make your custom content type on the top.
Following is the code method to change the content type order.
Include "using SP = Microsoft.SharePoint.Client;" on the top of your class.

void ChangeContentTypeOrder(SP.ClientContext ctx, SP.List list, string contentTypeName)
{
            SP.ContentTypeCollection currentCTOrder = list.ContentTypes;
            ctx.Load(currentCTOrder);
            ctx.ExecuteQuery();

            IList<SP.ContentTypeId> reverceOrder = new List<SP.ContentTypeId>();
            foreach (SP.ContentType ct in currentCTOrder)
            {
                if (ct.Name.Equals("contentTypeName"))
                {
                    reverceOrder.Add(ct.Id);
                }
            }
            list.RootFolder.UniqueContentTypeOrder = reverceOrder;
            list.RootFolder.Update();
            list.Update();
            ctx.ExecuteQuery();           
}



Where "SP.List list" is the list name and  'string contentTypeName' is the custom content type which you have to make as a default content type

Wednesday, 8 May 2013

SharePoint 2010 : Deploy webpart page embedded with Visual webpart using SharePoint feature

Are you looking for a solution to deploy webpart pages using SharePoint feature? Do you need to use Visual webparts part in to the page? Following is the solution for your answers. Here I am going to explain to how to deploy webpart pages with visual webpart using module feature.

Create new SharePoint project, select "Empty SharePoint Project" template


On next window, provide local SharePoint site url and select "Deploy as a farm solution" as a trust level. Click on Finish button
The next step is to create Visual Webpart, right click on project and add new item

Add sample label control in webpart's ascx for demonstration, here you can design your webpart

Now add new module feature in the project. Right click on project and add new item


Now delete sample.txt file from module and add aspx page. Right click on module and add new item
Select Text file template from General section and name it as MyPage.aspx.

Same as above, add new class file for aspx page

Solution Explorer window will be like this

Open MyPage.ASPX page and paste following lines, registered SharePoint required assemblies and Project assemblies

<%@ Assembly Name="$SharePoint.Project.AssemblyFullName$" %>
<%@ Import Namespace="Microsoft.SharePoint.ApplicationPages" %>
<%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls"
Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral,
PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="asp" Namespace="System.Web.UI"
Assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35" %>
<%@ Register Tagprefix="Utilities" Namespace="Microsoft.SharePoint.Utilities"
Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral,
PublicKeyToken=71e9bce111e9429c" %>
<%@ Import Namespace="Microsoft.SharePoint" %>
<%@ Assembly Name="Microsoft.Web.CommandUI, Version=14.0.0.0, Culture=neutral,
PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPages"
Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral,
PublicKeyToken=71e9bce111e9429c" %>
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="MyPage.aspx.cs"
Inherits="MyWebPartPages.MyPage" masterpagefile="~masterurl/default.master" %>

<asp:Content ID="Main" ContentPlaceHolderID="PlaceHolderMain" runat="server">
    <WebPartPages:WebPartZone runat="server" ID="myWebpartZone">
    <ZoneTemplate></ZoneTemplate>
    </WebPartPages:WebPartZone>
</asp:Content>



Then open MyPage.aspx.cs class file and paste following lines

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint.WebPartPages;

namespace MyWebPartPages
{
    public partial class MyPage : WebPartPage
    {
        protected void Page_Load(object sender, EventArgs e)
        {
        }
    }
}

Make sure that page inherits from WebPartPage

Next step is to embed visual webpart with the webpart page. For that open Module's Elements.xml file and update it as follow
<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
 <Module Name="MyWebpartPage" Url="SitePages">
  <File Path="MyWebpartPage\MyPage.aspx" Url="MyPage.aspx"

        Type="GhostableInLibrary" IgnoreIfAlreadyExists="FALSE">
      <AllUsersWebPart WebPartOrder ="0" WebPartZoneID ="myWebpartZone">
        <![CDATA[
          <webParts>
            <webPart xmlns="http://schemas.microsoft.com/WebPart/v3">
              <metaData>
                <type name="MyWebPartPages.MyVisualWebPart.MyVisualWebPart, $SharePoint.Project.AssemblyFullName$" />
                <importErrorMessage>Cannot import this Web Part.</importErrorMessage>
              </metaData>
              <data>
                <properties>
                  <property name="Title" type="string">MyVisualWebPart</property>
                  <property name="Description" type="string">MyVisualWebPart</property>
                     
                </properties>
              </data>
            </webPart>
          </webParts>
        ]]>
      </AllUsersWebPart>
    </File>
  </Module>
</Elements>


Build and deploy the solution and open "Site Pages"  library.


Click on MyPage file and you will see the output webpart page



Thursday, 6 December 2012

SharePoint Online: Get web full url


Sometimes you need to get full url of current web. following is the short method which will return you full web url.

public string getWebFullUrl(Web web)
{ 

string webTitle = web.ServerRelativeUrl.Substring(web.ServerRelativeUrl.LastIndexOf("/") + 1);

return web.Context.Url + webTitle + "/";

}



Remember web.ServerRelativeUrl will return only relative url, as show in following table:

Site Collection URL
Site URL
web.ServerRelativeUrl
http://MySharepointsite.com
http://MySharepointsite.com
/
http://MySharepointsite.com
http://MySharepointsite.com/site1
/site1
http://MySharepointsite.com
http://MySharepointsite.com/sites/site1
/sites/site1

Thursday, 29 November 2012

SharePoint 2010: Print List Views Button on Ribbon

After getting lots of emails/replies from my last post SharePoint 2010 : Print Calendar list. I've decided to expand new solution with new functionality where you can add "Print Button" on each type of SharePoint lists, even if it is SharePoint Calendar list,Document libraries, tasks lists or any custom lists.
This feature is developed as a Sandbox Solution and successfully tested on SharePoint 2010, O365 SharePoint Online sites.
Print Button on Document Libraries Ribbon:


Print Button on Lists Ribbon:






Print Button on Calendar Ribbon:





Please have a look at my new codeplex solution to download and install feature in your SharePoint 2010 site.
Download Solution from Codeplex

Tuesday, 3 January 2012

SharePoint Client Object Model: CAML query execution using pagination

Below approach is used when user wants to perform pagination based on given parameters. In order to make paging work, you need to get page index and recurring count values from user.
List Items can be retrive in result and user can specify PageIndex and RecCount values which will be used for resulting certain number of values.


If your list is having more than 1 million and user requested only for list items in the rage of 100-200 then it is not good practice to get all list item collection. To avoid to load all list items collection you need to get required list item from CAML and using Paging. The logic is :

  1. Calculate skip value
  2. Assign skip values to ListItemCollectionPosition PagingInfo e.g. Paged=TRUE&p_ID=SKIP_NUMBER”
  3. Pass ListItemCollectionPosition value to CAML query
  4. Apply RowLimit value to CAML query

Suppose if you are trying to get list items from 100 to 200 then assign PageIndex =2 and recCount =100 into the following method.
//Add client
using SP = Microsoft.SharePoint.Client;

public void getItems(int pageIndex, int recCount)
{
SP.ClientContext ctx = getClientContext(); //authenticate client context
                                          // first Authentication post for more details

if (ctx != null)
{
              int iSkip = pageIndex * recCount - recCount;
              SP.List list = ctx.Web.Lists.GetByTitle("Your LIst Name"); // replace with your list name
              ListItemCollectionPosition itemPosition = new ListItemCollectionPosition();
              itemPosition.PagingInfo = string.Format("Paged=TRUE&p_ID={0}",iSkip);
              CamlQuery camlQuery = new CamlQuery();
              camlQuery.ListItemCollectionPosition = itemPosition;

              camlQuery.ViewXml = @"<View><ViewFields>
                                    <FieldRef Name='ID'/>
                                    <FieldRef Name='Title'/>
                                    </ViewFields><RowLimit>" + recCount + @"</RowLimit>
                                    </View>";
                  
SP.ListItemCollection listItems = list.GetItems(camlQuery);
              ctx.Load(listItems);
              ctx.ExecuteQuery();

              foreach (SP.ListItem listItem in listItems)
              {
//Do forward with listItem["ID"].ToString() and  listItem["Name"].ToString()
              }
}
}


Please have a look at Authentication post for more details about SharePoint Client object model authentication.

Thursday, 15 December 2011

How to create Calendar recurring event from SharePoint Designer 2010 workflow?


Do you want to create new calendar recurring event from SharePoint workflow? If yes, then you are at correct place.
You can easily create simple calendar event (which doesn’t have recurring properties/values), Some days before I was trying to create new recurring event from SPD workflow using “Create Item” action, and found that we can’t create recurring event from SPD workflows because when we’re trying to add new calendar list item from ‘Create Item’ OOB workflow action, at that point we can’t assign the recurring rules values to ‘Recurrence’ column and there is not any available way to pass recurrence rule xml values.
SPD_WF
I found an interesting article which creates new calendar event with recurring parameters programatically(http://msdn.microsoft.com/en-us/library/ms434156.aspx). But I was looking to create calendar events from SPD workflows and I decided to create workflow custom action to insert new recurring events. If you don’t know how to create custom action for SPD workflows then look at here (http://msdn.microsoft.com/en-us/office365trainingcourse_lab_3_2_topic3#_Toc290553044), this is very simple and easier solution to create custom custom actions from VS. You just have to make following changes,
  1. Add new class file to the solution for recurring event action (I created as “CreateCalendarRecurrenceEvent.cs”)
  2. Your ‘Element.xml’ file would be as following,  

    <?xml version="1.0" encoding="utf-8"?>

    <Elements xmlns="http://schemas.microsoft.com/sharepoint/">

      <WorkflowActions>

        <Action Name="Create Recurring Event"

                SandboxedFunction="true"

                Assembly="$SharePoint.Project.AssemblyFullName$"

                ClassName="SPDRecurringEventAction.CreateCalendarRecurrenceEvent"

                FunctionName="CalendarRecurrenceEvent"

                AppliesTo="all"

                Category="My Custom Workflow Activities">


          <RuleDesigner Sentence="Create New calendar recurring event with title : %1 and rule: %2 (Exception to %3)">

            <FieldBind Id="1" Field="eventTitle" Text="Event Name" DesignerType="TextBox" />

            <FieldBind Id="2"  Field="recurrenceRule" Text="Recurrence Rule" DesignerType="TextBox" />

            <FieldBind Id="3" Field="Except" Text="Exception" DesignerType="ParameterNames" />

          </RuleDesigner>


          <Parameters>

            <Parameter Name="__Context"

                       Type="Microsoft.SharePoint.WorkflowActions.WorkflowContext, Microsoft.SharePoint.WorkflowActions"

                       Direction="In" DesignerType="Hide"/>


            <Parameter Name="eventTitle" Type="System.String, mscorlib" Direction="In"

                       DesignerType="TextBox" Description="Event Name" />


            <Parameter Name="recurrenceRule" Type="System.String, mscorlib" Direction="In"

                       DesignerType="TextBox" Description="Recurrence Rule" />


            <Parameter Name="Except" Type="System.String, mscorlib" Direction="Out"

                       DesignerType="ParameterNames" Description="Exception encountered"/>

          </Parameters>

        </Action>

       

      </WorkflowActions>

    </Elements>


  3. In your new class add following method to create new recurring event.
class CreateCalendarRecurrenceEvent

    {

        public Hashtable CalendarRecurrenceEvent(SPUserCodeWorkflowContext context, 
string eventTitle, string recurrenceRule)

        {

            Hashtable results = new Hashtable();

            int iYear = 0, iMonth = 0, iDay = 0;

            results["Except"] = string.Empty;

            try

            {

                using (SPSite site = new SPSite(context.CurrentWebUrl))

                {

                    using (SPWeb web = site.OpenWeb())

                    {


                        iYear = DateTime.Now.Year; iMonth = DateTime.Now.Month; iDay = DateTime.Now.Day;

                        DateTime startTime = new DateTime(iYear, iMonth, iDay, 8, 0, 0); //

                        DateTime endTime = startTime.AddHours(6);


                        SPList cal = web.Lists["Calendar"];

                        SPListItem calEvent = cal.Items.Add();

                        calEvent["Title"] = eventTitle;

                        calEvent["RecurrenceData"] = recurrenceRule;

                        calEvent["EventType"] = 1;

                        calEvent["EventDate"] = startTime;

                        calEvent["EndDate"] = endTime;

                        calEvent["UID"] = System.Guid.NewGuid();

                        calEvent["Recurrence"] = 1;
                        calEvent.Update();

                    }

                }

            }

            catch (Exception ex)

            {

                results["Except"] = ex.ToString();

            }

            return results;

        }

    }


(NOTE: I have used default calendar list to create new recurring event, if you want to create recurring event in another calendar list then change 'Calendar' list name.
)
Build and deploy action and follow the steps given at  http://msdn.microsoft.com/en-us/office365trainingcourse_lab_3_2_topic3#_Toc290553044

In SharePoint Designer workflow, add your custom activity, assign Name and Recurrence Rule pattern as in XML format. You can check more recurrence patterns from Here.
(NOTE :  Rule value must be in single line text, I have used as " <recurrence><rule><firstDayOfWeek>su</firstDayOfWeek><repeat><daily dayFrequency='2' /></repeat><windowEnd>2011-12-30T09:00:00Z</windowEnd></rule></recurrence>
  ")


I have created SPD custom activity solution on Codeplex, you can download actual project solution from here (http://spdcustomaction.codeplex.com/releases/view/78835)

Enjoy custom activity to create new recurring events from SharePoint Designer workflow.