Thursday, October 13, 2011

Get TaskID in SharePoint custom Visual Studio workflows

When you are working with custom workflows implementing in Visual studio, you might be sending the emails when a task is created. By default SharePoint sends an email when a task is assigned to a user. But, if you want to customize the email body and subject, then you will use send mail activity and will give link to the user. Here the problem starts.
In CreateTask activity in Visual Studio you cannot get the taskID as the task is not yet created. What to do??? So, to get the task identifier we have to implement the below approach.
  1. CreateTask Activity
  2. TaskCreated Activity 
  3. SendMail Activity
  4. OnTaskChanged Activity
  5. TaskComplete Activity
Remember, until unless the Activity TaskCreated is executed the TaskID will not be available in workflow context. The main reason behind is, the task created information is not caught by SharePoint workflow anywhere until we run this activity. So, in the TaskCreated activity you can get the AfterProperties of the task and in those properties you will get the recent created task identifier which is integer.

So, note that in custom workflows which are implementing through Visual Studio the only way you can get the TaskID is AfterProperties of the TaskCreated activity. I have wasted hours when I was learning these. Hope you liked it.

The context has expired and can no longer be used–SharePoint and Reporting Services

Error:

"System.Web.Services.Protocols.SoapException: Report Server has encountered a SharePoint error. ---> Microsoft.ReportingServices.Diagnostics.Utilities.SharePointException: Report Server has encountered a SharePoint error. ---> Microsoft.SharePoint.SPException: The context has expired and can no longer be used. (Exception from HRESULT: 0x80090317) ---> System.Runtime.InteropServices.COMException: The context has expired and can no longer be used. (Exception from HRESULT: 0x80090317) --- End of inner exception stack trace --- at Microsoft.ReportingServices.WebServer.ReportingService2005Impl.GetDataSourceContents(String DataSource, DataSourceDefinition& Definition) at Microsoft.ReportingServices.WebServer.ReportingService2006.GetDataSourceContents(String DataSource, DataSourceDefinition& Definition)"

Solution:

This was coming completely due to the sever clock has wrong time set. So, by adjusting the time on the server solved the problem.

Special thanks to "Steve Mann" for finding the solution. It is a great find as it is just by guessing and thinking in different ways. Good one Steve.

Saturday, October 8, 2011

Close SharePoint 2010 Dialog through code

In SharePoint 2010, the new feature is added is the dialog framework. With the help of this, user stays on the same page and able to get the information without go away from the current page. So, there are ways that we can close the dialog from the code in different ways. Below are the mainly used implementations in javascript and code behind.
Javascript:
<script type='text/javascript'>window.frameElement.commitPopup()</script>

The window.frameElement is the node which holds the current dialog window. commitPopup() method which commits the popup and closes the dialog from the page window. So, by simply calling the above method, the dialog window will close automatically.

Code-Behind:
HttpContext context = HttpContext.Current;
if (HttpContext.Current.Request.QueryString["IsDlg"] != null){
context.Response.Write("<script type='text/javascript'>window.frameElement.commitPopup();</script>");
context.Response.Flush();
context.Response.End();
}

The dialog framework recognizes an additional parameter in the request named "IsDlg=1", which says open the page in dialog box. So, in code-behind simply check for query string parameter and if it exists then call the javascript method mentioned above by writing it to browser. So, when it executed the dialog will be closed.

This is a very nice tip which helps in some custom implementations. Hope it helps.

Exception of type 'System.Workflow.ComponentModel.WorkflowTerminatedException' was thrown

This is the error you see when you use the TerminateActivity in Windows workflow foundation/Visual Studio workflow development for SharePoint applications. The main reason behind why this exception is "We are terminating the current running workflow in middle and framework rises the exception that the workflow is terminated".

The main use of this TerminateActivity is for terminating workflow only. But, I do not recommend to use this activity in your workflows as this is a kind of exception which is throwing by WWF framework. Instead we could try

  • Filter the logic by if, else and end the workflow.
  • By throwing the exception from your code and by using the FaultHandler catch the exception and write it to logs.
  • If we want to stop the workflow, we may write the code to stop the workflow by using CancelWorkflow(workflow).
  • Even if you use the activity if you do not want to  see the above exception in the workflow logs then you might do this. From the "Properties" window the attribute "Error" – fill this field with some text like "Workflow terminated as the reviewers not found for the current item" etc. So that user can understand the error clearly instead of the exception details.

Hope it helps.