2011-04-30

How To Get Column Data On Each List Items row in a Xslt List View WebPart

In SharePoint 2007, We can get all column data bellow xslt code.
This sample is getting "Title" column value in "Modified" column.


Also we can get same result bellow code.


The Bellow image is result.



In SharePoint 2010, we cannot use the above code. We should use bellow code.



The Bellow image is result.


Then, I introduce how to add this code easily in SharePoint Designer.


  • Open AllItems.aspx or other new view page in SharePoint Designer.
  • Click "Advanced Mode" in Home tab to enable to edit entire page.



  • Click List View Web Part in Design View.

  • Click "Customize XSLT" - "Customize Entire View" in Design Tab. 



  • Drag & Drop "Title" from Data Source Detail to Xslt List View Web Part.

  • You can check the code in Code View.


After cherry blossoms, we can see a lot of field mustard !


2011-04-19

ItemAdded Event Sometimes Cannot Get AfterProperties

-ed Event such as "ItemAdded" method sometimes cannot get AfterProperties which is added by Document Parser from a list item. I heard this from one of my colleagues and I haven't reproduced it yet.
Document Parser enables to binding the document properties to list item's columns. Here is the sample :


  • Click New Document.




  • Fill in the form and click Save.
  • You can see the form data were binded to list item's columns.



We usually write event handler code which gets list item's column data when an item is added. But sometimes we cannot get item's column data by using AfterProperties.
This is because -ed event (ItemAdded) runs asynchronously. That means -ed event and document parser which add data to column run different threads. In this case, what we need to do is adding Thread.Sleep in -ed event code. Thread.Sleep is specified in milliseconds unit. 
 Here is the sample :

public override void ItemAdded(SPItemEventProperties properties)
{
    Thread.Sleep(100);
    string name = (string)properties.AfterProperties["Name"];
    string title = (string)properties.AfterProperties["Title0"];
    string discription = (string)properties.AfterProperties["Discription"];
    SPDiagnosticsService.Local.WriteTrace(0, new SPDiagnosticsCategory("ItemAdded", TraceSeverity.Unexpected, EventSeverity.Error), TraceSeverity.Unexpected, "ItemAdded" + " " + name + " " + title + " " + discription, "ItemAdded" + " " + name + " " + title + " " + discription);
}



I love Terje Sorgjerd's creations. They are my favorites. So beautiful, so creative. I'll share his another creation.




2011-04-16

Using the SharePoint 2010 Modal Dialog in Custom Aspx Page

SharePoint 2010 provides a new dialog framework using Client OM (javascript).
You can see the following dialog when you click an item from the list.


Modal dialog is provided by SP.UI.ModalDialog class.
Today, I'd like to introduce how to create a link to show modal dialog in a custom aspx page.
The steps are here.


  • Create Empty SharePoint Project.


  • Add new Application page in the new project.


  • Open new Application page, and add HyperLink tag in "PlaceHolderMain".

    HyperLink


  • Open code view of new Application page, and Write the code bellow.

This code indicates : 
  1. Get workflow task item's URL.
  2. Register modal dialog's script by using ScriptManager class.
  3. Bind javascript method for task url link.
StringBuilder taskUrl = new StringBuilder();

        protected void Page_Load(object sender, EventArgs e)
        {
            SPWeb web = SPContext.Current.Web;
            SPList list = web.Lists["Announcements"];

            foreach (SPListItem item in list.Items)
            {
                if (item.Workflows != null)
                {
                    foreach (SPWorkflow workflow in item.Workflows)
                    {
                        if (workflow.Tasks != null)
                        {
                            foreach (SPListItem task in workflow.Tasks)
                            {
                                //create task item url.
                                taskUrl.Append("http://sharepoint/_layouts/WrkTaskIP.aspx?List=");
                                taskUrl.Append(workflow.TaskListId);
                                taskUrl.Append("&ID=" + task.ID + "&IsDlg=1&Web=");
                                taskUrl.Append(web.ID);
                            }
                        }
                    }
                }
            }
            
            //make modal dialog script.
            string script =
                @"
    var modalDialog;
    function ShowDialogTest() {
        var options = {
            url: '" + taskUrl.ToString() + @"',
            tite: 'Workflow Task',
            allowMaximize: false,
            showClose: false,
            width: 800,
            height: 600 };
        modalDialog = SP.UI.ModalDialog.showModalDialog(options);
    }";
            //register the script.
            ScriptManager.RegisterStartupScript(this, this.GetType(), ClientID, script, true);
            //bind the script for hyperlink.
            HyperLink1.NavigateUrl = "javascript:ShowDialogTest()";
        }

