Today I was speaking on Finland Sharepoint UG (http://spug.fi/) meeting about using WatiN for avoiding limitations of sandbox solutions and client object model in Sharepoint. It was first virtual event which I participated in Finland SP UG and it went very well. Thanks to all attendees and other speakers (famous guys, Gunnar Peipman and Spencer Harbar) for interesting talks and this meeting. And special thanks for Jussi Roine for organizing the event. Update: presentation from my speak is available on Slideshare: Using WatiN in Sharepoint.
Wednesday, October 29, 2014
Tuesday, October 21, 2014
If you tried to localize fields, content types or web part titles for Sharepoint Online you already know that it is not trivial process. The main problem is that we can’t deploy farm solutions to Sharepoint Online which may install files on file system. As result we can’t put custom resx files to 15/Resources folder and use them in declaration of our artifacts with special syntax “$Resources:filename,key”.
However it is still possible to localize some frequently used strings like Documents, Meetings, Events, Calendar and others with minimal efforts. Just search for the needed string across OTB Sharepoint resx files which are installed to 15/Resources folder with basic Sharepoint or language pack installation. If you will find such string you still will be able to use it in your artifacts in regular way. For example, localized Documents string may look like this “$Resources:cmscore,ListNameDocuments” because cmscore.resx and its language-specific versions contains translations of Documents string.
Of course with this approach you are limited with strings which present in OTB Sharepoint resource files, but it is better than nothing. In order to be able to use custom resource files for localizing fields and content types in Sharepoint Online much more complicated technique should be used. I will write about one of these technique in one of the future posts.
Saturday, October 18, 2014
In one of my previous posts (see Reactivate Web-scoped features from PowerShell using client object model in Sharepoint Online) I wrote about problem which you will face with when will update sandbox solution: all web-scoped features on existing sites will be deactivated, so you will need to activate them back after wsp update. In this post I will write about one more issue related with update of sandbox solutions: after update binding of all managed metadata fields with appropriate term sets become broken. I.e. fields became greyed out and you can’t select any value for them using managed metadata picker.
In another post Provision managed metadata term sets and fields for Sharepoint Online using client object model I showed how to provision managed metadata fields and term sets and bind them with each other via client object model. And I wrote that it is important to assign IDs explicitly to the term sets because they will be used for binding. These ids will also help for fixing fields’ bindings after wsp update.
The main idea is that after each wsp update you need to call function Bind-Managed-Metadata-Field which was showed in the previous article again:
This example uses the same xml file structure as in previous article. After that your managed metadata fields will work again after update of sandbox solution.
Monday, October 13, 2014
I have a good news for Sharepoint developers which use Camlex library in their projects: today Camlex 4.0 and Camlex.Client 2.0 with support of list joins and field projections were released. Let’s check msdn example List Joins and Projections and see how it will look like with Camlex syntax. Suppose that we have 4 lists:
with the following left joins:
- Orders to Members
- Members to Cities
- Cities to States
In order to create CAML query with list joins we need to specify value for SPQuery.Joins and SPQuery.ProjectedFields properties. Suppose that we need to create the query for all orders made by customers from London, UK. Here is how it is done using Camlex syntax:
Here we have 4 Camlex calls for Query, Joins, ProjectedField and ViewFields properties. Let’s see what CAML is generated for each property:
As you can see joins syntax is quite straightforward:
First syntax (without specifying primary list) is used when primary list if the same list against which query is made, second – when it is different list. For projected fields syntax is also self descriptive:
i.e. you need to specify values for attributes of the resulting Field element.
For joins and projected fields only fluent interfaces were used for supporting multiple elements (.Join().Join()… or .Field().Field()…), i.e. there are no appropriate methods which receive collection of parameters which can be passed in order to get multiple Join or Field elements in resulting CAML. Such methods simplify dynamic creation of the parameters in runtime when their amount is not known in compile time. This approach is used in Camlex for Where and ViewFields, but I hardly may imagine scenarios when dynamic creation of join chains will be needed. If someone will need it, I will think about adding it to the library, but meanwhile only fluent interfaces for joins and projected fields will be used.
Reverse version of new features (which allows to make conversion in opposite direction from CAML to C#) is not implemented yet. It will take some time to implement it and I decided to release it later. Practically it means that e.g. if you will try to convert Joins or ProjectedFields from CAML to C# Camlex syntax on online service http://camlex-online.org (this service was launched in order to simplify Sharepoint developers which are not familiar with Camlex starting using it), it won’t work currently. But I’m going to implement it in next release so it will work after that.
Wednesday, October 8, 2014
Sometimes we need to delete big amount of records from the table in SQL Server database. If number of records is quite big (several millions) the simple delete command will hang:
In this case we can use the following approach: delete records by chunks (e.g. 100000 items per operation, but it depends on how many columns your table has. It if has a lot of columns and data, you may adjust this number for your scenario) until all records will be deleted. For example imagine that we have table [Log] used for logging some operations:
And suppose that this table grows quite fast and we need periodically delete old log records from it (e.g. older than 2 weeks). It can be done by creating job in SQL Server agent. For this job create the step which will run the following code:
This script will delete records from the Log table by chunks in 100000 rows until all records which are older than 2 weeks won’t be deleted and won’t hang because of big amount of data.
Saturday, October 4, 2014
We all know how to add custom web parts on the publishing page declaratively in farm solution. In order to do it first of all we need to create module and provision page itself. In the <File> element for the page we may add web parts (OTB or custom) using <AllUsersWebPart> element:
However the same approach won’t work in sandbox solutions because in this case assembly is not installed to the GAC and instead of web part you will see error message that type of your web part is not found. In order to provision custom web parts declaratively from sandbox solution we need to add <Solution SolutionId=”…” xmlns=xmlns="http://schemas.microsoft.com/sharepoint/" > under <metaData> element. SolutionId attribute should have id of your sandbox solution which you may find in Visual Studio with opened solution, then Package > Package.package > Manifest > copy SolutionId from here. Here is how module should look like in order to work with sandbox solution:
After that your web part will be shown on the page.