Showing posts with label SharePoint. Show all posts
Showing posts with label SharePoint. Show all posts

Thursday, March 14, 2013

SharePoint Workflow CreateTaskActivity and OnTaskChangedActivity must be one-to-one mapping

In a Visual Studio workflow for SharePoint 2010, if you have a series of complex logic that check various conditions to determine what to do if a task is completed, you may be tempted to put in multiple OnTaskChanged activities with the token tied to the same CreateTask activity.  I have recently tried that.  The flow of the workflow looks pretty clear and natural visually.  It built and deployed successfully and started and executed the steps successfully until it hit the second OnTaskChanged.  The Workflow History logged "An error has occurred in ", and the SharePoint log logged this error:

Error in commiting pending workflow batch items: System.ArgumentException: 0x80070057     at Microsoft.SharePoint.Library.SPRequestInternalClass.RegisterEventReceiver(String bstrUrl, String bstrListName, EventReceiverOperation operation, Guid guidId, String bstrName, Guid guidSiteId, Guid guidWebId, Guid guidHostId, Int32 dwHostType, Int32 dwSynchronization, Int32 dwType, Int32 dwSequenceNumber, String bstrRemoteUrl, String bstrAssembly, String bstrClass, Guid solutionId, String bstrData, String bstrFilter, Int32 dwCredential, Guid contextObjectId, Guid contextType, Guid contextEventType, Guid contextId, Guid contextCollectionId)     at Microsoft.SharePoint.Library.SPRequest.RegisterEventReceive.....

THe bottomline is, put one OnTaskChanged activity in a While activity.  With a couple of IfElse in there, the workflow would look confusing visually, but it would work fine at runtime.

Saturday, March 9, 2013

FileNotFoundException after SharePoint workflow DelayActivity

I noticed that a SharePoint 2010 workflow that's deployed to my dev SharePoint farm kept logging " failed to run" in the Workflow History after every so often.  Turned out that every time the Delay Activity comes out of its time out, this error is logged.  The workflow is stuck forever in the In Progress status though.  Found in the SharePoint ULS log the following everytime this happened:

03/09/2013 20:50:13.76  OWSTIMER.EXE (0x09F0)                    0x20E0 SharePoint Foundation          Legacy Workflow Infrastructure 75yn Unexpected Load Workflow Assembly: System.IO.FileNotFoundException: Could not load file or assembly 'My.Content.WF.ClientReview, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1f310f3d9eb1728b' or one of its dependencies. The system cannot find the file specified.  File name: ''My.Content.WF.ClientReview, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1f310f3d9eb1728b'     at System.Reflection.RuntimeAssembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)     at System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(AssemblyName assemblyRef, Evidence assemblySecurity, RuntimeAssembly reqAssembly, S... 1746069c-9c8e-2075-8ca7-47e33a38cd91
So what was going on?  My workflow only references SharePoint assemblies, and itself is indeed in the GAC.  A closer look shows that this was thrown from OWSTIMER.EXE.  So it's the timer job service.  Apparently the Delay Activity relyies on the timer job service to fire.  Just like w3wp.exe, it needs a restart to recognize newly changed assemblies in the GAC.  Sure enough, I restarted the timer job service, started a new WF, and the Delay Activity fired successfully after coming out of its timeout. 

Friday, February 17, 2012

Cannot connect to the SharePoint site in Visual Studio 2010

When creating a SharePoint in Visual Studio 2010 on a SharePoint server, you may still get the error : "Cannot connect to the SharePoint site":



You are using a site collection administrator account but the problem is that the site collection admin account doesn't have access to the SP config database and content database. Note that Visual Studio goes against the API directly so it can't do anything until it can read from the database. Here's what's in the SP log:

02/17/2012 15:08:49.68 vssphost4.exe (0x071C) 0x136C SharePoint Foundation Database 880j High SqlError: 'Login failed for user 'us\siteAdminDeveloper'.' Source: '.Net SqlClient Data Provider' Number: 18456 State: 1 Class: 14 Procedure: '' LineNumber: 65536 Server: 'US.local,1433'
02/17/2012 15:08:49.69 vssphost4.exe (0x071C) 0x136C SharePoint Foundation Database 3351 Critical SQL database login for 'SharePoint_Config' on instance 'SqlHost' failed. Additional error information from SQL Server is included below. Login failed for user 'US\siteAdminDeveloper'.

Since you are doing development on SharePoint, use an account that's an Farm Administrator to avoid problems like this.

Thursday, November 4, 2010

SharePoint custom field definition considerations

When defining custom fields in XML for SharePoint, the element has numerous attributes and most of them are optional. It's important to think through.

