Welcome to MSDN Blogs Sign in | Join | Help

Issue with SPFile.SendToOfficialFile() while using with custom access policy (copy of WSS_Minimal)

Recently I had worked with an another interesting case with one of my customers. She has developed a custom webpart to iterate all the files in a SharePoint document library and send that file to a record center, also she want to implement partial trust and use least permission to the custom component. For that, she copied the WSS_Minimal.config file and added basic permissions. The below lines of code was using inside the custom webpart.

 

  SPList oList = oElevWeb.Lists["Shared Documents"];

                    SPFile oFile = oList.Items[0].File;

                    string strOutPut;

                    oFile.SendToOfficialFile(out strOutPut);

 

But the webpart failed to accomplish the functionality whenever she deploy the webpart dll to the webapplication’s bin direcoty and use her custom CAS policy based upon WSS_Minimal trust. From the call stack we came to know that the operation of sending the file to a record center need some high level permission (Full trust or GAC deployment) and the issue get resolved whenever we deploy the dll to the GAC or gave FullTrust as the Trust, but customer don’t want to go ahead with that resolution and want to create a custom WSS_Minimal file with exact permission set to execute her code.

 

Description: The application attempted to perform an operation not allowed by the security policy.  To grant this application the required permission please contact your system administrator or change the application's trust level in the configuration file.

Exception Details: System.Security.SecurityException: Request for the permission of type 'Microsoft.SharePoint.Security.SharePointPermission, Microsoft.SharePoint.Security, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c' failed.

Source Error:

The source code that generated this unhandled exception can only be shown when compiled in debug mode. To enable this, please follow one of the below steps, then request the URL:

1. Add a "Debug=true" directive at the top of the file that generated the error. Example:

  <%@ Page Language="C#" Debug="true" %>

or:

2) Add the following section to the configuration file of your application:

<configuration>
   <system.web>
       <compilation debug="true"/>
   </system.web>
</configuration>

Note that this second technique will cause all files within a given application to be compiled in debug mode. The first technique will cause only that particular file to be compiled in debug mode.

Important: Running applications in debug mode does incur a memory/performance overhead. You should make sure that an application has debugging disabled before deploying into production scenario.


Stack Trace:

 

