Saturday, February 25, 2012

You most probably know that with CSS3 it became easy to crate nice-looking rectangle areas (e.g. for buttons) with rounded corners and gradient. However in Sharepoint development we are often limited to enterprise requirements which makes impossible using of CSS3 (hopefully during last several years I didn’t have IE6 compatibility requirements, but IE7 is still often mentioned). In this post I will show how to create stretching rounded corners background for web part titles in Sharepoint 2010. In the end of article I will also show how to use it for Sharepoint 2007.

Without CSS3 we have to use images with rounded corners. For this example I used online http://css-tricks.com/examples/ButtonMaker for generating of the nice-looking button and then made images from screenshot. We will need 2 images of the same height:

left:

and right:

Note that left image should be wider (for this example I trimmed it to fit into blog layout) – it will be used when user stretches browser window horizontally.

Wednesday, February 22, 2012

On one of the projects we used Linq 2 Sql as ORM for our domain model in Sharepoint application. It doesn’t give you 100% persistence ignorance, however from my point of view it is good alternative keeping in mind that in Sharepoint 2010 we are limited with .Net 3.5 and can’t use e.g. Entity Framework starting from 4 version where codefirst approach was introduced. NHibernate is also can’t be applied in some projects with strong enterprise requirements (don’t ask me why, often we just should live with it). I’m going to write separate post(s) about building testable DDD-style infrastructure for projects with help of Linq 2 Sql soon. Here I would like to share one of the problems which we faced during implementation.

We use transactional logic via modified UnitOfWork pattern. With Linq 2 Sql transactions are implemented via generated DataContext class. We make all modifications in DataContext instance and when everything is ready call DataContext.SubmitChanges(). Here problem came out: SQL statements are executed in the following order:

Insert

Update

Delete

regardless of how you called these operations when perform updates in DataContext. It may cause problems if there are e.g. unique key constraints on the table. E.g. imagine that we have 2 entities:

Company

Contact

with one-to-many relation. I.e. each Company may have multiple Contacts:

Contact.Name should be unique, so we add unique key constraint to the table Contact on Name column. Then we need to update some company and its contacts. In order to update contacts the simplest approach is to remove all old contacts and add new one:

1:while (company.Contacts.Count > 0)

2: {

3: company.Contacts.RemoveAt(0);

4: }

5:

6:foreach (var contact in newContacts)

7: {

8: company.Contacts.Add(contact);

9: }

With this approach you don’t need to care about synchronization of each field in each contact. But what will happen when we will call SubmitChanges? As Linq 2 Sql executes inserts before deletes – it will add contacts which of course may be the same as previous if no changes were made in them. As Contact.Name field is unique – we will get violation of unique key constraint exception.

There are some workarounds available, e.g. here: Workaround LINQ to SQL annoying limitations. Author used reflection in order to change operations order, but I can’t be sure that it doesn’t have any side effects so I didn’t use it in production code. Instead we had to implement more complicated mechanism for updates. Instead of deleting all child contacts and inserting new ones we calculated difference between existing contacts set and new contacts set in order to determine which contacts should be deleted and which added. Also we calculated intersection of 2 sets in order to get list of contacts which should be updated. With this approach predefined operations order in Linq 2 Sql won’t cause exception (assuming that Id and unique Name will remain in one-to-one relation, i.e. that we won’t delete existing item and create new one with the same Name. Instead we will update existing item):

Here I used convenient extension method IsNullOrEmpty() for enumerations (see Checking For Empty Enumerations). This is more complicated way, however it allowed to avoid violation of unique key constraint. Hope it will help someone who will encounter with the same issue with Linq 2 Sql in their projects.

Tuesday, February 14, 2012

Some time ago I faced with the problem when tried to call WCF service from Sharepoint timer job: it threw the following exception: “The caller was not authenticated by the service”. When you will investigate this problem, most of solutions which you will find will say that this error is caused by wsHttpBinding with Message level security, and if you don’t need that – you may rather set security mode to “None” or use basicHttpBinding instead. It was not the case for us – because we had service developed by 3rd party company which used wsHttpBinding and we couldn’t change it.

Notice that we called WCF service from Sharepoint timer job. Sharepoint jobs are executed in separate service process (owstimer). Also we needed to call it from Sharepoint site which is running in w3wp process and has own web.config. When service is called from site we can use web.config for configuring WCF client. But how to configure it when service is called from timer job? Of course you can create owstimer.exe.config file and copy WCF configuration there – but in this case configuration will be duplicated in web.config and in owstimer.exe.config. I found the article which shows interesting solution: Calling WCF Web Services from a SharePoint Timer Job. The idea is that we store WCF configuration in one place (in sites’s web.config. Of course you will need to duplicate it if you have several authentication zones, but if you use SPWebConfigModifications for web.config updates it will be done automatically). In timer job we read web.config using classes from System.Configuration and System.ServiceModel assemblies and construct Binding and EndpointAddress instances using read configuration which then passed to the proxy constructor:

1: var binding = (Binding)bindingCollectionElement

2: .BindingType.GetConstructor(new Type[0]).Invoke(newobject[0]);

3: bindingConfig.ApplyConfiguration(binding);

4: var address = new EndpointAddress(endpointElement.Address);

5: var proxy = new MyProxy(binding, address);

I tried to do it like this and got mentioned security exception. As I said all solutions which I found were not applicable for us. After some investigation I found difference between configuration from config and configuration from code: EndpointAddress.Identity property was set to null when it is configured from code.

Saturday, February 4, 2012

On this week new version 3.1 of Camlex.Net was released. In this release we added support of the dynamic ViewFields. This feature was requested in one of the discussions on the codeplex Camlex site. I.e. the following new methods were added to the IQueryEx interface:

I.e. now you can create list of field names or field ids dynamically and pass it into the Camlex. It will create CAML for ViewFields based on this list. For example the following code:

1: var items = new [] { "Title", "FileRef" };

2:

3:string caml = Camlex.Query().ViewFields(items);

will produce the following CAML:

1:<FieldRefName=\"Title\"/>

2:<FieldRefName=\"FileRef\"/>

I would like to share also some interesting (from my point of view :) ) implementation details. You can easily skip the rest of the post if you are not interested in it. Before version 3.1 there were the following methods (they still exist of course):

When add new functionality I wanted to reuse these existing methods in order to avoid creating of extra code. In order to do this the following question should be solved: having array of strings or guids (e.g. { “1”, “2”, “3” }) how to create lambda expression “x => new [] { x[“1”], x[“2”], x[“3”] }”? The solution is quite elegant:

I.e. we iterate through all items in the list and for each item create expression – access to indexer x[item], and add them to the NewArrayInit expression. Note on the ToArray() call – without it lazy LINQ expression won’t be populated and array initialization will fail.

We are very interested in your feedback. Feel free to contact us via Camlex site on the codeplex.

About Me

I've created this blog for sharing my technical experience in software engineering. Most of posts will be dedicated to Sharepoint. But I will write also about another areas of software development for .Net platform. Hope it will be useful and will help you in your work.