Saturday, March 10, 2012

The new things in SharePoint 15 Object Model - Part 2

In the previous post, I introduced some new methods in come class’ in SharePoint 15 Object Model. In this post, I would like to show more new methods that help you prepare to upgrade your product to new baseline and improve your performance.

1. SPFieldLookup: As you known, the schema of this column contains information the original list and column that this column is looking to. If you need to get the original list and column, you must read and analyst data from schema. In new object model, you just get from method GetJsonClientFormFieldSchema() method and parse it to Json object. It’s easily to get an object and improve your code.

2. Microsoft SharePoint Foundation 15 has exposed the new class named “SPFileRightsManagementSettings” for getting information about the download file. This class defined 5 properties and without any method, I don’t know why Microsoft did not introduce any method for this class.


  • AllowPrint: this property indicates whether the file is able to print or not. 
  • AllowScript: allow the viewer can be run the script while reviewing the document. 
  • AllowWritecopy: allow the viewer can write down a copy. 
  • DocumentAccessExpireDay: get the day which document is available to download. 
  • GroupName: show the group which has permission can be view this document. 


There is only 1 noticed for any object of this class is not guaranteed about thread safe, that means this object must be disposed and released the memory after used.

Because companies often have restrictions that require their files to be stored in nonencrypted formats, SharePoint Foundation does not store files in encrypted, rights-managed file formats. However, SharePoint Foundation calls an IRM protector to convert the stored file to an encrypted format each time a user downloads the file. Similarly, when a user uploads a rights-managed copy of a file, SharePoint Foundation calls the appropriate IRM protector to convert that copy to a nonencrypted format before it is stored. As a result, you do not need to create custom solutions to enable searching or archiving of document libraries where IRM is enabled. Storing the files in nonencrypted format ensures that the current Search indexing service is able to crawl content stored on the servers. Search results are already scoped to user permissions, so the user never sees search results that include content to which they do not have some level of access.”

In SharePoint Foundation, IRM is enabled for any files in document libraries and Site Collection Admin can choose the method to protect the downloadable file. Thus, IRM must be enabled at the document libraries level. For more information read more here

3. SPSolutionExporter: used to export a web site as a template and export a workflow as a workflow template. This class expose new method called “ExportFolderToList” to export a specific folder as an object to the gallery.

public static string ExportFolderToList( SPFolder folder, string solutionFileName, string title, string description, SPList solutionList ) 

For being time, Microsoft does not show how big the folder can be exported. The folder size exports as a solution file template must be less than the maximum size allowed unless it throws exception exceeds the maximum allowed.

Thursday, March 8, 2012

The new things in SharePoint 15 Object Model - Part 1

From the technical preview document, SharePoint 2015 has been updated a lot of methods that help developers improving the code.

1. The first thing is from SPUtility, this class gives a supplementary the method GetLayoutsFolder to specify the layout folder.

SPUtility.GetLayoutsFolder(SPWeb);
SPUtility.GetLayoutsFolder(SPSite);

If site.CompatibilityLevel returns the value greater than or equal 15, the method GetLayoutsFolder() returns "_layouts/site.CompatibilityLevel", otherwise returns "_layouts".

In aditional, there are 3 new propertie:

ContextCompatibilityLevel: Gets the compatibility level of the context site ContextLayoutsFolder: Gets the versioned layouts folder for the context site CurrentThemeFolderName:  Gets the name of the current theme folder

2.  ASP.NET has been supported Control.Page to regist the script on client by ClientScript. Almost developers often use this object to regist, but with SharePoint 2015 object model we can use the new class to replace Control.Page class.

SPPageContentManager also has fully methods to perform like Control.Page such as IsClientScriptBlockRegistered, IsStartupScriptRegistered, RegisterClientScriptBlock, RegisterHiddenField, RegisterScriptFile, RegisterStartupScript