[SecurityException: Request for the permission of type 'Microsoft.SharePoint.Security.SharePointPermission, Microsoft.SharePoint.Security, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c' failed.]

   Microsoft.SharePoint.SPSecurity.RunWithElevatedPrivileges(CodeToRunElevated secureCode) +40

   Microsoft.SharePoint.OfficialFile.RgofpFromListItem(SPListItem item, RecordsRepositoryProperty[]& rgofp) +1400

   Microsoft.SharePoint.OfficialFile.SubmitFile(SPFile file, String strRecordSeries, String& strAdditionalInfo) +2122

   Microsoft.SharePoint.OfficialFile.SubmitFile(SPFile file, String& strAdditionalInfo) +120

   Microsoft.SharePoint.SPFile.SendToOfficialFile(String& additionalInformation) +44

   AugTestLast.WebPart1.oButton_Click(Object sender, EventArgs e) +158

   System.Web.UI.WebControls.Button.OnClick(EventArgs e) +111

   System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument) +110

   System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +10

   System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +13

   System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +36

   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +6785

   System.Web.UI.Page.ProcessRequest(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +242

   System.Web.UI.Page.ProcessRequest() +80

   System.Web.UI.Page.ProcessRequestWithNoAssert(HttpContext context) +21

   System.Web.UI.Page.ProcessRequest(HttpContext context) +49

   ASP.DEFAULT_ASPX__82859748.ProcessRequest(HttpContext context) +4

   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +181

   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously

 

Resolution:

==========

After my research found the  specific permission sets that we need to provide to execute the code to send file to record center. To understand better about the CAS setting in WSS please take look at the below excerpt that I have taken from the below MSDN article.

http://msdn.microsoft.com/en-us/library/dd583158(office.11).aspx.

 

Windows SharePoint Services defines two trust levels of its own:

  • WSS_Minimal

  • WSS_Medium

 

The trust levels extend the Minimal and Medium trust levels of ASP.NET for Windows SharePoint Services. The trust levels are defined in security policy files, wss_minimaltrust.config and wss_mediumtrust.config. By default, Windows SharePoint Services 3.0 stores these files in the following location:

local_drive:\Program Files\Common Files\Microsoft Shared\web server extensions\12\config

By default, when you extend a virtual server with Windows SharePoint Services, Windows SharePoint Services sets the trust level to WSS_Minimal. This helps provide a secure trust level in which assemblies operate with the smallest set of permissions required for code to execute.

The following table outlines the specific permissions granted with the custom security policy files included with Windows SharePoint Services.

Permission

WSS_Medium trust level

WSS_Minimal trust level

AspNetHostingPermission

Medium

Minimal

Environment

Read: TEMP, TMP, OS, USERNAME, COMPUTERNAME

 

FileIO

Read, Write, Append, PathDiscovery:Application Directory

   

IsolatedStorage

AssemblyIsolationByUser, Unrestricted UserQuota

   

Reflection

   

   

Registry

   

   

Security

Execution, Assertion, ControlPrincipal, ControlThread, RemotingConfiguration

Execution

Socket

   

   

WebPermission

Connect to origin host (if configured)

   

DNS

Unrestricted

   

Printing

Default printing

   

OleDBPermission

   

   

SqlClientPermission

AllowBlankPassword=false

   

EventLog

   

   

Message Queue

   

   

Service Controller

   

   

Performance Counters

   

   

Directory Service

 

 

SharePointPermission

ObjectModel = true

 

WebPartPermission

Connections = true

Connections = true

Note   By default, Windows SharePoint Services does not grant access to the Microsoft SharePoint object model. To grant access, you must raise the associated trust level by one of several methods. The next section discusses these methods.

 

So, if we take a look at the WSS_Minimaltrust.config file we can see that it will not even allow us to execute SharePoint object model code because we must need to enable it by setting ObjectModel=true in Microsoft.SharePoint.Security.SharePointPermission in the custom CAS policy file. Once we do that then we can execute the code but once we use  oFile.SendToOfficialFile() then internally it is using a webservice _vti_bin/officialfile.asmx to send the file to the record center. We must need to be configure this in Central Administration > Application Management > Configure Connection to Records Center if we want to send the document through UI. By default, assemblies in the BIN directory do not have the required permission, System.Net.WebPermission to access Web services. To grant this permission, we must need to add the following to the corresponding IPermission element in the appropriate policy file:

 

              <IPermission

                      class="WebPermission"

                      version="1"

                            Unrestricted="true"

                                 />           

 

Once we do that then we can execute the SendToOfficialFile() method. Also here we have to enable to the following IPermission to send it successfully. If you are using a copy of WSS_MediumTrust.config then no need to add this one because it will be there by default.

              <IPermission

                     class="EnvironmentPermission"

                     version="1"

                     Read="TEMP;TMP;USERNAME;OS;COMPUTERNAME"

                            />

 

Below xml is a modified copy of WSS_MinimalTrust.config to execute the SendToOfficialFile() method. Also we can use Permission Calculator Tool to find out the exact permission levels that needed for a particular assembly http://msdn.microsoft.com/en-us/library/ms165077(VS.80).aspx, I have used this tool to find out the all permission sets of Microsoft.SharePoint.dll.

 

<configuration>

  <mscorlib>

    <security>

      <policy>

        <PolicyLevel version="1">

          <SecurityClasses>

            <SecurityClass Name="AllMembershipCondition" Description="System.Security.Policy.AllMembershipCondition, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>

            <SecurityClass Name="AspNetHostingPermission" Description="System.Web.AspNetHostingPermission, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>

            <SecurityClass Name="FirstMatchCodeGroup" Description="System.Security.Policy.FirstMatchCodeGroup, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>

            <SecurityClass Name="NamedPermissionSet" Description="System.Security.NamedPermissionSet"/>

            <SecurityClass Name="SecurityPermission" Description="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>

            <SecurityClass Name="StrongNameMembershipCondition" Description="System.Security.Policy.StrongNameMembershipCondition, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>

            <SecurityClass Name="UnionCodeGroup" Description="System.Security.Policy.UnionCodeGroup, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>

            <SecurityClass Name="UrlMembershipCondition" Description="System.Security.Policy.UrlMembershipCondition, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>

            <SecurityClass Name="WebPartPermission" Description="Microsoft.SharePoint.Security.WebPartPermission, Microsoft.SharePoint.Security, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"/>

            <SecurityClass Name="ZoneMembershipCondition" Description="System.Security.Policy.ZoneMembershipCondition, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>

 

            <!-- add the following 3 security class information to refer those later-->

            <SecurityClass Name="SharePointPermission" Description="Microsoft.SharePoint.Security.SharePointPermission, Microsoft.SharePoint.Security, Version=11.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />

            <SecurityClass Name="WebPermission" Description="System.Net.WebPermission, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>

            <SecurityClass Name="EnvironmentPermission" Description="System.Security.Permissions.EnvironmentPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>

 

          </SecurityClasses>

          <NamedPermissionSets>

 

            <PermissionSet

                    class="NamedPermissionSet"

                    version="1"

                    Unrestricted="true"

                    Name="FullTrust"

                    Description="Allows full access to all resources"

                        />

            <PermissionSet

                    class="NamedPermissionSet"

                    version="1"

                    Name="Nothing"

                    Description="Denies all resources, including the right to execute"

                        />

            <PermissionSet

                    class="NamedPermissionSet"

                    version="1"

                    Name="SPRestricted">

 

              <IPermission

                        class="AspNetHostingPermission"

                        version="1"

                        Level="Minimal"

                            />

             

              <IPermission

                    class="SecurityPermission"

                    version="1"

                    Flags="Execution"

                            />

 

              <IPermission class="WebPartPermission"

                   version="1"

                   Connections="True"

                            />

 

        <!--add the following IPermissions to allow to execute the object model code and webservices-->

              <IPermission

                     class="EnvironmentPermission"

                     version="1"

                     Read="TEMP;TMP;USERNAME;OS;COMPUTERNAME"

                            />

             

              <IPermission class="SharePointPermission"

                      version="1"

                      ObjectModel="True"

                      Unrestricted ="True"

                            />

 

              <IPermission

                      class="WebPermission"

                      version="1"

                            Unrestricted="true"

                                 />           

            </PermissionSet>

           

          </NamedPermissionSets>

 

          <CodeGroup

                  class="FirstMatchCodeGroup"

                  version="1"

                  PermissionSetName="Nothing">

            <IMembershipCondition

                    class="AllMembershipCondition"

                    version="1"

                        />

            <CodeGroup

                    class="UnionCodeGroup"

                    version="1"

                    PermissionSetName="FullTrust">

              <IMembershipCondition

                      class="UrlMembershipCondition"

                      version="1"

                      Url="$AppDirUrl$/_app_bin/*"

                            />

            </CodeGroup>

            <CodeGroup

                    class="UnionCodeGroup"

                    version="1"

                    PermissionSetName="SPRestricted">

              <IMembershipCondition

                      class="UrlMembershipCondition"

                      version="1"

                      Url="$AppDirUrl$/*"

                            />

            </CodeGroup>

            <CodeGroup

                    class="UnionCodeGroup"

                    version="1"

                    PermissionSetName="FullTrust">

              <IMembershipCondition

                      class="UrlMembershipCondition"

                      version="1"

                      Url="$CodeGen$/*"

                            />

            </CodeGroup>

            <CodeGroup class="UnionCodeGroup" version="1" PermissionSetName="Nothing">

              <IMembershipCondition

                    class="ZoneMembershipCondition"

                    version="1"

                    Zone="MyComputer" />

              <CodeGroup

                      class="UnionCodeGroup"

                      version="1"

                      PermissionSetName="FullTrust"

                      Name="Microsoft_Strong_Name"

                      Description="This code group grants code signed with the Microsoft strong name full trust. ">

                <IMembershipCondition

                        class="StrongNameMembershipCondition"

                        version="1"

                        PublicKeyBlob="002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293"

                                />

              </CodeGroup>

              <CodeGroup

                      class="UnionCodeGroup"

                      version="1"

                      PermissionSetName="FullTrust"

                      Name="Ecma_Strong_Name"

                      Description="This code group grants code signed with the ECMA strong name full trust. ">

                <IMembershipCondition

                        class="StrongNameMembershipCondition"

                        version="1"

                        PublicKeyBlob="00000000000000000400000000000000"

                                />

              </CodeGroup>

            </CodeGroup>

          </CodeGroup>

        </PolicyLevel>

      </policy>

    </security>

  </mscorlib>

</configuration>

Posted by sowmyancs | 0 Comments

A tricky work-around to avoid infinite loop while updating an item in ItemUpdated Event in a very special scenario.

I think this post’s title is little confusing, anyway here is another scenario to play with a List Event Handler. Recently I had worked with one my customers , he had implemented the code to send documents to a record center using SPFile.SendToOfficialFile() method. In the destination document library he had registered an event handler to catch the ItemUpdated event and update some metadata. Also there were several content types in the destination document library and there was an expiration policy for each content type which will automatically update a date time column “Expiration date”.

The issue was whenever he register the event handler it was not updating that column through the content type policy and we figured out that once we remove the this.DisableEventFiring & this.EnableEventFiring everything worked as expected, but then the major problem was from the ItemUpdated event he was updating the list item which results an infinite loop and wanted a work-around for that issue.

To resolve that infinite issue, we have created a static Boolean variable and updated its value whenever there is an ItemUpdated event and whenever there is a second ItemUpdated event fire due to the loop then we set the value to false and exits from the event. Thus this way it will not affect any other users and each time the static variable will set to false. Also to avoid any issue with multiple threads we have put a lock on the object’s instance.

Here is the sample code for that implementation.

   1: using System;
   2: using System.Collections.Generic;
   3: using System.Text;
   4: using Microsoft.SharePoint;
   5:  
   6: namespace EventHandlerTest
   7: {
   8:     class TestEventHandler : SPItemEventReceiver
   9:     {
  10:         private static bool IsItemUpdated = false;
  11:         object oObject = new object();
  12:  
  13:         public override void ItemAdded(SPItemEventProperties properties)
  14:         {
  15:             base.ItemAdded(properties);
  16:         }
  17:  
  18:         public override void ItemAdding(SPItemEventProperties properties)
  19:        {
  20:             base.ItemAdding(properties);
  21:         }
  22:  
  23:         public override void ItemUpdated(SPItemEventProperties properties)
  24:         {         
  25:             
  26:             lock (oObject)
  27:             {
  28:                 try
  29:                 {
  30:                     if (IsItemUpdated == true)
  31:                     {
  32:                         IsItemUpdated = false;
  33:                         return;
  34:                     }
  35:  
  36:                     if (!IsItemUpdated)
  37:                     {
  38:                         properties.ListItem.Update();
  39:                         IsItemUpdated = true;
  40:                     }
  41:  
  42:                 }
  43:                 catch (Exception ex)
  44:                 {
  45:                     IsItemUpdated = false;
  46:                 }
  47:                 finally
  48:                 {
  49:  
  50:                 } 
  51:             }           
  52:                        
  53:             
  54:         }
  55:  
  56:         public override void ItemUpdating(SPItemEventProperties properties)
  57:         {
  58:             base.ItemUpdating(properties);
  59:         }
  60:  
  61:     }
  62: }

Posted by sowmyancs | 0 Comments

Move a SPListItem without loosing its ItemId – Custom List

Once I got a requirement to move a list item from one folder location to another within the same list (e.g. move the item to a sibling) while retaining the same ItemID.

Example:

Here is the original structure...

List 1
     Folder 1
          Item A
     Folder 2

We need to move Item A to Folder 2 also the ItemID need be retained.

List 1
     Folder 1
     Folder 2
          Item A

If it is a custom list item ( in list template ID 100 – custom list) then through code we can’t copy the item using SPListItem.CopyTo() method and that information is added in the community content in our MSDN SDK article : http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.splistitem.copyto.aspx , we can see some people already mentioned about that concern so I hope this solution will be a work-around for that method as well.

We can work-around it in another way , export the Item A from the List and then import it to the same list after deleting & re-parenting the item. You can copy paste this code to a .NET console based application and modify the necessary stuffs. Also this way you can retain the ID of the list item as well.

   1: using System;
   2: using System.Collections.Generic;
   3: using System.Text;
   4: using Microsoft.SharePoint;
   5: using Microsoft.SharePoint.Deployment;
   6: namespace MoveItem
   7: {
   8:     class Program
   9:     {
  10:         static string siteUrl = "http://site";
  11:  
  12:         static void Main(string[] args)
  13:         {
  14:             string exportFolder = @"C:\export\";
  15:             string exportFileName = "Export_File.cmp";
  16:  
  17:             using (SPSite site = new SPSite(siteUrl))
  18:             {
  19:                 using (SPWeb oWeb = site.OpenWeb())
  20:                 {
  21:                     SPList oList = oWeb.Lists["MyList"];
  22:  
  23:                     SPListItem oItemA = oList.GetItemById(7);// ItemA
  24:  
  25:                     SPExportObject exportObject = new SPExportObject();
  26:                     exportObject.Id = oItemA.UniqueId;
  27:                     exportObject.Type = SPDeploymentObjectType.ListItem;
  28:  
  29:                     SPExportSettings exportSettings = new SPExportSettings();
  30:                     exportSettings.LogExportObjectsTable = true;
  31:                     exportSettings.LogFilePath = @"C:\export\log.log";
  32:                     exportSettings.SiteUrl = siteUrl;
  33:                     exportSettings.ExportMethod = SPExportMethodType.ExportAll;
  34:                     exportSettings.FileLocation = exportFolder;
  35:                     exportSettings.BaseFileName = exportFileName;                    
  36:                     exportSettings.ExportObjects.Add(exportObject);
  37:  
  38:                     SPExport export = new SPExport(exportSettings);
  39:                     export.Run();
  40:  
  41:                     // delete the item from Folder 1
  42:                     oItemA.Delete();                    
  43:  
  44:                     SPImportSettings settings = new SPImportSettings();
  45:                     settings.SiteUrl = siteUrl;
  46:                     settings.WebUrl = siteUrl;
  47:                     settings.FileLocation = @"c:\export";
  48:                     settings.LogFilePath = @"C:\export\log.log";
  49:                     settings.RetainObjectIdentity = false;
  50:                     settings.BaseFileName = exportFileName;                    
  51:  
  52:                     SPImport import = new SPImport(settings);
  53:   // handle the import event to re-parent the item
  54:                     import.Started += new EventHandler<SPDeploymentEventArgs>(import_Started);
  55:                     import.Run();
  56:                 }
  57:             }
  58:                 
  59:             }
  60:  
  61:         static void import_Started(object sender, SPDeploymentEventArgs e)
  62:         {
  63:           
  64:             using (SPSite site = new SPSite(siteUrl))
  65:             {
  66:                 using (SPWeb oWeb = site.OpenWeb())
  67:                 {
  68:                     SPList oList = oWeb.Lists["MyList"];
  69:  
  70:                     foreach (SPImportObject io in e.RootObjects) 
  71:                    { 
  72:                       if (io.Type == SPDeploymentObjectType.ListItem)               
  73:                       {
  74:                           io.TargetParentUrl = oList.RootFolder.ServerRelativeUrl + "/Folder2/";  
  75:                           
  76:                       }                                                                                                                                           
  77:                    } 
  78:  
  79:                 }
  80:             }
  81:         }
  82:     }
  83: }
  84:  
Posted by sowmyancs | 2 Comments

Important point need to remember while working with DateTime filtering values in FullTextSqlQuery

Once I was working with a custom search webpart issue in which search was implemented by using FullTextSqlQuery method, but it was not returning any results whenever we use contains predicate to filter the date time type columns.

There was a custom managed property of type Date Time to filter in the custom webpart. Since it was not returning any results in the custom webpart, we added that managed property in OOB advance search web part to include the custom managed property in the pick property section. After that, selected the date time managed property and executed the search by giving the same value that we given in the custom search webpart and it returned the correct results. We also checked the ULS logs to check the query used to execute the search with the date time type managed property in the filtering condition.

We saw that there is a difference in the construction of query between the custom webpart and the query executed in OOB (out-of-the-box).

SharePoint has only 3 filtering conditions with any managed property of type Date and Time. So, we must need to construct a query in a way that SharePoint can internally understand. If you pass ‘07/08/2009’ as your input date value SharePoint will convert that input date value in the format of ‘2009/07/08 18:30:00’ internally. You can see the query in the ULS logs once you execute a search in UI.

I have captured the SQL syntaxes for all the three filtering conditions. (eg: 07/08/2009 as our input date value)

Equal

Full Text Query: SELECT WorkId, Rank, Title, Author, Size, Path, Description, Write, SiteName, CollapsingStatus, HitHighlightedSummary, HitHighlightedProperties, ContentClass, IsDocument, PictureThumbnailURL  from scope() where ("scope" = 'All Sites') And ((Created >= '2009/07/07 18:30:00' and Created < '2009/07/08 18:30:00'))

Earlier than

Full Text Query: SELECT WorkId, Rank, Title, Author, Size, Path, Description, Write, SiteName, CollapsingStatus, HitHighlightedSummary, HitHighlightedProperties, ContentClass, IsDocument, PictureThumbnailURL  from scope() where ("scope" = 'All Sites') And (Created < '2009/07/08 18:30:00')

Later than

Full Text Query: SELECT WorkId, Rank, Title, Author, Size, Path, Description, Write, SiteName, CollapsingStatus, HitHighlightedSummary, HitHighlightedProperties, ContentClass, IsDocument, PictureThumbnailURL  from scope() where ("scope" = 'All Sites') And (Created > '2009/07/08 18:30:00')

You can refer the above syntaxes for building your SQL query for filtering date type managed properties.

Posted by sowmyancs | 1 Comments

Feature stapler for MySite to activate the Publishing Infrastructure Feature

Recently, I had worked with another interesting requirement in which customer has some specific requirement with MySites. Their basic requirement was whenever the “my site” get provisioned that time they want to activate the “Office SharePoint Server Publishing Infrastructure feature”.

So, the easiest way that we could accomplish their requirement was using a feature stapler.

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

<Elements Id="fa899b9d-85dd-4e0b-82d1-7cf7f6577136" xmlns="http://schemas.microsoft.com/sharepoint/">

<FeatureSiteTemplateAssociation Id="21e613ec-e03f-4499-b1a4-3095d5786b29" TemplateName="SPSPERS#0" />

</Elements>

Two OOB templates which are involved in MySite creation are SPSPers#0 and SPSMSiteHost#0. First one is for Home and the second one is for Profile – profile site will get created whenever we provision the SSP and it will just take the user account information as query string to show the details , (?people.aspx?domain\username) whenever we click on “My Profile” tab.

We have created a farm level scoped feature to associate the template to the Publishing Infrastructure feature. When this farm level stapling feature get installed, it staples the publishing infrastructure feature with SPSPERS#0 and then after whenever we create any MYSite then the Publishing Infrastructure feature automatically get activated. Also, for profile site since we are using a single site for all the users, we can manually activate it once and it will be available for all other users.

Here are some links which will give more information about MySite customization & Feature stapling.

http://blogs.msdn.com/sridhara/archive/2007/05/19/customizing-mysite-in-moss-2007.aspx

http://msdn.microsoft.com/en-us/library/bb861862.aspx

Posted by sowmyancs | 0 Comments

“who” is “where” given a map of SharePoint ?

Once I got a request from one of my colleagues in MS and his customer wants to find out “who” is “where” given a map of SharePoint. So, if there is a Site A being visited by X and Y and X happens to be interacting docLib B – is there a way one could query either the object model / database to find out.

1. Who is at Site A

Ans. X and Y

2. Who is uploading a document into dobLib B

Ans. X

It was really an interesting requirement, I had researched to find out a way and couldn’t find any built in feature to get this information except Auditing. Once you enable auditing it will log type of events that a specific user performing on a site in a table “AuditData”. You can see the user id and the type of objects (whether on a site, list, list item etc) and the occurred date in this table. Also you can pull the same details through object model.

I have written the following code snippet in a .NET console based application and was able to retrieve that information. I hope this will be helpful if anybody got this kind of requirement.

   1: static void Main(string[] args)
   2:         {
   3:             using (SPSite oSite = new SPSite("http://blrs2r04-08:31990"))
   4:             {
   5:                 using (SPWeb oWeb = oSite.OpenWeb())
   6:                 { 
   7:                     SPAuditQuery newQuery = new SPAuditQuery(oSite);
   8:  
   9:                     newQuery.SetRangeEnd(DateTime.Now); //Retrieve information 
  10:  
  11:                     SPAuditEntryCollection oAuditEntries = oSite.Audit.GetEntries(newQuery);
  12:                    
  13:                     foreach (SPAuditEntry oAudit in oAuditEntries)
  14:                     {
  15:  
  16:                         Console.WriteLine(oWeb.AllUsers.GetByID(oAudit.UserId).ToString() + oAudit.ItemType.ToString() + oAudit.EventName +  oAudit.Occurred.ToString());
  17:  
  18:                     }                    
  19:               
  20:                 }
  21:             }
  22:             Console.ReadLine();
  23:         }
Posted by sowmyancs | 0 Comments

Generate a report about all the sites and lists under a site collection

One of my customer wants monitors their SharePoint environment in order to meet governance requirement.

Primary goal was generate a report of site hierarchy under a site collection including webs and libraries etc. created during specific timeframe.

Thus, I have created a small utility – a .NET console based application which will accept a site collection URL as an input parameter and generate report which will dump the information name and created date of sites and lists.

Here is the code snippet.

   1: using System;
   2: using System.Collections.Generic;
   3: using System.Text;
   4: using Microsoft.SharePoint;
   5: using System.IO;
   6:  
   7: namespace SiteInformation
   8: {
   9:     class Program
  10:     {
  11:         static TextWriter reportfile = null;
  12:  
  13:         static void Main(string[] args)
  14:         {
  15:             try
  16:             {
  17:                 reportfile = new StreamWriter("SiteInfo.csv");
  18:  
  19:                 Console.WriteLine("Enter your site collection URL :");
  20:  
  21:                 string strUrl = Console.ReadLine();
  22:  
  23:                 SPSecurity.RunWithElevatedPrivileges(delegate()
  24:                 {
  25:                     using (SPSite oSite = new SPSite(strUrl))
  26:                     {
  27:                         using (SPWeb oRootWeb = oSite.OpenWeb())
  28:                         {
  29:                             SPWebCollection oWebs = oRootWeb.Webs;
  30:                             if (oWebs.Count == 0)
  31:                                 reportfile.WriteLine("No subsites under " + oRootWeb.Name);
  32:                             else
  33:                                 GetData(oWebs);
  34:                         }
  35:                     }
  36:                 });
  37:  
  38:             }
  39:             catch (Exception ex)
  40:             {
  41:                 Console.WriteLine(ex.Message);
  42:             }
  43:             finally
  44:             {
  45:                 reportfile.Close();
  46:                 reportfile.Dispose();
  47:             }
  48:             Console.WriteLine("Operation completed successfully !");
  49:             Console.ReadLine();
  50:         }
  51:  
  52:           static void GetData(SPWebCollection oWebs)
  53:           {
  54:               foreach (SPWeb oWeb in oWebs)
  55:                   {
  56:                       reportfile.WriteLine("*********************************************************");
  57:                       reportfile.WriteLine("Site URL " + oWeb.Url);
  58:                       reportfile.WriteLine("Site Name >> " + oWeb.Name + " || Created Date >> " + oWeb.Created.ToString());
  59:                       GetLists(oWeb.Lists);
  60:  
  61:                     if (oWeb.Webs.Count == 0)
  62:                         reportfile.WriteLine("No subsites under " + oWeb.Name);
  63:                     else
  64:                         GetData(oWeb.Webs);                  
  65:                   }
  66:           }
  67:  
  68:         static void GetLists(SPListCollection oLists)
  69:         {
  70:             foreach (SPList oList in oLists)
  71:             {
  72:                 reportfile.WriteLine("List Name >> " + oList.Title + " || Created Date >> " + oList.Created.ToString());
  73:             }
  74:         }
  75:     }
  76: }

I have attached the application in the format of a zip file with this post.

Posted by sowmyancs | 0 Comments

Attachment(s): SiteInformation.zip

How to filter AssignTo column with current user “[Me]” if the value is a group of members ?

Actually I got this requirement as a Question about using [me] filters for Group Membership:

Consider I have a SharePoint Group created called “My Group” and I am a member of the group.  I am adding an “Assigned To” column to a library and all users will be putting a GROUP name in that People/Group field (not individual names as each item is a team effort).  Well the problem is that when I filter by “Assigned To” with [Me] as the filter SharePoint does not evaluate down to group membership level – so it would not show me anything unless my name was specifically selected the “Assigned To” field.

We can’t achieve this functionality in out-of-the-box, but you can achieve it by customizing the <ListViewXml> in SharePoint designer.

Here are the steps…

1) open the corresponding Aspx in Sharepoint Designer
2) In the source code, locate the ListViewXml tag
3) Inside this tag, locate the Where clause (begins with "<Where" and ends with "/Where>")
4) Replace the contents of this tag with the following:


