Monday, March 30, 2009

error while updating task

Today we face a strange problem.
We are facing this error

“The workflow's parent item associated with this task is currently in the recycle bin, which prevents the task from being completed.”


We are totally confuse what this error want to say.

Below is the scenario when we are getting error.

We have a requirement where admin can reassign task to of a user to another user.
So we are assigning a task to another user by changing “assign to” field of tasklist item.

When we are calling item.update() (also tried systemupdate() and updateoverwriteversion() ) we are getting this error.

But we are not able to understand why this error is coming.
Then after spending 2-3 hours we are come to a conclusin.
we are getting this error because we are trying to update task which has attached with custom content type and that content type has been inherited by workflow task item.

Even though that task is not created by workflow but if task created with content type that is being inherited by workflow task item then you can not update it directly it should be updated by workflow only.

So in our case we change the content type from workflow task item to simple task itme so that will solve our problem. But we are still not able to understand the error massage.

Sunday, March 22, 2009

Working with large list

Hi all,

Every time we start designing any project on sharepoint, we or I can say all, are having same problem.

Where to store the data in the sharepoint? (Which can be used as data table? in the language of dumb client who want to use sharepoint but don’t know why)

This is the million dollar question for starting any sharepoint project.

And billion dollar answer is none other than SharePoint Custom Lists.

And after deciding to go with the list another question will come about the taxonomy and structure of list.

You may also read so many article that more that 2000 item is hitting performance in the list. And that is true (that is what Microsoft says)

We found one of a very good document from Microsoft regarding the same Issue with title “Working with large lists” here is the link.


It really worth to read this article to decide architecture.

So we found one way to over come this situation.

Scenario: we are analysis SharePoint solution for one of the manufacturing plant.
And data is been stored in SharePoint list. For an example order list is containing a large number of data. So our first concern is how to implement this much data in one list.
One of the best solution we found is we created taxonomy for SharePoint list item. We decided to store order data in list with folder structure.

What we thought is that create a solution which will help to over come this 2k item problem.

First a folder is created for year like “2009” then month like “3” and then we are storing item in that folder. ( according to client they will not get orders more then 2k per month) other wise you keep segregating this with weeks, or days or may be hours according to your need.
So in our case if I’m adding an order today then my folder structure is
Order list/2009/3/my item

Note: we are storing/inserting item in the list programmatically and will post the same thing (how to do it programmatically?) asap

So this will solve our one problem.

And at the same time another problem is how to store other data or other related things like ….. history for an example. And each order is having multiple records in history.

So to over come this problem we user same structure with one more node.
Year/month/ordered/item in the list. and this date is form order created date not history created.

So we can store multiple items almost 2k item related to one particular order.
So our order history list we will have following structure.

Order History List/2009/3/OrderID#27/history item.
Again repeating the same that if history table updated in April even that structure will be the same as we are creating structure according to order.

So this way we can over come form SharePoint view limitation of 2ooo items.

There are a lot of other ways like creating subsite of Order (Main Item) and store related info in that subsite only. And many more are there according to our need and time.

But this is one of the way that we had done and working fine so we thought that better to share the same to every one so that we can get impact if some one had other idea for similar kind of implementation or some draw back or side effect of this implementation so that we can share the same with community. Please fill free to comment and share your idea regarding the same.

Thursday, March 5, 2009

Handling State Machine Workflow – Part 2

Hi All,


I am back with state machine worklfow part 2.

Please refer Handling State Machine Workflow – Part 1 for previous reading.

Let's proceed with part2. Ok, As of now we have services attached to the WorkflowRuntime, its now time to start an instance of the workflow.

First thing we will do here is get the name of the workflow class and we have to start the workflow from code. When we start the workflow, we will get an instanceID of that.

First get the WorkflowInstance class object.

WorkflowInstance instance;

instance = workflowRuntime.CreateWorkflow(typeof(Workflow1));


here workflow1 is the class name of state machine workflow. Change it accordingly to your state machine workflow class name. This method is even common for sequential workflow as well.

And then finally call,

instance.Start();

If you now take out the StateMachineWorkflowInstance like this,

StateMachineWorkflowInstance objinstance =
new StateMachineWorkflowInstance(workflowRuntime, instance.InstanceId);


you will get an idea about the first state being in objinstance. You can see it from its CurrentStateName property.

now, here comes the interesting part. As i said in previous part that you need to preserve the instance id because later at any other page or form, you may want to take the state machine workflow to different state. So you need to take out the same instance and perform the next state on the same instance. So for that you need to save this instance so that even machine is shut down due to power failure or any other thing. Then also you have instance saved in the database. For this, the very important line is.

instance.Unload();

Once you do this, your instance will get preserved to the database as we have attached the persistence service to the workflowruntime. Thanks to this service we are able to save it in the database.