I recently came across some fields defined with Sealed="TRUE". This attribute prevents the deletion of the column from a list once it's added (either added directly or by adding a content type that has this field). It's a good idea to enforce metadata consistency this way. However, what if a user mistakenly add a content type that has this field to a list, and then want to remove it? Well, there's no way unless writing a utility to delete it from the list using the API:

int fieldCount = l.Fields.Count;
for (int i = fieldCount - 1; i > -1; i--)
{
SPField f = l.Fields[i];
if (f.Group == "MyGroup") //or other criteria
{
Console.WriteLine(f.StaticName + " " + f.AllowDeletion.ToString());
f.AllowDeletion = true;
f.Sealed = true;
f.Delete();
}
}
l.Update();


There is also the attribute of AllowDeletion. Interestingly, If AllowDeletion="TRUE" and Sealed="TRUE", the column can be deleted. AllowDeletion appears to have precedence. Need to do some research to figure out the exact differences between the two.

Wednesday, October 28, 2009

prompted for login and then 401.1 Access Denied when accessing Shared Services

Many people have written about this problem. When you are in the SharePoint Central Administration site, and click one of the Shared Services you created on the left Quick Launch menu (e.g. SharedServices1), you are prompted for login repeatedly and it eventually shows your the 401.1 Unauthorized: Access is denied due to invalid credentials error.

I have summarized below the possible causes and fixes that I have found on the web:
  1. Because the SSP URL has a domain name different from the machine name. This is almost always the case. A security feature called "loopback check" introduced in Windows 2003 SP1 and onward is the reason fro this. Apply a registry change on the server by following the MSFT support at http://support.microsoft.com/kb/926642/

  2. Because the name of the SSP you created (e.g. SharedServices1) happens to be the same as the name of the AppPool for the SharePoint Web Application that hosts the Shared Services Admin site. They must be named differently as the SSP instance will creates a AppPool automatically under its name.

  3. The SSP site collection administrators has only one user account. Not sure why this is would be a problem but adding a secondary administrator to the site collection helped with some of this error.

Saturday, February 28, 2009

System.InvalidOperationException: Correlation value specified does not match the already initialized correlation value on declaration approveRejectTas

Continuing with new discoveries of SharePoint workflow stuff, I ran into this logged exception after I added a SendEmail activity to my previously working workflow. So I know it's gotta be something in this Activity, which runs after a new Task is created in the workflow. Like every other Activity in the pipeline of the task process (Create Task, OnTaskChanged, CompleteTask etc), I gave this one the same correlation token as the task level token. Turn out that's the problem. Apparently the SendEmail activity (and a few other activities such as LogActivity) can only assume the workflow level correlation token.

Sunday, December 28, 2008

NullReferenceException on SPWorkflowTask.AlterTask ()

In a custom task edit form for a custom content type, the following code is used to update the task item:

Hashtable taskHash = new Hashtable();
taskHash["Status"] = "Approved";
taskHash["PercentComplete"] = "1";
SPWorkflowTask.AlterTask(this._taskItem, taskHash, true);

This works great most of the time, however, if the custom content type defines no fieldrefs, or more specifically, the content type XML does not have the node, as could be the case if only a custom form is included in the custom content type, the following exception would be thrown on the AlterTask line:

System.NullReferenceException was unhandled by user code
Message="Object reference not set to an instance of an object."
Source="Microsoft.SharePoint"

To fix this cryptic error, make sure that the node is in the content type definition XML, even when there're no child nodes.

Debug ASPX pages added to /LAYOUTS in SharePoint

How do you debug an ASPX page added to SharePoint's /LAYOUTS folder? There are many situations where you need to drop ASPX pages in the /LAYOUTs folder as part of a custom solution to some requriements. For example, an edit form for a custom content type, or a page for displaying data in a special way.

If the page fails, the exception is most likely logged in SharePoint log in the 12 hives, but wouldn't it be nice if you can step through the page in debug mode? All you need to do is to add the attribute debug="true" in the Page directive, set the breakpoint and attach the debugger to the process in Visual Studio, and voila!

Of course this is the standard way to debug ASP.NET pages. Only if you can remember it in the muddy water of SharePoint.

Tuesday, July 8, 2008

stsadm -o Deploysolution, to force or not to force?

There have been many discussions about this error that occurs when running stsadm -o deploysolution to deploy a solution:

The Execute method of job definition "SPSolutionDeploymentJobDefinition" (id "65274d73-2174-417e-b0fa-a63130953ee3") threw an exception. Failed to create feature receiver object from assembly "MyFeaturePack, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9f4da00116c38ec5", type "MyFeaturePack.FeatureReceiverApplyRootUI" for feature 0f9127e3-a930-41a3-8cda-21ded77d996d: System.ArgumentNullException: Value cannot be null.

Parameter name: type
at System.Activator.CreateInstance(Type type, Boolean nonPublic)
at System.Activator.CreateInstance(Type type)
at Microsoft.SharePoint.Administration.SPFeatureDefinition.get_ReceiverObject()