<Where>

<Or>

<Membership Type="CurrentUserGroups">

<FieldRefName="AssignedTo"/>

</Membership>

<Eq>

<FieldRef Name="AssignedTo"/>

<Value Type="Integer">

<UserID Type="Integer"/>

</Value>

</Eq>

</Or>

</Where>


Save the page, and you're ready to go.

Posted by sowmyancs | 0 Comments

How to delete a user from BDC permissions list

Once one my colleagues had a requirement where he want to delete users from ‘Business Data Catalogue Permissions’ programmatically.

Here are the few classes that you can use to deal with the BDC permissions programmatically:

Namespace: Microsoft.Office.Server.ApplicationRegistry.Infrastructure (Microsoft.SharePoint.Portal.dll contains the above namespace)

Classes:

1. BdcAccessControlList

2. IndividualAccessControlEntry

My colleague Varun has written a post about how to add a user to the BDC permission list through code, please take a look at his post for getting the complete snippet here.

Here I am giving the code snippet for deleting the users; however like adding the user we don’t have direct method to delete the user instead we need to do a little tweak.

   1: using System;
   2: using System.Collections.Generic;
   3: using System.Linq;
   4: using System.Text;
   5:  
   6: using Microsoft.Office.Server.ApplicationRegistry.Administration;
   7: using Microsoft.Office.Server.ApplicationRegistry.Infrastructure;
   8:  
   9: namespace RemoveUSER
  10: {
  11:     class Program
  12:     {
  13:         static void Main(string[] args)
  14:         {
  15:             SqlSessionProvider.Instance().SetSharedResourceProviderToUse("SharedServices1");
  16:             
  17:             try
  18:             {
  19:                 ApplicationRegistry registry = ApplicationRegistry.Instance;
  20:                 IAccessControlList acl = registry.GetAccessControlList();
  21:                 IAccessControlList acl2 = acl.Clone();
  22:                 acl.Clear();
  23:                 foreach (IAccessControlEntry entry in acl2)
  24:                 {
  25:                     if (entry.IdentityName.Equals("BLRS2R04-08\\Administrator"))
  26:                     {
  27:                         
  28:                     }
  29:                     else
  30:                     {
  31:                         acl.Add(entry);
  32:                     }
  33:                 }                
  34:                 registry.SetAccessControlList(acl);
  35:             }
  36:             catch (Exception ex)
  37:             {
  38:             }
  39:  
  40:         }
  41:     }
  42: }