3. SharePoint 2015 also expose new properties of SPWorkflowEventProperties
  •  AssociationId: Gets the identifier of the workflow SPWorkflowAssociation. 
  • AssociationName: Gets the name of the workflow SPWorkflowAssociation.
  • CorrelationId: Gets the correlation identifier for the workflow, if supplied.
  • Created: Gets the DateTime value for when the workflow was created.
  • ItemGuid: Gets the identifier of the workflow ParentItem.
  • ItemId: Gets the identifier of the workflow ParentItem.
  • ListId: Gets the identifier of the workflow ParentList.
  • Modified: Gets the last DateTime the workflow was modified
  • StatusText: Gets the string that represents the status of the workflow.
  • StatusValue: Gets the integer that represents the workflow status.
  • TemplateId: Gets the identifier of the workflow association base template.
This helps us improve performance a lot because these properties can be access directly when workflow is running. Of course, defends on the purpose of your project but these properties reduce the time to build a workflow a lot. That's good upgrading.

Tuesday, March 6, 2012

Could not create site or list by reserved name?


As you know, Windows reserved some words as a device configuration such as CON (CON known as console), PRN (PRN known as printer device)…Thus, we cannot create a folder or file name which the name were registered. I don’t think this issue affected to SharePoint because before SharePoint save anything, it always validates the input data to be sure all texts are correct.

When I show my issue to my colleague, they were for sure that I didn’t configure SharePoint farm correctly or my SharePoint server had have a big problem. I didn’t have any comment or idea for this issue, but I was ensured that there was a problem with SharePoint.

Let’s try with these steps:
  • ·        Create a site or a list with named “CON”, “COM1” or any name which are reserved by windows.
  • ·        No validation and continue saving, but after finish, the page redirected look like:



In general, SharePoint will show the message after validated data input, but in this case, SharePoint didn’t. Anyone knows is it a work as design or SharePoint issue?

Tuesday, February 28, 2012

How to detect SharePoint platform is MOSS or WSS?

SharePoint platform wasn't show special thing to determine MOSS or WSS is running currently. But we can check the feature in feature collection to detect the default feature for MOSS. When we install MOSS, there are 2 features as default in MOSS flatform:OssNaviation and Publishing. Just check these feature, the code snippet look like:



 private bool CheckMossOrWss()
        {
            bool isMOSS = false;

            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                SPFeatureDefinitionCollection features = SPContext.Current.Site.WebApplication.Farm.FeatureDefinitions;
                SPFeatureDefinition docSetfea = features.FirstOrDefault(f => (f.DisplayName == "DocSet" || f.DisplayName == "Publishing"));
                 
                isMOSS = (docSetfea != null);
           
            });
            return isMOSS;
        }


Hope this help.

Tuesday, February 14, 2012

Working on locked site in site collection

Sometime we need to go through each site in site collection to update the properties bag, or whenever we need to loop on all site in site collection to do something, the code is simple like this:

foreach(SPSite site in webapp.Sites)
{
    //TODO: your code here
}

Everything works fine if Administrator did not lock any site in site collection. The administrator can go to Central Administration -> Application Management -> Site quote and lock, then perform the locking for one of site in site collection. Of course the code you won't work correctly and throw an exception:

Microsoft.SharePoint.SPException: Access to this Web site has been blocked.Please contact the administrator to resolve this problem. ---> System.Runtime.InteropServices.COMException (0x81020071): <nativehr>0x81020071</nativehr><nativestack></nativestack>Access to this Web site has been blocked.Please contact the administrator to resolve this problem.   at Microsoft.SharePoint.Library.SPRequestInternalClass.OpenWebInternal(String bstrUrl, Guid& pguidID, String& pbstrRequestAccessEmail, UInt32& pwebVersion, String& pbstrServerRelativeUrl, UInt32& pnLanguage, UInt32& pnLocale, String& pbstrDefaultTheme, String& pbstrDefaultThemeCSSUrl, String& 

To avoid the exception happens and the code will still continue if the site cannot access to, we should use the try/catch block to bypass the error:

foreach(SPSite site in webapp.Sites)
{
     try
     {
           //TODO: your code here
     }
     catch(Exception ex)
     {
         //Log the error here to know which site cannot be accessed
     }
     finally
     {
          //if you have an opening site to get the property from SPWeb, please close before dispose SPSite object
          site.Close();
          site.Dispose();
     }
}

The code above worked fine and everything seems to be right, but it's not the best practice here for a large site collection. Assume we need to loop for more than 1 thousand site in site collection, it's for sure that the code above is not good because everytime exception happens, the object exception must be initilized and go through final block to close and dispose object model. 

In this topic, I would like to check if the site cannot be accessed, we will bypass and continue on another site, the code will change:

foreach(SPSite site in webapp.Sites)
{

                FieldInfo fi = typeof(SPSite).GetField("bitField", BindingFlags.Instance | BindingFlags.NonPublic);
                if (fi == null)
                {
                    continue;
                }
                SPSite.BitField bitField = (SPSite.BitField)fi.GetValue(site);
                //check if locked site
                bool IsReadLock = (bitField & SPSite.BitField.readLock) > (SPSite.BitField)0u;
                bool IsWriteLock = (bitField & SPSite.BitField.writeLock) > (SPSite.BitField)0u;
                if (IsReadLock || IsWriteLock)
                {
                    continue;
                }

                //TODO: Your code here
}

Now, there is no try/catch block to receive the exception but there is no exception in this case, because we don't go and work on locked site.

Any another suggestion are welcome.

Hope this help.

Wednesday, January 11, 2012

Properties or AllProperties of SPWeb / SPWebApplication

Properties and Properties Bag may be differently if you are working on SharePoint. Especially for to update and remove data from their collection.



If you want to add

webApp.Properties.Add(p1);

That means you just add a propery to Web Application's properties and SPWeb's properties bag. However, if you remove this key out properties list, like following the code:

webApp.Properties.Remove(p1);

That means you just remove p1 out from SPWeb's properties bag, and in Web Application's properties is still existed. So, at the next time, you will never add or after sucessfull adding, nothing is added into SPWeb.

So, the best practice is always update or remove from both properties to be sured the system works correctly.


Add Properties


web.AllowUnsafeUpdates = true;


//Add property if not exist

if (web.AllProperties[strPropertyKey] == null)
{
       web.AllProperties.Add(strPropertyKey, strPropertyValue);
}




if (web.Properties[strPropertyKey] == null)
{
       web.Properties.Add(strPropertyKey, strPropertyValue);
}



web.Update();
web.Properties.Update();
web.AllowUnsafeUpdates = false;

Update properties



web.AllowUnsafeUpdates = true;


web.AllProperties[strPropertyKey] =  strPropertyValue;


web.Properties[strPropertyKey] = strPropertyValue;



web.Update();
web.Properties.Update();
web.AllowUnsafeUpdates = false;

Delete Properties


web.AllowUnsafeUpdates = true;


web.Properties.Remove(strPropertyKey);


web.AllProperties[strPropertyKey] =  null;


web.Update();
web.Properties.Update();
web.AllowUnsafeUpdates = false;

Hope this help.

Tuesday, January 3, 2012

How to delete a site with all sub-sites

SharePoint does not allow user delete the site which has many sub-sites existed. That means if there are many sub-sites are still working, and user try to delete the parent site, the error will throw exception. Here is the piece code to help delete the parent site with long operation.



private void DeleteAllWebs()
        {
            SPLongOperation.Begin(delegate(SPLongOperation longOperation)
            {
                try
                {

                    int lCID = base.Web.Locale.LCID;
                    uint language = base.Web.Language;
                    int uIVersion = base.Web.UIVersion;

                    string layouts = Utilities.DetermineLayoutsUrl(base.Web.ParentWeb, this.Context, false, false);

                    this.DeleteWeb(base.Web);

                    string queryString = string.Concat(new string[]
   {
   "c=",
   lCID.ToString(CultureInfo.InvariantCulture),
   "&ui=",
   language.ToString(CultureInfo.InvariantCulture),
   "&uiv=",
   uIVersion.ToString(CultureInfo.InvariantCulture)
   });
                    longOperation.End(layouts + "webdeleted.aspx", SPRedirectFlags.UseSource, this.Context, queryString);


                }
                catch (Exception ex)
                {
                    logger.Error("DeleteCommunity", ex);
                    throw ex;
                }
            }
            );
        }

        protected void DeleteWeb(SPWeb web)
        {
            if (web.Webs.Count > 0)
            {
                foreach (SPWeb subweb in web.Webs)
                {
                    try
                    {
                        DeleteWeb(subweb);
                    }
                    finally
                    {
                        if (subweb != null)
                            subweb.Dispose();
                    }
                }
            }
            if (web.Exists)
                web.Delete();
        }


Hope this help!

Tuesday, December 20, 2011

Synchronous between 2 site collections to make a backup data

There was many ways to create a backup for your site collection from content-database. For the others purpose, you will find out the best solutions for you situation, and in this sort topic, I will show you how to create a backup content of site collection in disaster case or crashing data.

Content Deployment Path is a part of tool using in SharePoint Server 2010 to sync data from source site collection to destination collection. Source and destination site don't need to be in the same farm server, they may work on other farm but between 2 farms must have a connection. That means you have to have an account can access to destination site collection.

There are a lot of jobs created and sometime it make your system to be slow down or not responding, however it actually only happens for the very first time running.



One more thing need to be warned, that is, if you are performing on crossing server farm, you should take a time to manage security between the farms because SharePoint requires transfering data by secure socket network, if so, you must go to the Central Administration to reconfig Content Deployment Settings to do:
- Enable listening between the sever farms by setting Accept incoming content deployment jobs
- Select Do not require encryption option if you didn't work on SSL administration

After create an Content Deployment Path, you will see the item in the list, and create a job to perform action.



Conclusion: you can monitor the deployment jobs in Central Administration section, and manage all jobs in the setting page. Note: please don't set the schedule too short to avoid the conflict data between 2 jobs in the same path.

Friday, December 16, 2011

Series solutions on document management for officer - Part 3

At the previous posted, I recommended 2 solutions for officer employees. SharePoint 2010 OOTB has not supported enough components to work on documents especially about document management and collaboration. Security is also an important thing and could not separate from content management actions. If there are many actions on the same document at the same time, it would be conflicted when user perform saving execution. Collaboration is the best solutions to solve this problem and for now Microsoft had released a lot of components for collaboration such as Office Web, SharePoint Online (Office 365),... However, another scenarios often has been used frequently in office that is to share some documents (items) in the same department or another departments.



This topic will reduce (save ) your time when you work on document/content management. I produce this component to help you share (items) your documents, it allows:
- Share item(s) to one or many people with specific permission, the permission list is taken from SharePoint permission level.
- Privately item(s) from another users, except for System Account and Site Collection Admin.
- Inherit from parent.

Limitation for free this component:
- Cannot share item(s) for many people with many permissions. For example, if you need to add some people /groups with FullControl and Contributor for this item.
- Cannot get the permission editing for item which are the same permission items.
- Only support SharePoint 2010

Download here

Tuesday, November 29, 2011

Series solutions on document management for officer - Part 2

In the previous post, I just reserved a piece of package of document management for officer. In the daily tasks, I think it's very useful if there is any robot functioning to perform our tasks. It's like a command in SQL and executes many times, sometime it makes us feel uncomfortable or tired with a boring jobs. That's why I think it's really useful for office, especially some people work in Acc Dept and HR Dept.

In this topic, I introduce a new feature in a series of small tool for officer. That's download a multiple files from document library or picture library.

SharePoint OOTB has supported already a feature named Download a copy in Copies category of Ribbon. However, to get a copy of file, user can perform by right-click on the file name and select Save file as from context menu of Internet Explorer. Of course with SharePoint, user has a lot of methods to download a copy of file, but the question is how to get many files and folder into a package? There is only way to do that is to go through every item and download, then using compressed function has supported by windows to zip all in one.



There are some limitation of free version:
- Not supported compressing all sub-folders.
- Not supported other zip type, just using "zip".

There are features of this tool:
- Allow compressing files and folders in the same level.
- Supported for SharePoint Foundation and Office Server.

It's available to download here.
(... to be continued )