The moment you unload the instance, it will be unloaded and freed from memory and stored in database, so even your memory is also free now. It will not keep running this workflow.

See the data stored in the persistence database once you unload the instance. Single Row will get inserted with that instance GUID. I have many other workflow instance persisted.



I will later explain you how we can take out a existing workflow instance and move our state ahead of same instance.

Wednesday, February 25, 2009

Programmatically Apply Theme to a site

Hi all,
If you want to apply a theme to a site programmatically then the code is pretty straight forward. Have a look at it:

using (SPSite parentSite = new SPSite(SPContext.Current.Site.Url))
{
//Allow the unsafe updates in site from the current user
parentSite.AllowUnsafeUpdates = true;
using (SPWeb currentWeb = parentSite.AllWebs[SPContext.Current.Web.Name])
{
using (SPWeb childWeb = currentWeb.Webs[name])
{
childWeb.AllowUnsafeUpdates = true;
//The code line shown below will apply the theme of the parent site to the child site
childWeb.ApplyTheme(currentWeb.Theme);
childWeb.Update();
childWeb.AllowUnsafeUpdates = false;
}
}
parentSite.AllowUnsafeUpdates = false;
}

Although this code works fine when you use it for applying theme to a site which already exists in the site collection, but this may not work (atleast in my case)when i tried applying a theme to a site which i am creating programmatically.
So if you are also facing same problem then instead of applying theme just after creating the site, move the code outside the create method and take reference of the newly created site and then call the above code. It will work !

In case you are still not able to understand it then write to us at sharepointkings@gmail.com or write a comment to this post.

Tuesday, February 24, 2009

Handling State Machine Workflow – Part 1

Hi All,

Today we are going to discuss about state machine workflow. First question arises is what is state machine workflow and when to use state machine workflow. I will explain this entire handling of state machine in series.

Ok coming back to our question, the answer is really very simple. If your process doesn’t have sequence of activity that needs to be followed and if you have something which has specific start and ending point, then better that you go with sequential workflow else go for state machine workflow.

Let me give you an simple example where you have different statuses defines and on each status you have to perform certain actions and those statuses can be changed from time to time from different page of Sharepoint or even from any other application which uses the state machine workflow.

Other example where you have bug tracking application which doesn’t have specific ending point as far as bug is concern. Bug can be in open state then it can be in In-Progress State, it can be in submitted state, it can be re-Opened state as many states as we define, which can be in any state and can change to any state.

Changing of state is called transition between states. Transition can happen from any state to any other state which is not fixed defined. In these kinds of scenarios you can use the state machine workflow.

In this article I am not going to show you how to create state machine workflow. I will talk about how to manage state machine workflow. By manage what I mean is how you can call the state machine workflow and change the state of workflow.

State machine workflow is very different story than sequential workflow. It has got many other things.

Now assume that you have created state machine workflow and hosted on one server and your applications for Sharepoint is running on the same server. Now all applications will use this workflow for an instance. So what we have here is every application will start workflow from code let’s say depending on condition and then maintain the instance of it. You need to maintain the instance of the workflow because you also need to change the state of the same instance to the different state.

So here is a full story how you can achieve all these.

First and for most, when you are designing your state machine workflow, do not forget to add persistence service to the workflow runtime. So that you can preserve the workflow instance in the database. Persistence service helps to store the workflow instance in the database when workflow goes idle.

Go to this location. Location may differ from machine to machine depending on framework.

C:\WINDOWS\Microsoft.NET\Framework\v3.0\Windows Workflow Foundation\SQL\EN.

Here you will find four SQL scripts that you need to run against your SQL server database which you want to connect your application with. One is for tracking service and the other is for persistence service.

So Create one database for workflow store because you need to preserve the instances of your state machine workflow in this database and later you need to retrieve this same instance back to the application for further application.

Now run those scripts against the database. First run Schema files and then run logic files.

This way you are ready with the database that can store the workflow instances. The mail reason to store the workflow instances in the database is that it is not a good practice to store long running workflows in memory. Better that we unload that instance and store it in database so it free the memory and when required, load that instance from the database again and then perform the operation and then again unload it.

Now you also have to add ExternalDataExchangeService service if you are familier with State machine workflow, because this services handles the call between client application and workflow host application for data exchange.

Now once you have the database setup for it, it’s time to add the persistence service to the workflow runtime and data exchange service.

WorkflowRuntime workflowRuntime = null;

workflowRuntime = new WorkflowRuntime();
string strWorkflowConnectionString = string.Empty;
strWorkflowConnectionString =
ConfigurationManager.ConnectionStrings[“connectionstringname”].ConnectionString;

workflowRuntime.AddService(new SqlWorkflowPersistenceService(strWorkflowConnectionString));
ExternalDataExchangeService dataExchange;
dataExchange = new ExternalDataExchangeService();