Posted by sowmyancs | 0 Comments

workaround to the issue with the DataSheet View (if you have custom master page)

On creating a new ‘Datasheet View’ in a simple OOB Custom List or Document Library (where System master page is a custom master page) leads to either a hang (IE8) or an infinite loop (IE7)

Leading to ever growing of window height both resulting in a CPU crash.

During the script debugging found that the following are the two functions in Core.js which are going to infinite loop when custom master page with footer is present for the system pages.

GCWindowResize and GCOnResizeGridControl 

The workaround is to add counters in these two functions to overcome the infinite loop. The new functions would be as follows.

var win_resize_counter = 0;

        var obj_resize_counter = 0;

        function GCWindowResize(GCObject) {

 

            win_resize_counter++;

            if (win_resize_counter < 3) {

                if (TestGCObject(GCObject)) {

                    glGCResizeCounter = 0;

                    GCResizeGridControl(GCObject);

                }

            }

            else

                win_resize_counter = 0;

 

        }

        function GCOnResizeGridControl(GCObject) {

 

            obj_resize_counter++;

            if (obj_resize_counter < 2) {

                if (TestGCObject(GCObject)) {

                    if (glGCResizeCounter < cGCMaxGCResizeCount) {

                        glGCResizeCounter++;

                        GCResizeGridControl(GCObject);

                    }

                }

            }

            else

                obj_resize_counter = 0;

        }