The code is very simple. If there are more than two task items, the code doesn't work.


  • Deploy and access the new application page.


If you create Application page in SharePoint Empty Project, the aspx page is deployed in "_layouts" and master page tag is attached automatically. This is very nice function !! 
Sample url is here. "ShowModalDialog" is the project name.

http://sharepoint/_layouts/ShowModalDialog/ApplicationPage1.aspx


  • Click "HyperLink" link. Modal Dialog is displayed !!



Tips :

I also created an application page in ASP.NET Web Application project. But the code didn't work even after I added the script reference. 



I got "'Type' is undefined (sp.js)" error when I clicked hyperlink to display modal dialog. I can't understand why the error appears.
I'm trying to find out why it happens.




I found tremendously beautiful movie in Vimeo !!
The movie was recorded on a mountain in Spain.





2011-04-10

How to disabling event firing in SharePoint 2010

Today, I tested whether event receiver fires or not when I use SPListItem's Update methods.
The results are here.


Methods                 event firing
Update()                   fired
SystemUpdate()             fired
SystemUpdate(false)        fired
UpdateOverwriteVersion()   fired

All methods fired !!

But I think people sometimes want not to fire a event receiver when a update method is used.
So, I would like to introduce how to disable event firing.


In SharePoint 2010, SPEventReceiverBase.DisableEventFiring Method and SPEventReceiverBase.EnableEventFiring Method are already obsolete. We need to use EventFiringEnabled Property.



A sample code is here.

private void button1_Click(object sender, EventArgs e)
{
    const string siteUrl = "http://sp2010";
    SPSite site = new SPSite(siteUrl);
    SPWeb web = site.RootWeb;

    SPList list = web.Lists["Announcements"];
    SPListItem item = list.Items[3];

    HandleEventFiring handleEventFiring = new HandleEventFiring();
    handleEventFiring.DisableHandleEventFiring();

    try
    {
        item.Update();
    }
    finally
    {
        handleEventFiring.EnableHandleEventFiring();
    }
}

public class HandleEventFiring : SPItemEventReceiver
{

    public void DisableHandleEventFiring()
    {
        //obsolete
        //this.DisableEventFiring();
        this.EventFiringEnabled = false;
    }

    public void EnableHandleEventFiring()
    {
        //obsotete
        //this.EnableEventFiring();
        this.EventFiringEnabled = true;
    }
}



This summer, I plan to go forest hiking.


2011-04-09

troubleshooting in making workflow each steps (InvalidOperationException and ArgumentNullException)

This time, I introduce how to make simple workflow and its troubleshooting.
Someone who makes workflow encounter a few exceptions. I show each resolutions when workflow execution.


  • Make Sequential Workflow from SharePoint 2010 template.


  • Make simple workflow. CreateTask, Delay, and CompleteTask.

  • Set correlation Token same as onWorkflowActivated1 for createTask1 and completeTask1 in each properties menu.
onWorkflowActivated1 : workflowToken
createTask1              : workflowToken
completeTask1           : workflowToken
  • Build, deploy and run in particular list. Of course, It doesn't work. 


I checked ULSlog and found bellow InvalidOperationException about workflow.

