If your assembly reference to $SharePoint.Project.AssemblyFullName$, for example in your master page, is not resolved when building the package, you have to edit the project file. Under the correct property group make sure the following line is in:

<TokenReplacementFileExtensions>master</TokenReplacementFileExtensions>

Reload the project, rebuild the solution and create the package.

Since SharePoint 2010, they introduced the modal dialog. This fancy screen is noticed by many and people start thinking in terms of it. So I got a request to make a new site provisioning system where the user gets a link under site actions which opens in a modal dialog. After some google requests I came up on two sites which could help me. First of all Chankaradeep Chandran posted something about ‘Using the SharePoint 2010 Modal Dialog’. Still I got a problem, how to get those files on SharePoint. So I ended up with the second post from a good friend, Jan Tielens. He posted in March an article about ‘Referencing Javascript files with SharePoint 2010 Custom Actions using ScriptSrc’.

I combined the knowledge and insights of both posts into a solution for my problem. First of all you have to start a Project scoped as Farm Solution since we have to publish files into the Layouts folder. This javascript file can be added into the Layouts Mapped Folder very easy.

   1: function google_OpenModalDialog() {

   2:     var options = SP.UI.$create_DialogOptions();

   3:     options.width = 500;

   4:     options.height = 250;

   5:     options.url = "http://www.google.com/";

   6:     SP.UI.ModalDialog.showModalDialog(options);

   7: }

To publish the file in SharePoint, so you can reference methods of it you have to add a CustomAction.

   1: <CustomAction Location="ScriptLink" Sequence="1000"

   2:               ScriptSrc="PlayingWithSiteActions/OpenModalDialog.js">

   3: </CustomAction>

Finally you can add another CustomAction to display a link under Site Actions a reference the javascript method when clicked on it.

   1: <CustomAction Id="SiteActionsToolbar" GroupId="SiteActions" Location="Microsoft.SharePoint.StandardMenu"

   2:               Sequence="1001" Title="Open Google">

   3:     <UrlAction Url="javascript:google_OpenModalDialog();" />

   4: </CustomAction>

Thanks to Jan and Chankaradeep for their part in my research.

Today we got a new solution from a third party, which we installed on our development environment with the help of the supplier. Everything worked fine, but when we installed it on our test environment, it kept complaining that a resource object was not found (“The resource object with key ‘X’ was not found.”). We ran the stsadm -o copyappbincontent but it was still an error. We checked the resource directory in the 12-hive and the virtual directories in the inetpub folder and everything was present. Eventually we deleted the resource files inside the virtual directories and ran the copyappbincontent command again and yes, it worked. Strange problem, but since this solution was not found on the internet by me, I thought let’s share it.

I often get the requirement from the business to draw borders around all webparts, change the background color of specific webparts or even other styling issues. After the first prototype, they often change their mind and tell you which zones (best case) or even which webparts (worst case) they want styled and which not. At first it looks like a challenging problem, but with todays cascading stylesheets you can do a lot. Let me demonstrate this with some examples.

(more…)

I lost several hours on a problem that what solved by something very simple but unexplainable from my side. I had to create a new MasterPage for our MySites. On the root site collection of the MySites WebApplication we published some custom application pages to extend the standard functionality. These pages used the session state (HTTPContext.Current.Session) to store their model. Everything worked fine with the old MasterPage, but as soon as I selected the new one, the Edit Profile page started complaining that the SessionState was empty. I checked lots of things, even copied the old MasterPage sourcecode into the new MasterPage which didn’t worked neither. After lots of google links, a lot of frustration, even opening IIS, web.config files, trust configs, etc I found the solution on an other blog (lucky for me I’m not alone). Because it took me quite some links to read, I repost the solution here.

- If you get a HttpContext.Current.Session is nothing or HttpContext.Current.Session is null.
- If a page gives you “Session state can only be used when enableSessionState is set to true, either in a configuration file or in the Page directive” and you’re absolutely sure you did this and other things Microsoft recommends to use Session State in SharePoint.
- If you have enabled Session State through SharePoint Central Administration.
- When you try to set the EnableSessionState attribute on the Page directive of your Application Page and the following error comes back: “The enablesessionstate attribute on the page directive is not allowed in this page.”.

Then just use the ‘Reset to site definition‘ in your Site Settings of your Site Collection. Simple isn’t? What is it doing, well send an email to Microsoft, because I can’t tell you, but it fixed the problem for me.

In ‘Mimicking the Workspace column of an Event Item (Part 1)‘, I noted that it would not work if you use the custom field type from the UI. After some research, it seemed that SP2 for SharePoint 2007 created this problem. If you install the hotfix from August 2009 or even October 2009, the problem is solved.

Correction previous post: The override of the FieldRenderingControl can be skipped as well. The standard rendering of a SPFieldUrl is sufficient.

(more…)

Took me a while to figure this out, so I thought this might be useful for others too. I had to select all items where a certain text was not in the id of the tag. Very simple to select the opposite (those which contain the text in the id) with the following statement.

$(“.item[id*='sometext']“);