For customizing the core.js in the supported way please find the below MSDN article

http://msdn.microsoft.com/en-us/library/cc768565.aspx

Posted by sowmyancs | 2 Comments

Issue with upgrading the web part pages created from the custom web part page template from SPS 2003 and MOSS 2007

Once I had worked with a case in which customer has created a custom web part page template in SPS 2003 as per the following MSDN article http://msdn.microsoft.com/en-us/library/dd583147.aspx. When customer upgraded from SPS 2003 to MOSS 2007 he found that the web part pages created in SPS 2003 based on the custom web part page templates are not upgraded correctly to MOSS 2007.

Their look and feel in MOSS 2007 is not similar to SPS 2003. As the issue is with the web part pages created from the custom web part page template we need to ensure that whether the mapping of custom web part page template is done correctly. Checked the Server under 12 hive whether custom web part page templates are available in MOSS 2007. The custom web part page templates are in place. Checked the Mapping file to verify whether the mapping of custom web part page template between SPS 2003 and MOSS 2007 is correct. The mapping is accurate between 60 hive and 12 hive of custom web part page templates.

Checked the “Docs” table in the MOSS 2007 content database to verify whether the set up path of the web part pages created from custom web part page template are accurate. But the “SetUpPath” column in the MOSS content database is NULL for the web part pages created from the custom web part page template. When we updated the “SetUpPath” column then the look and feel of this problematic pages are fixed as expected. As we cannot directly modify the database table checked with the SharePoint API to update this column in the database. But the “vti_SetupPath” property in the SPFile property bag is read only and we are unable to update its value using API. So decided to export t the web part pages created from the OOB web part page template to check the manifest.xml of this page. Then exported the web part pages created from the custom web part page template and checked the Manifest.xml. We found that the “vti_SetupPath” property is not set in the manifest.xml of the web part pages created from the custom web part page template. Decided to set this property in the manifest.xml and import it again to the web part pages library.