workflowRuntime.AddService(dataExchange);

objService = new SupplierService();

dataExchange.AddService(objService);

workflowRuntime.StartRuntime();


This way we can add both services to the workflow runtime. In my second part i will continue explaining how we can go ahead with taking instances on hand and move state machine workflow ahead.

Friday, February 20, 2009

using SPListItem.UpdateOverwriteVersion

Hi All,

Today we are going to discuss something about UpdateOverwriteVersion on SPListItem.

When you have versioning enabled on document library or list and when you do not want to create a new version even you are updating an item in the list or document library at that time you can use this method because Update will create version for the item.

Many times i also found that in workflow when you want to update any item on which workflow is running and if you use Update method on the SPListItem, it throws Error in terms on Error Starting in Workflow. When i use this UpdateOverwriteVersion, it didn't give me.

With the help of this method, you can also set certain properties like Author, Editor and Modified. Remember you need to change both Author as well as Editor on these properties to take effect.

Example :

using (SPSite objSite = new SPSite("http://server/"))
{
using (SPWeb objWeb = objSite.OpenWeb())
{
SPList objDocLib = objWeb.Lists["Shared Documents"];
SPListItem objItem = objDocLib.Items[0];
objItem ["Created"] = new DateTime(2008, 5, 5);
objItem ["Author"] = "{author}";
objItem ["Editor"] = "{editor}";
objItem ["Modified"] = new DateTime(2008, 5, 6);
objItem.UpdateOverwriteVersion();
}
}

That’s it.

Sunday, February 15, 2009

SharePoint Confusion.

Dear Readers,
As you know we all are using SharePoint since a long time now.
But still we are confused with a simple point.
What to use while SharePoint Development?

we have a simple scenario(s).

Scenario 1:

We are storing data in the list. You can consider that data is for Order List.
There are multiple people or group working on that order and we want to map that.

Now if we want to achieve this functionality in standard web application then we store order items in one table and number of people or group working on that order stored in another table with OrderID (Multiple rows). And fetch information with inner join.

But same thing if we want to go for SharePoint then we have two ways
1) Create another list and store Order List Item id (Lookup or manually maintained) with people or group working on that order. So this will work like two tables.
2) Create another Column in order list with people picker in same order list with multiple selections. So we can figure out how many people are working in the same order.

Now functionality wise both the way is fine.

But which will be the best way?
Simply saying we don’t have an answer.

We used both in different application but won’t find difference (till now).

But both the case has its own positive and negative point.

In one every time we need to have instantiate extra list object and fetch data and in another we can reach the limitation maximum number of user in a column. (No limit has been defined but we had not tried 1000+ different user in same people picker) and find specific one by looping with “;#” separation or ID separation.

So we want your inputs if any one facing any problem and solved it by any way Or we are sure that every one has this kind if confusion which will be better for longer run Or these kinds of scenario then share that with us and all the reader so that every one will be benefited.

We will update more such scenario(s) soon and also update your scenario(s).

Friday, February 6, 2009

Geting SharePoint web service response in DataTable c#

Hi all,
Few days before I was exploring how to get SharePoint web service response in DataTable instead of XMLNode?. for example you are using SharePoint List.asmx web service and try to get all SharePoint List collection get this response in DataTable.
here is code snippet.


/// <summary>
/// Get SharePoint List collections using SharePoint web service
/// Instead of Xml response it return DataTable.
/// remove XML name space from web service response.
/// </summary>
/// <returns></returns>
public DataTable GetSharePointListCollection()
{
try
{
//ListService is SharePoint List.asmx List Instance.
XmlNode ndSPLists = ListService.GetListCollection();
//to remove xml Name spance.
Regex StripXmlnsRegex =new Regex(@"(xmlns:?[^=]*=[""][^""]*[""])",RegexOptions.IgnoreCase|RegexOptions.Multiline|RegexOptions.Compiled| RegexOptions.CultureInvariant);

//to find and replace short XmlNameSpace like z:,rs: from xmlresponse by GetListItems method
Regex removeShortNameSpace = new Regex(@"(?<lessthan><)(?<closetag>[/])?(?<shortname>\w+:)\s*", RegexOptions.IgnoreCase|RegexOptions.Multiline|RegexOptions.Compiled|RegexOptions.CultureInvariant);

//remove namespace xmlnls from result xml..
string xmlResponse = StripXmlnsRegex.Replace(ndSPLists.InnerXml, "");

//find and replace short XmlNameSpace like z:,rs: from responce with space..
xmlResponse = removeShortNameSpace.Replace(xmlResponse, delegate(Match m)
{
Group closetag = m.Groups["closetag"];
if (closetag.Length != 0)
{
return "</";
}
else
{
return "<";
}

});
//load xml from removed XmlNameSpace and short name of XmlNameSpace..
//XDocument xmlDoc = new XDocument();
//xmlDoc = XDocument.Parse(xmlResponse);
xmlResponse = "<Lists>" + xmlResponse + "</Lists>";
XDocument xdoc = XDocument.Parse(xmlResponse);

using (StringReader reader = new StringReader(xdoc.ToString()))
{
DataSet dsSPLists = new DataSet();
dsSPLists.ReadXml(reader);
if (dsSPLists.Tables.Count > 0)
{
return dsSPLists.Tables[0];
}
}

return null;
}
catch
{
throw;
}
}