System.InvalidOperationException:
Correlation value on declaration "workflowToken" is already initialized.  
at System.Workflow.Runtime.CorrelationToken.Initialize(Activity activity, ICollection`1 propertyValues)  
at System.Workflow.Activities.CorrelationService.InvalidateCorrelationToken(Activity activity, Type interfaceType, String methodName, Object[] messageArgs)  
at System.Workflow.Activities.CallExternalMethodActivity.Execute(ActivityExecutionContext executionContext)     at System.Workflow.ComponentModel.ActivityExecutor`1.Execute(T activity, ActivityExecutionContext executionContext)  
at System.Workflow.ComponentModel.ActivityExecutor`1.Execute(Activity activity, ActivityExecutionContext executionContext)  
at System.Workflow.ComponentModel.ActivityExecutorOperation.Run(IWorkflowCoreRuntime workflowCoreRuntime)  
at System.Workflow.Runtime.Scheduler.Run()

This error is little bit tricky.
What we need to do is using new correlation token for each set of createTask and completeTask.
onWorkflowActivated1 : workflowToken
createTask1              : TaskToken1
completeTask1           : TaskToken1


We use orrelation token to identify each tasks. If you have two tasks in workflow, you can set here.

onWorkflowActivated1 : workflowToken
createTask1              : TaskToken1
completeTask1           : TaskToken1
createTask2              : TaskToken2
completeTask2           : TaskToken2

  • Let's build, deploy and run again !  But,, you still get ArgumentNullException...
System.Reflection.TargetInvocationException:
Exception has been thrown by the target of an invocation. ---> System.ArgumentNullException: Value cannot be null.  
at Microsoft.SharePoint.Workflow.SPWorkflow.GetReservedItemId(SPList list, Guid taskId, Boolean createNew)  
at Microsoft.SharePoint.Workflow.SPWorkflow.GetReservedItemId(SPList list, Guid taskId)  
at Microsoft.SharePoint.Workflow.SPWinOETaskService.CreateTaskWithContentTypeInternal(Guid taskId, SPWorkflowTaskProperties properties, Boolean useDefaultContentType, SPContentTypeId ctid, HybridDictionary specialPermissions)  
 at Microsoft.SharePoint.Workflow.SPWinOETaskService.CreateTask(Guid taskId, SPWorkflowTaskProperties properties, HybridDictionary specialPermissions)  
--- End of inner exception stack trace ---  
at System.RuntimeMethodHandle._InvokeMethodFast(Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)  
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)  
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)  
at System.RuntimeType.InvokeMember(String name, BindingFlags bindingFlags, Binder binder, Object target, Object[] providedArgs, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParams)     at System.Workflow.Activities.CallExternalMethodActivity.Execute(ActivityExecutionContext executionContext)  
at System.Workflow.ComponentModel.ActivityExecutor`1.Execute(T activity, ActivityExecutionContext executionContext)  
at System.Workflow.ComponentModel.ActivityExecutor`1.Execute(Activity activity, ActivityExecutionContext executionContext)  
at System.Workflow.ComponentModel.ActivityExecutorOperation.Run(IWorkflowCoreRuntime workflowCoreRuntime)  
at System.Workflow.Runtime.Scheduler.Run()

It seems that this error occurs when createTask execute.
In here, What we need to do is setting new GUID for createTask.

  • Double-click "TaskId" in createTask1 properties. and make new Field which bind TaskId.


You can find bellow code is generated.

public Guid createTask1_TaskId1 = default(System.Guid);



  • Double-click "TaskProperties" in createTask1 properties. and make new Field which bind TaskProperties.


You can find bellow code is generated.

public SPWorkflowTaskProperties createTask1_TaskProperties1 = new Microsoft.SharePoint.Workflow.SPWorkflowTaskProperties();


  • Double click onWorkflowActivated1 and write code in onWorkflowActivated1_Invoked like this.

private void onWorkflowActivated1_Invoked(object sender, ExternalDataEventArgs e)
{
    this.workflowId = workflowProperties.WorkflowId;
}

  • Double click createTask1 and write code in createTask1_MethodInvoking like this.

private void createTask1_MethodInvoking(object sender, EventArgs e)
{
    this.createTask1_TaskId1 = Guid.NewGuid();
    this.createTask1_TaskProperties1.Title = "Please approve the document.";
    this.createTask1_TaskProperties1.AssignedTo = "domain\\someone";
}



  • Let's build, deploy and run again !
done.... It's heavy work.



So, this time is spring. We can see a lot of cherry blossoms. enjoy now !!



2011-04-03

Enable to execute -ed events synchronously or asynchronously in SharePoint 2010

In SharePoint 2007, -ed events are executed only asynchronously.
This causes some problems between the main thread the and sub thread. For instance, -ed event thread sometimes cannot get its own item's "afterproperties".


Using SharePoint 2010, -ed events can be executed either synchronously or asynchronously.

The two Event Receivers are as follows:

  • -ing events (ItemAdding, ListAdding, etc)
    • synchronously 
  • -ed events (ItemAdded, ListAdded, etc)
    • synchronously or asynchronously

You can write "Synchronous" in Elements.xml in SharePoint EventReciver Project in Visual Studio 2010.

<Synchronization>Synchronous</Synchronization>

Listed below are the steps for making a synchronous -ed event:

  • Create project as Event Receiver.



  • Choose 2 events (ItemAdding and ItemAdded).



  • Write the code. I added the current thread name in ULS log in ItemAdding and ItemAdded method to see status of thread. It is also necessary to add Microsoft.SharePoint.Administration namespace.
using System;
using System.Security.Permissions;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Security;
using Microsoft.SharePoint.Utilities;
using Microsoft.SharePoint.Workflow;
using Microsoft.SharePoint.Administration;

namespace EventReceiverProject4.EventReceiver1
{
    /// <summary>
    /// List Item Events
    /// </summary>
    public class EventReceiver1 : SPItemEventReceiver
    {
       /// <summary>
       /// An item is being added.
       /// </summary>
       public override void ItemAdding(SPItemEventProperties properties)
       {
           System.Threading.Thread.CurrentThread.Name = "Current Thread";
           string theadName = System.Threading.Thread.CurrentThread.Name;

           SPDiagnosticsService.Local.WriteTrace(0, new SPDiagnosticsCategory("ItemAdding", TraceSeverity.Unexpected, EventSeverity.Error), TraceSeverity.Unexpected, theadName, theadName);
           base.ItemAdding(properties);
       }

       /// <summary>
       /// An item was added.
       /// </summary>
       public override void ItemAdded(SPItemEventProperties properties)
       {
           string theadName = System.Threading.Thread.CurrentThread.Name;
           SPDiagnosticsService.Local.WriteTrace(0, new SPDiagnosticsCategory("ItemAdded", TraceSeverity.Unexpected, EventSeverity.Error), TraceSeverity.Unexpected, theadName, theadName);
           base.ItemAdded(properties);
       }
    }
}


The ItemAdding and ItemAdded thread names are different because ItemAdded is run asynchronously.
The results are shown here:
  • ItemAdding's thread name : Current Thread
  • ItemAdded's thread name : null


Next, I added <Synchronization>Synchronous</Synchronization> in Elements.xml.


<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <Receivers ListTemplateId="104">
      <Receiver>
        <Name>EventReceiver1ItemAdding</Name>
        <Type>ItemAdding</Type>
        <Assembly>$SharePoint.Project.AssemblyFullName$</Assembly>
        <Class>EventReceiverProject4.EventReceiver1.EventReceiver1</Class>
        <SequenceNumber>10000</SequenceNumber>
        <Synchronization>Synchronous</Synchronization>
      </Receiver>
      <Receiver>
        <Name>EventReceiver1ItemAdded</Name>
        <Type>ItemAdded</Type>
        <Assembly>$SharePoint.Project.AssemblyFullName$</Assembly>
        <Class>EventReceiverProject4.EventReceiver1.EventReceiver1</Class>
        <SequenceNumber>10000</SequenceNumber>
      </Receiver>
  </Receivers>
</Elements>


The Results are shown here: 
  • ItemAdding's thread name : Current Thread
  • ItemAdded's thread name : Current Thread

These are interesting results !!



I'll start to post blog today !!



I believe that today will become a memorial day.
I will start to write SharePoint dev topic in "English" from today.

I'm a SharePoint developer, and I have some knowledge in C#, ASP.NET, Silverlight, and Windows Phone 7.
I will introduce some effective topics  for SharePoint developers.

Please let me know when


  • there are some errors with my English.
  • there is something wrong about the technology.
  • you have better technology you would like to share.

thanks !!