Following are the changes need to be done in the manifest.xml file of the affected web part pages after the export.  

  1.   Within the SharePoint list, get the list of items [Created using custom web part page template. Export all the list items using SharePoint Object model.  Though we can use stsadm command, its scope is restricted to web site only.  We are looking at list / list item levels.
  2. Once Export is successfully completed, delete the list items in the list [Those files which got exported]
  3. On Export, we get content migration package [This package gets stored in the location that we specify in the code ].
  4. The package consists of Manifest.XML file.  The xml file has the following tag.

 

<SPObject Id="23576837-bc5a-433f-9e38-93ba255dbb27" ObjectType="SPFile" ParentId="f95f1bdf-4459-4edf-8c3f-79820d73abd0"

 

                  ParentWebId="c93ce050-2346-4b0c-ab65-e997d5b326e3"

                  ParentWebUrl="/sites/Chandru"

                  Url="/sites/Chandru/Shared Documents/sowmyan6.aspx">

 

            <File Url="Shared Documents/sowmyan6.aspx" Id="23576837-bc5a-433f-9e38-93ba255dbb27" ParentWebId="c93ce050-2346-4b0c-ab65-e997d5b326e3" ParentWebUrl="/sites/Chandru" Name="sowmyan6.aspx" ListItemIntId="36" ListId="b51a6865-d9a8-41a5-b467-e00ab4d781d0" ParentId="f95f1bdf-4459-4edf-8c3f-79820d73abd0" TimeCreated="2009-04-09T20:32:16" TimeLastModified="2009-04-09T20:32:44" Version="1.0" IsGhosted="true" SetupPath="1033\STS\doctemp\smartpgs\spstd7.aspx" SetupPathVersion="3" SetupPathUser="1073741823" FileValue="00000000.dat" Author="1073741823"  ModifiedBy="1073741823">

                  <Properties>

                        <Property Name="vti_metatags" Type="StringVector" Access="ReadOnly" Value="GENERATOR Microsoft\\ SharePoint ProgId SharePoint.WebPartPage.Document HTTP-EQUIV=Content-Type text/html;\\ charset=utf-8 CollaborationServer SharePoint\\ Team\\ Web\\ Site" />

                        <Property Name="vti_cachednolayoutzones" Type="StringVector" Access="ReadOnly" Value="TitleBar" />

                        <Property Name="ContentTypeId" Type="String" Access="ReadWrite" Value="0x01010040A4775A0A71C7478867F9E357CD8475" />

                        <Property Name="vti_generator" Type="String" Access="ReadOnly" Value="Microsoft SharePoint" />

                        <Property Name="vti_cachedhastheme" Type="Boolean" Access="ReadOnly" Value="false" />

                        <Property Name="vti_cachednoperszones" Type="StringVector" Access="ReadOnly" Value="TitleBar" />

                        <Property Name="vti_cachedneedsrewrite" Type="Boolean" Access="ReadOnly" Value="false" />

                        <Property Name="vti_cachedzones" Type="StringVector" Access="ReadOnly" Value="TitleBar LeftColumn Header TopRow CenterLeftColumn CenterColumn CenterRightColumn Footer" />

                        <Property Name="vti_charset" Type="String" Access="ReadOnly" Value="utf-8" />

                        <Property Name="vti_parserversion" Type="String" Access="ReadOnly" Value="12.0.0.6335" />

                        <Property Name="ContentType" Type="String" Access="ReadWrite" Value="Document" />

                  </Properties>

                  <WebParts>

                        <WebPart Name="110ee2a6-d028-4d90-bbc1-bc19c8f885aa" AllUsersProperties="AQUAAAACKgBJACkAAz4AAAIqAEoAKQADPQAAAVUAYgAD//8bL19sYXlvdXRzL2ltYWdlcy93cGljb24uZ2lmDwFTAGIAA///BHRlc3QPDw==" Level="major" WebPartZoneID="TitleBar" WebPartTypeId="94e9c166-264a-f84b-2377-bccefb8b3771" IsIncluded="true" WebPartOrder="1" FrameState="0" />

                  </WebParts>

                  <Links>

                        <Link TargetId="d6f83029-a908-406f-981a-a93fdfcb618e" TargetUrl="/_layouts/images/blank.gif" IsDirty="false" />

                  </Links>

            </File>

 

      </SPObject>

5.  Do the above highlighted modifications (Add/Edit) in the manifest.xml file.

6.    Now, run the import code. [ Make sure that those files from SharePoint library are deleted before import is run.  Otherwise, the files  won’t be over written ].

7.    On successful import, the list item will now point to the correct template [As the setuppath of that item is rightly set]

Posted by sowmyancs | 1 Comments

SharePoint state machine workflow : some issues and work-arounds

In this post I am giving some possible issues that you may face while working with state machine workflow and the work around to resolve those issues.

Issue 1

=======

Sometimes, if you have a SharePoint state based workflow that has a DelayActivity and the DelayActivity never fire and error out eventually. The problem lies in the fact that the workflow calls  out to another DLL in the code activity following the DelayActivity. When the call is made a  " System.IO.FileNotFoundException: Could not load file or assembly" exception is raised (see below), though the DLL is in the GAC and has SafeControl entry in web.config. 

System.IO.FileNotFoundException: Could not load file or assembly 'Utilities, Version=1.0.0.0, Culture=neutral, PublicKeyToken=584ac65395d6cc3f' or one of its dependencies. The system cannot find the file specified. File name: 'Utilities, Version=1.0.0.0, Culture=neutral, PublicKeyToken=584ac65395d6cc3f' at RRURequestWorkflow.Workflow1.codeActivity2_ExecuteCode(Object sender, EventArgs e) at System.Workflow.ComponentModel.Activity.RaiseEvent(DependencyProperty dependencyEvent, Object sender, EventArgs e) at System.Workflow.Activities.CodeActivity.Execute(ActivityExecutionContext executionContext) at System.Workflow.ComponentModel.ActivityExecutor`1.Execute(T activity, ActivityExecutionContext executionContext) at System.Workflow.ComponentModel.ActivityExecutor`1.Execute...

Issue 2

=======

Some other occasions, if you have a state machine workflow with several activities. Whenever it reaches a delay activity, it throws following error in the ULS logs.

Engine RunWorkflow: System.Runtime.Serialization.SerializationException: Cannot get the member 'codeActivity1_ExecuteCode'.     at System.Reflection.MemberInfoSerializationHolder.GetRealObject(StreamingContext context)     at System.Runtime.Serialization.ObjectManager.ResolveObjectReference(ObjectHolder holder)     at System.Runtime.Serialization.ObjectManager.DoFixups()     at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)     at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)     a...              