create a site programmatically in moss

Hi All,

Sometimes we often requires to create a site programmatically in code.

So here is a simple way we can create any site from code.

for that first you need to gain an access on Web or Site under which you want to create your site.

so i am writing a code in webpart just to demonstrate you the things, you can change the code accordingly where ever you are writing your code like in event handler or feature receiver.

SPContext.Current.Web.AllowUnsafeUpdates = true;
SPWebCollection objWebs = SPContext.Current.Web.Webs;
objWebs.Add("GAME ZONE", "Games Site", "This is the Games Site", 1033,"STS#0", true, false);
SPContext.Current.Web.AllowUnsafeUpdates = false;


Let us understand the parameters for this.

There are three overload for creating site. First overload simply give the name of the site that you want to create which does not give us much flexibility.

Rest two overloaded method has only one difference. Difference is of specifying the site template. you want to use team site, blank site, wiki, blog. What kind of a site you want to create goes here.

So one overloaded method with the SPWEbTemplate uses enumerations to choose from and the other overload which gives you an option to write down String for site template.


Now here is a list of Strings that you can place in the parameter as in the example it is STS#0 for Team Site.

STS#0 Team Site

STS#1 Blank Site

STS#2 Document Workspace

MPS#0 Basic Meeting Workspace

MPS#1 Blank Meeting Workspace

MPS#2 Decision Meeting Workspace

MPS#3 Social Meeting Workspace

MPS#4 Multipage Meeting Workspace

WIKI#0 Wiki

BLOG#0 Blog

and these are additional web template IDs

BDR#0 Document center—A central document management location for an enterprise

OFFILE#0 Records center—A central location in which records

OFFILE#1 managers can define routes for incoming files

CMSPUBLISHING#0 Publishing site

BLANKINTERNET#0 Publishing site—A site for publishing web pages on a schedule with workflow features enabled

BLANKINTERNET#1 Press releases site

BLANKINTERNET#2 Publishing site with workflow—A publishing site for web pages using approval workflows

SPSNHOME#0 A site for publishing news and articles

SPSREPORTCENTER#0 Report center—A site for creating, managing, and delivering web pages, dashboards, and Key Performance Indicators (KPIs)

SPSPORTAL#0 A starter hierarchy for an intranet divisional portal

PROFILES#0 A profile site that includes page layouts with zones

BLANKINTERNETCONTAINER#0 Publishing portal—a site collection preconfigured for revision-controlled, secure content creation and publication

SPSMYSITEHOST#0 My Site host—keep in mind that only one of these can be provisioned per Shared Services Provider

SRCHCENTERLITE#0 Search center—A site designed to deliver the search query and results experience

SRCHCENTERLITE#1 Search center—A superset of the previous; does not appear in navigation bars


These are the available templates.


1033 is for site in English language.


That's it. Your job is done. you have created site dynamically.

Thursday, February 5, 2009

Changing Home page Default.aspx programmatically in moss

Hi All,

Whenever we enter the URL in address bar of the browser for moss site, it automatically redirects to the Default.apsx. If we want user to go to some different page in the site.

so here is the code we write for that.

I am changing this in webpart so i am writing this code in webpart page. it is possible to have this code in Feature.

SPContext.Current.Web.AllowUnsafeUpdates = true;
SPFolder objFolder = SPContext.Current.Web.RootFolder;
objFolder.WelcomePage = "Shared%20Documents/Forms/AllItems.aspx";
objFolder.Update();
SPContext.Current.Web.AllowUnsafeUpdates = false;


Now when the user will hit the URL, it will automatically redirected to Shared Documents AllItems.aspx

That's it. you are done with this.



Share your SharePoint Experiences with us...
As good as the SharePointKings is, we want to make it even better. One of our most valuable sources of input for our Blog Posts comes from ever enthusiastic Visitors/Readers. We welcome every Visitor/Reader to contribute their experiences with SharePoint. It may be in the form of a code stub, snippet, any tips and trick or any crazy thing you have tried with SharePoint.
Send your Articles to sharepointkings@gmail.com with your Profile Summary. We will Post them. The idea is to act as a bridge between you Readers!!!

If anyone would like to have their advertisement posted on this blog, please send us the requirement details to sharepointkings@gmail.com