Common causes of the problem include that (1) the assembly not being deployed to GAC, thereby having code access issue; (2) the signing key is somehow wrong; (3) the class name is not what's defined in feature.xml.

However, this error occurred for a different reason. Actually I still don't know the reason but managed to figure out a solution. Somehow adding the "-force" parameter on stsadm -o deploysolution made it to work for me:

stsadm -o deploysolution -url http://mossdev/ -name MyUI.wsp -immediate -allowgacdeployment -force

Maybe -force wipes out some caching somewhere. Oh well.

Tuesday, July 1, 2008

Custom theme in a feature does not get applied

People have written about deploying various customizations and custom functionalities as features via SharePoint Solution packages. I'm not going to go through it step by step here. As usual, I want to focus on the 'unusual' or 'gotcha' stuff when it comes to SharePoint.

Assuming you already have your custom theme, feature.xml, and the solution packaging files (manifest.xml and the ddf) ready, you can deploy the theme via the solution package, which adds your custom theme to /12/TEMPLATES/THEMES. Then you need to tell your site collection or web to actually use this new custom theme. This is typically accomplished in the FeatureReceiver class so when you activate the feature, the theme is applied. There are of course other ways to do this. For example, you can write a simple console application to run on the SharePoint WFE server to apply the theme.

SPWeb has a method ApplyTheme() that allows you to change the web theme in the code.

public override void FeatureActivated(SPFeatureReceiverProperties properties) {
SPSite site = properties.Feature.Parent as SPSite;
if (site == null) {
throw new SPException("This feature should only be activated on a Site Collection");
}
SPWeb rootweb = site.RootWeb;
rootweb.MasterUrl = "MyNewUI.master";
rootweb.ApplyTheme("MyCustomTheme");
rootweb.Update();
}

The code works without any error and the master page is correctly applied to the root web when you activate the feature. However, the custom theme is not applied. What is wrong?

The problem is with the order of the last two methods on SPWeb. It is necessary to call SPWeb.Update() to commit the changes when you assign new values to many of the pulbic properties of SPWeb. However, calling Update() AFTER ApplyTheme() somehow wipes out the change ApplyTheme() makes. So in order for this to work, there cannot be an Update() call after ApplyTheme() is called on the same instance of SPWeb. The above code would work perfectly by simply switch the order of the two method calls:

................
rootweb.Update();

rootweb.ApplyTheme("MyCustomTheme");
...............


Some folks have mentioned that in order to apply a custom theme from feature activation, there can not be an entry in \12\TEMPLATE\LAYOUTS\1033\SPTHEMES.XML for the theme. I found this to be not true. SPTHEMES.XML is for displaying the available themes on _layouts/themeweb.aspx for user to select. It has bearing on how a theme works or how it's applied. Therefore, you can either modify SPTHEMES.XML in your FeatureReceiver class or you don't have to. Adding an entry would allow user to see the theme applied listed on on _layouts/themeweb.aspx. That's all.


.

Friday, June 27, 2008

SPGridView Filtering

SPGridView is an amazing control in WSS 3.0's Microsoft.SharePoint.WebControls namespace. It is feature-packed but unfortunately, there is little documentation on how to use it beyond the vanilla data-binding. The post at Bob's SharePoit Bananza is perhaps the most helpful work so far. And here's another one with a bit more code.