First of all, jQuery doesn’t has an Attribute filter in the selectors to select the opposite. They do have an inverse for the attribute filter ‘attr=value’, but this won’t work for ‘attr*=value’. So you have to work with the :not basic filter. The documentation and examples there say :not(selector), so you would think that the following would work.

$(“:not(.item[id*='sometext'])”);

But I won’t, it just selects about anything. The only correct way is to move the :not just before the attribute filter like this.

$(“.item:not([id*='sometext'])”);

Seems simple once you know :)

We got a request for a project to mimic the Workspace column of an Event Item, in that sense that they also wanted an icon in the header and an icon for the link value instead of the text. The site column, ‘Workspace’, and site content type, ‘Event’, are hidden in SharePoint. Besides that, the ‘Workspace’ column is of the ‘Cross Project Link’ field type, which isn’t available. This field type cannot be used via the user interface. Since we got two additional requirements, open link in new window and display description besides icon, we opted to inherit from the parent type ‘URL’. Via the user interface, this is the ‘Hyperlink or Picture’ type. For maximum reuse, we build a new field type with some custom properties and header and display pattern.

(more…)

I think every developer experiences a moment in his career that he is pretty sure his code is correct, but it isn’t. There is a problem without any doubt, but although he looks a thousand times at his code, he can’t find it. Eventually he starts to doubt himself and after a lot of sweat, coffees, no-sleep, grrrrs, help-me-please, he suddenly yells very loud. Everyone is looking and wondering which pills he forgot to take this morning and the only thing you have is a very big smile on your face and red cheeks. And yes, you can guess it probably, I experienced that this week!

The case (ripped to the bottom) was very simple. I had to create a new Site Collection, add a group to this new Site Collection and update some properties of this new group. Simple isn’t it? Let me paste the code I wrote for this and probably everyone sees the problem immediately. Only thing I have as input was an url to a Site Collection, an url, a title and an owner for the new Site Collection and a name for the new Group.

Dim site As SPSite = New SPSite(siteUrl)
Dim webApp As SPWebApplication = site.WebApplication

Dim newSite As SPSite = webApp.Sites.Add(newSiteUrl, newSiteTitle, Nothing, 1033, newSiteOwner, Nothing, Nothing)
Dim newWeb As SPWeb = newSite.RootWeb()

newWeb.SiteGroups.Add(newGroupName, site.Owner, Nothing, Nothing)
Dim newGroup As SPGroup = newWeb.SiteGroups(newGroupName)

You see it? Let’s hope you don’t, otherwise I feel really stupid :) On the last line, you get a nice exception, Group cannot be found. Unless, and here is the fun part, your site.Owner is the same account as who is running your Web Application (in other words the account running the Application Pool for your Web Site in IIS).

So you have a workaround and a real problem to tackle. If you know what, it is simple. Don’t use SPUser objects from other Site Collections to do things! You see the problem now? For those who don’t, replace site.Owner (an SPUser object from another Site Collection) with newSite.Owner and everything is solved. Stupid I looked over this and didn’t realised this could be a potential problem, but lesson learned as they say.

Recently we build some custom display and edit forms for a list, but need to secure the view and edit rights for the listitems. We didn’t wanted to use listitem permissions, because the list contained People or Group columns, where we could derive the permissions from. It wouldn’t be user friendly if they had to define the People or Group fields and set listitem permissions. Sooner or later, this would run out of sync and end users would be confused.

So, after some research on the internet and the MSDN library, I found out that a SPFieldUserValueCollection contains an Exists method, to which you have to pass a delegate to a method. This delegate method will accept a Predicate(Of T) on a List(T). So in our case the delegate method had to accept a SPFieldUserValue. In return it will give a boolean value defining if the user is contained in the People or Group field.

A People or Group field can contain SharePoint Groups, Domain Users, Domain Groups and/or Distribution Groups. Below you can find an implementation for the first three types of values. The method can be used for a single value and multiple value People or Group Field. As soon as it returns true, it will skip checking other values in the multiple value form. You can replace the web object with SPContext.Current.Web offcourse and keep in mind that you have to implement the DomainGroupContainsCurrentUser method. Implementations of this using LDAP can be found at the internet.

Private Function CurrentUser(ByVal fuv As SPFieldUserValue) As Boolean
     If fuv.User IsNot Nothing AndAlso Not fuv.User.IsDomainGroup Then
         Return (fuv.User.ID = web.CurrentUser.ID)
     ElseIf fuv.User IsNot Nothing AndAlso fuv.User.IsDomainGroup Then
         Return DomainGroupContainsCurrentUser(fuv.User.Name)
     ElseIf web.SiteGroups.GetByID(fuv.LookupId).ContainsCurrentUser() Then
         Return True
     Else
         Return False
     End If
End Function

Calling this method is pretty simple. Suppose you have a SPFieldUserValueCollection, fuvc, then you just enter fuvc.Exists(AddressOf CurrentUser) in VB.NET. This approach can be used for every SP…Collection because they all derive from List(T).

Next Page »

Follow

Get every new post delivered to your Inbox.