...t System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream)     at System.Workflow.ComponentModel.Activity.Load(Stream stream, Activity outerActivity, IFormatter formatter)     at System.Workflow.ComponentModel.Activity.Load(Stream stream, Activity outerActivity)     at System.Workflow.Runtime.Hosting.WorkflowPersistenceService.RestoreFromDefaultSerializedForm(Byte[] activityBytes, Activity outerActivity)     at Microsoft.SharePoint.Workflow.SPWinOePersistenceService.LoadWorkflowInstanceState(Guid instanceId)     at System.Workflow.Runtime.WorkflowRuntime.InitializeExecutor(Guid instanceId, CreationContext context, WorkflowExecutor executor, WorkflowInstance workflowInstance)     at System.Workflow.Runtime.WorkflowRuntime.Load(Guid key, Creation...           

...Context context, WorkflowInstance workflowInstance)     at System.Workflow.Runtime.WorkflowRuntime.GetWorkflow(Guid instanceId)     at Microsoft.SharePoint.Workflow.SPWinOeHostServices.Send(SPWinOeWorkflow winoeworkflow, SPWorkflowEvent e)     at Microsoft.SharePoint.Workflow.SPWinOeEngine.RunWorkflow(Guid trackingId, SPWorkflowHostService host, SPWorkflow workflow, Collection`1 events, TimeSpan timeOut)

 

 

 Engine RunWorkflow: System.Workflow.Activities.EventDeliveryFailedException: Event "OnWorkflowItemChanged" on interface type "Microsoft.SharePoint.Workflow.ISharePointService" for instance id "36fc71f8-c048-4306-bd29-8ad1aa02a5c4" cannot be delivered. ---> System.Runtime.Serialization.SerializationException: Cannot get the member 'phase7SendRequestorPrintView_MethodInvoking'.     at System.Reflection.MemberInfoSerializationHolder.GetRealObject(StreamingContext context)     at System.Runtime.Serialization.ObjectManager.ResolveObjectReference(ObjectHolder holder)     at System.Runtime.Serialization.ObjectManager.DoFixups()     at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, Boolean isCrossAppDomain, I...        

...MethodCallMessage methodCallMessage)     at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)     at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream)     at System.Workflow.ComponentModel.Activity.Load(Stream stream, Activity outerActivity, IFormatter formatter)     at System.Workflow.ComponentModel.Activity.Load(Stream stream, Activity outerActivity)     at System.Workflow.Runtime.Hosting.WorkflowPersistenceService.RestoreFromDefaultSerializedForm(Byte[] activityBytes, Activity outerActivity)     at Microsoft.SharePoint.Workflow.SPWinOePersistenceService.LoadWorkflowInstanceState(Gu...               

...id instanceId)     at System.Workflow.Runtime.WorkflowRuntime.InitializeExecutor(Guid instanceId, CreationContext context, WorkflowExecutor executor, WorkflowInstance workflowInstance)     at

System.Workflow.Runtime.WorkflowRuntime.Load(Guid key, CreationContext context, WorkflowInstance workflowInstance)     at System.Workflow.Runtime.WorkflowRuntime.GetWorkflow(Guid instanceId)     at System.Workflow.Activities.WorkflowMessageEventHandler.EventHandler(Object sender, ExternalDataEventArgs eventArgs)     --- End of inner exception stack trace ---     at System.Workflow.Activities.WorkflowMessageEventHandler.EventHandler(Object sender, ExternalDataEventArgs eventArgs)     at Microsoft.SharePoint.Workflow.SPWinOEWSSService.RaiseEvent(SPWinOeWorkflow workflow, SPWorkflowEvent workflowEvent, O... 

...bject workItem, IPendingWork workHandler)     at Microsoft.SharePoint.Workflow.SPWinOeHostServices.Send(SPWinOeWorkflow winoeworkflow, SPWorkflowEvent e)     at Microsoft.SharePoint.Workflow.SPWinOeEngine.RunWorkflow(Guid trackingId, SPWorkflowHostService host, SPWorkflow workflow, Collection`1 events, TimeSpan timeOut)