I want to talk about a couple of quirks that took me forever to figure out as I was trying to get the filtering working in my own web part:


  • It is important to assign the SPGridView object a ID value. This is often overlooked when you create and add the instance in the backend code
    SPGridView grid = new SPGridView();
    grid.ID = "gvw1"; //or any string

    If the ID is not assigned, ASP.NET would assign one like "ctl00" automatically as it renders the control. However, this would result in the filter dropdown on the column header not working. Upon clicking, it gives a generic javacript error "'null' is null or not an object". Here's the difference in the onClick attribute in the HTML table tag generated:

    ID property not assigned:
    onclick="SPGridView_FilterPreMenuOpen('ctl00_PlaceHolderMain_ctl00', 'ctl00_PlaceHolderMain_ctl00_SPGridViewFilterMenuTemplate', 'ctl00_PlaceHolderMain_ctl00_ctl01_SPGridViewMenu0', 'Title', event);

    ID property = "gvw1":
    onclick="SPGridView_FilterPreMenuOpen('ctl00_PlaceHolderMain_gvw1', 'ctl00_PlaceHolderMain_gvw1_SPGridViewFilterMenuTemplate', 'ctl00_PlaceHolderMain_gvw1_ctl01_SPGridViewMenu1', 'Title', event);

    There is really no difference other than the ctl100 vs gvw1. However, it costed me a lot of hairs to figure out that it DOES make a difference!

  • The columns with the filter one can not have spaces in the column name. This is typically not an issue as the internal name of any field in SharePoint has no space (concatenated by the underline if the display name has spaces). The problem could arise when the data comes from a different source or is manipulated with new columns added in the fly. For exmaple:
    this.grid.FilterDataFields = "Service Department";
    this.grid.FilteredDataSourcePropertyName = "FilterExpression"; this.grid.FilteredDataSourcePropertyFormat = "{1} = '{0}'";

    "Service Department" is a new column I added to the DataTable behind the ObjectDataSource, and it is the column that I want to filter on (It's the first column in the data source so no commas needed). However, it gives this error when dropping down the filter and clicking an item in the dropdown:
    Syntax error: Missing operand after 'Department' operator. at System.Data.ExpressionParser.Parse() at System.Data.DataExpression..ctor(DataTable table, String expression, Type type) at System.Data.DataView.set_RowFilter(String value) at System.Web.UI.WebControls.FilteredDataSetHelper.CreateFilteredDataView(DataTable table, String sortExpression, String filterExpression, IDictionary filterParameters) at System.Web.UI.WebControls.ObjectDataSourceView.CreateFilteredDataView(DataTable dataTable, String sortExpression, String filterExpression) at System.Web.UI.WebControls.ObjectDataSourceView.ExecuteSelect(DataSourceSelectArguments arguments) at System.Web.UI.DataSourceView.Select(DataSourceSelectArguments arguments, DataSourceViewSelectCallback callback) at System.Web.UI.WebControls.DataBoundControl.PerformSelect() at System.Web.UI.WebControls.BaseDataBoundControl.DataBind() at System.Web.UI.WebControls.GridView.DataBind()

    Again not very indicative what the problem is. Well, the space in the column is the problem. Changing the column name to "Service_Department" or "ServiceDeparment" and the code above accordingly fixed the problem.

Wednesday, June 4, 2008

Another permission issue often found in SharePoint production env

Often in production deployment of SharePoint, the people and the accounts used to install and configure the SharePoint server farm itself are different from the ones responsible for further setting up the services on the server. For example, when using an administrator account that's not the one used to create the SSP to configure the services in the SSP, an error of "Access Denied" is encountered, even when the account is a server admin, farm admin, and the SSP site collection admin. What's missing is the "Personalization Services Permissions" right in the SSP (last item under User Profiles and My Sites). The user account must have all the permissions in this SharePoint category to perform operations like User Profile configuration and My Site Settings configuration.

STSADM command results in null reference error

When STSADM command returns immediately with "Object reference not set to an instance of an object” error, it is typically due to the inadequate permission the user account running the command has. The account should have the following:
  • belongs to the Administrators group on the server where the command is running.
  • is a farm administrator
  • has full access (sysadmin) to the SQL Server Instance (no need to have access to the server on which SQL Server runs on).

This problem often happens in production environments where probably no user accounts have the broad access levels needed as described above. Because user accounts are tightly managed and servers deployed in different silos and managed by different teams in many production environments.

Friday, May 2, 2008

Do not rename SharePoint Site Column "Title"

WSS 3.0 Site Column "Title" is the default site column on the content type Item. This column should not be renamed. Often it's tempting to rename it to something more relevant in a list, when the content type of the list is being edited:

However, since it's a system site column, changing it affects every list in the entire site collection even if the change was initiated in a subsite. What's worse, it cannot be changed back to the name back to "Title". it gives this error when you attempt to change it back:
“The Column name that you entered is already in use or reserved”
This is obviously a bug but the SharePoint team disagree to some extent. The solution is to program against the object model and update the name:
SPSite siteCollection = new SPSite("http://siteCollectionUrl");
SPField field = siteCollection.RootWeb.Fields[""];
field.Title = "Title";
field.Update();
This page discusses the issue in more detail and provides a small console application that runs the above code. http://sharepoint.microsoft.com/blogs/fromthefield/Lists/Posts/Post.aspx?ID=15

Wednesday, April 30, 2008

SharePoint ACL issue when adding custom images, CSS, script files

I just customized the master page of a MOSS 2007 site and also applied a custom theme that I created to it. It looked great (it's quoted from the customer, no kidding :). However, when a senior manager of the client decided to view it, the site just kept prompting for login continuously. He's not impressed. I knew he was able to view the site BEFORE any customization was applied. So how could an unghosted master page and a modified copy of an existing theme result in access issue?

It turned out that the new resources, a few image files and new CSS files, that I added for the customizations are the culprit. Or rather the ACLs on these new files. Several files added to the images folder and themes folder in the 12 hives didn't inherit the permissions from the parent folder for whatever reason (most other added files inherited fine). As soon as the ACLs on these files are set properly, the site stopped the endless login prompting.