Resolution for Issue 1 & 2:

After restarting the “windows SharePoint timer service” the both the above issues will get resolve. Root cause was, whenever you have workflow that has got a delay activity, the event is fired by the service(SPTimerV3), before it fires, it has to load the assembly from its bin or from the GAC, only one file(module loads) based on the assembly information specified in workflow.xml file loads.

Deploying the new binary after changing the workflow activities, the SPTimerV3 is not aware of the newly added binary; it won’t reload it unless you do a time reset. Unless you do a reset, the persistence (serialization or de-serialization) or loading of assembly would fail due to mismatch of types.

Issue 3

=======

Whenever you initialize the timeoutduration of 2 delay activities in the InitializeTimeoutDuration event, the delay activity will not work as expected.

Eg:  private void delayActivity2_InitializeTimeoutDuration(object sender, EventArgs e)

        {

                delayActivity2.TimeoutDuration = TimeSpan.FromMinutes(3);

        }

Resolution for Issue 3:

In state machine workflow we can’t initialize the timeoutduration by using the object name of the delay activity (eg: delayActivity2.TimeoutDuration = TimeSpan.FromMinutes(3);) instead use the sender parameter of the InitializeTimeoutDuration event, which will always be the currently running instance of the Delay,  cast it to a DelayActivity and set the value on the TimeoutDuration property.

When a state is entered in the state machine (or when other workflow activities like the ReplicatorActivity, WhileActivity or ConditionedActivityGroup are executed) the workflow engine makes a clone of activities from your workflow definition and execute them instead of the activities in your workflow definition.  For this reason you can't just change the activity as you did but you have to change the instance that the workflow is actually executing. 

Here is the sample:

  private void delayActivity2_InitializeTimeoutDuration(object sender, EventArgs e)

        {

               // delayActivity2.TimeoutDuration = TimeSpan.FromMinutes(3);

               (sender as DelayActivity).TimeoutDuration = TimeSpan.FromMinutes(3);

        }

 

The sender will be the instance of the DelayActivity that the workflow is actually executing.

You also found that if you bind the timeout property to a dependency field it allows you to set the values using the instance field. 

Posted by sowmyancs | 1 Comments

Things to remember while creating custom content types through feature.

Sometimes you may face an issue that, once you create new content type it will not display it in the Site Content Types in the site collection. You can check these issues by analyzing the custom Ctypes.xml deeply. Make sure that the you are adding the content type IDs correctly.

 

Please check the below image for getting an idea about the format of the content type IDs.

 

 

If you create a new content type then the new content type GUID must need to add as a prefix to the inheriting content type ID by separating it by “00”

Posted by sowmyancs | 1 Comments

Issue with SharePoint designer workflow to start under System Acccount.

If you create a workflow in SharePoint designer and if you use choose “When create a project, auto start this workflow”, then you may see that the workflow is not starting once you add an item. The reason

 

This behavior occurs because a security fix in Windows SharePoint Services 3.0 SP1 prevents declarative workflows from starting automatically under the system account. After you install Windows SharePoint Services 3.0 SP1, declarative workflows do not start automatically if the following conditions are true:

· The Windows SharePoint Services Web application runs under a user's domain account.

· The user logs in by using this domain account.

· The site displays the user name as System Account.

The details of this issue and the work around has been documented in the following

 KB http://support.microsoft.com/kb/947284

 

Posted by sowmyancs | 1 Comments
More Posts Next page »
 
Page view tracker