Archive

Archive for the ‘SharePoint 2010’ Category

Importing PowerShell Modules from GAC DLLS in order to use their CmdLets

What I am writing here is nothing new, just a consolidation of attempted answers I found when trying to do as the title of this post describes.  Now to set the stage, this is a DLL deployed as part of a SharePoint solution which is why it gets dropped to the GAC and then the CmdLets are used to configure the solution once the SharePoint WSPs are deployed.

Import-Module will take a full path to a DLL in the GAC or anywhere in order to use the CmdLets within it, but I didn’t want to be mucking with resolving the GAC path for a DLL, I just wanted to give it the assembly name without version and what not.  In looking at other people comments to loading DLLs with partial name, the obvious “LoadWithPartialName” was mentioned, however that will load the DLL into memory, but doesn’t load them as modules for CmdLet use…

Chaining the two commands together does work nicely though:

$assembly = [System.Reflection.Assembly]::LoadWithPartialName(‘MyProject.PowerShell’)

Import-Module -Assembly $assembly

New-ObjectToPerformTask -Url $url

It’s nothing special, but a nice complete way to load PowerShell cmdlets using partial names from the GAC, so its great for SharePoint deployed DLLs.

 

Advertisements

SharePoint… smart enough to adapt but too dumb to tell you

We came across something recently that is sort of interesting and extremely annoying.

So it seems that when adding a new sub folder to a SharePoint Document library (either through the UI or code), if the folder name ends in “_file”, “_files”, “.file”, or “.files” then SharePoint will automatically tack on an “_” (underscore) to the end of the folder name.  I guess internally they use those patterns in names for something, just like prefixing a folder name with “_” is supposed to hide it so it seems.  Anyway, so they tack on the underscore to prevent it matching the controlled pattern they use… that’s the interesting bit, but its been that way for a long time.

Normally a user might not even notice or care when looking in the UI since it might blend in, but we have a very clever data deployment system, that will create folders on the fly to match the XML data structure we give it for publishing documents and such.  This works great as we get the root SPFolder and drill down the folder path creating sub folders as we go.  The code then returns the folder path as it created it to give us a nice normalized string, and finally we add a document with that final folder path.  In the code, to be on the safe side, we rebuild the folder path to adapt to any changes SharePoint might have made when calling spFolder.SubFolders.Add(folderName).  We simply take the Names of the newly created SPFolder objects and join them together as we create the path… seemed like a sound plan.

This is where it SharePoint screwed us up recently, when testing some customer document loading.  If a name like “TEST_file” is passed in SharePoint will create the folder, appending the additional “_”, but will then return a new SPFolder object with the original name we asked for, and not the new name it actually created it with.  So basically it did one thing, then told us it did another.  The path was created, but we never new of the change and when uploading the document with a URL based on what SharePoint told us it did, the adding of the document failed, complaining the path didn’t exist.

Just a nice example of even when you try to adapt to what an external component (SharePoint in this case) might do, you still can’t trust it, cause it can in essence “lie” :).  This is why testing with real world data is so important, because even if you write a few lines of code, the things you depend on might have millions of lines and as hard as people try, things can be missed, mistakes made, and you might just be the first person out of thousands of other developers to notice because of one little word in all that data.

SharePoint and Extension methods… super cool

I must admit that Extension methods in C# has got to be one of the coolest ideas ever for the language, for one huge reason.  They allow intelli-sense to automatically expose the methods as if they were part of the original class.  This opened up a huge opportunity for simplifying complex tasks into easily reusable bite that were automatically available once the containing assembly was referenced.  Now granted, this isn’t much different from writing custom library of methods to wrap all the heavy lifting, but extension methods put them right in front of you without needing to look them up, and that means people can’t help but use them… that’s cool.  This mean a more natural reuse of existing code, and that means more code usage which should help testing and code coverage.

Now, along comes SharePoint, a prime example of something hideously beautiful… even with all the new things added over the years its still at its heart a big customizable list manager, which lets you granularly control and render the types and views of the data in each list.  Unfortunately, like anything technology based… the simpler it is for the end user, the more complex it is for the engineers.  It’s like a self parking car… a $1 button on your dashboard probably equates to a life time of engineering and billions in R&D if you trace the evolution of all the tech involved.

SharePoint offers lots of control through a very extensive server side object model (there are also client side object models but that’s not the focus here), and everything is linked together in a nice parent child relationship of objects.  This is great for understanding the inner workings of everything, but day to day, and especially for code maintenance and robustness, its a bit of a pain.  Two of the biggest pain points were security changes (not uncommon to be a pain), and setting the data of a specific list item field (its simple to do, but just as simple in what it does).

Starting with the security activities; these were one of the most obvious to implement as an extension method since there are multiple securable objects in SharePoint.  With a couple overloads tagged as extensions, I took the logic of adding for example down from finding the user by login name, checking if an role association already existed, and if not, finding the role definitions and then the particular role definition by name, creating a role association and then adding it and updating the securable, and turned it into a single call on and SPWebs and SPLists that takes a login name and role names as strings.  This mean that even both long time and recently hired developers writing code to manipulate the security in SharePoint simply had to call spWeb.AddMemberWithRole(“someuser”, “somerole”)… it just showed up for everyone to use; far easier.  Because it was so easy to use without looking for the methods, people weren’t rewriting new version, we just used what appeared as method of SPWeb and SPList objects.  This included demo data imports and data migrations, which meant the same block of code was easily reused and easily tested everywhere under tons of edge cases.

So I realize that by passing in two strings, means that we are not able to reuse references to underlying objects that we have already found when previously calling this method, and this is true, but given that where we used these, adding one user at a time in a stateless web environment, we usually started with string data for each request anyway.  We also could string together the logic of the larger extension method into smaller extension methods on each object, with things like FindOrCreateRoleAssociation, and such, covering all our needs but so far the need hasn’t come up and its been over three years.

Now, for the most powerful extension method in the arsenal, setting the field values on items.  This extension method is probably the most used and there is a reason for it.  Out of the box, SharePoint provides a simple indexed method for setting a field value in a list item, and it works ‘fine’ for most field types… the problem is that as simple as it is, it behaves just as simple.  It doesn’t do any thinking for us, which means you need to tell it exactly what to do.  It works fine for string and number typed fields, but once you start to deal with lookups and taxonomy fields, it requires a lot of help.  I am not going to go into specifics due to confidentiality, but essentially, this easy to access extension method provides two things that SharePoint doesn’t.

First, we would pass in an object type and try to figure out how it fits based on the field type we are setting.  For example, if you enter a “123;#Hello World” for a lookup field, or a SPFieldUserValue for a user field, we would let SharePoint handle it, but if you just entered “Hello World” it could use the information available with that Field type to figure out exactly what SharePoint needs for a fully qualified value.  By providing support for Lookups, Users, DateTime (with safe range checking), and Taxonomy fields (even supporting navigating term store paths), we were able to use this method for copying data in all our event receivers, custom input screens, and all of our data migration/importing (which means that we can provide highly adaptive importing reducing migration efforts).  This means that the same consistent data type handling use used everywhere, and after a lot of edge case handling, is far smarter and adaptive than SharePoint out of the box.

The second thing it does that SharePoint doesn’t do, is provide feedback about whether it actually preformed a change.  The method, tells us if it actually made a change, so that we can track our ‘sets’ and then only perform a SPItem.Update if we actually made a change.  Why is this important? Well, even though SharePoint has the raw data, it doesn’t detect if changes actually occurred, and that means that event receivers will always fire even if no changes occurred and AfterProperties are always set for any fields touched.  By tracking field changes ourselves and only saving when required, we are able to reduce the execution of event receivers to a minimum improving performance on saves.

As usual, none of these methods themselves are special, but the use of them as extension methods with a descriptive method name means that anyone working on the code can and will use it, improving custom code reuse, and reducing the number of replicated methods and helping new developer training.  Some of the hundreds of extension methods we use, like those couple mentioned becomes so natural to call that when working on something new performing doing basic SharePoint tasks you start typing the method names out of habit, forgetting that they aren’t yet there out of the box.

Issues with .Net Assembly Binding Redirection between .Net 2.0, 3.0 and 3.5 to .Net 4.0 and 4.5 (relating to SharePoint 2010 and 2013)

After about three hours of uncertainty as to why it didn’t work… a last ditch test and a 3am eureka moment converged to the following:

So a bit of backstory… the company I am working for, without going into the sensitive details, was writing a console app that we wanted to work against both SharePoint 2010 and SharePoint 2013.  Well there’s lots of hacky was to do that, including two different code brancehs which then need to be kept in sync or one code branch but doubling up project files and solutions in the folders, one pointing to SP2010 and one at SP2013… We use TFS build services and so any option would work, but most a management nightmares… so on being asked I suggested we use the assembly binding redirection (just like SharePoint itself does for loading webparts from older versions), as it’s the easiest to maintain.

So we tried… and after a good number of hours by another dev, and then by myself also for three hours, so couldn’t figure out why it didn’t work.  It would compile fine, and using the FUSLOGVW.EXE we were able to see the redirect was occuring, but then it wasn’t able to find the SharePoint 2013 assemblies (version 15).  All we had was a cryptic message at the end of the fusion log about “GAC Lookup was unsuccessful”.

So we ended the day with a big WTF?!?!

Well, so about 2 mins after I logged off, I decided to try one more thing and got a build working by changing the target framework to be .Net 4.5… a step forward.  Although this helped for SharePoint 2013 all of a sudden, it stopped working for SharePoint 2010, again complaining about not being able to find SharePoint.  Odd… but it’s something.

Then at 3am in the morning, the EUREKA moment happened… I figured out ‘why’, and then the details to make it all come together. The problem is that .Net 4.0 and above is a different GAC location now (it’s now in the place it should have always been).  If the project is a .Net Framework 3.5 project then it’s looking in the wrong GAC for the SP2013 assemblies (since they are .Net 4.5).  This was the whole reason it didn’t work from the beginning; when compiled to the right target framework, you don’t even need your own the binding redirection entries since SharePoint actually includes the minimum ones as policies in the .Net 4.5 GAC.  Having made the project a .Net 4.5 project it would have worked fine on SP2013 without any config settings as it would have looked in the correct GAC.

There is a catch though that would seem to be SharePoint specific.  SharePoint 2010 actually checks to ensure the app is targetting the ‘supported’ .Net 3.5 framework.  What this means is that to run against SP 2010 the EXE needs to target a .Net v3.5, while to run against SP 2013 it needs to target .Net v4.5 (or v4.0, but v4.5 is better).  The project can reference the SP2010 assemblies and, if targeting to the correct framework, will automatically adapt for the basic Microsoft.SharePoint assembly (there is a ‘but’ here that didn’t affect our specific situation right now).

So the next question is, how do we have one project target two different framework versions… answer, we don’t.  Luckily for us, MSBuild allows us to pass in overriding values for many things, one of which being the TargetFrameworkVersion (and in support of that, the ToolsVersion if needed).  And so we can instead make two build definitions in TFS (or simply two MSBuild commands if you are using some other automated build tool), one that does the default (or we could explicitly target .Net 3.5) and the other that passes additional arguments to MSBuild to explicitly target .Net 4.5. (it might be possible that we could also do one build definition with two outputs, one for each framework also). Now when the builds are kicked off, the exact same code, project file, and solution is used, but the MSBuild overrides the version and gives us one for SP 2010 and one for SP 2013.

Here are the details of the changes to make.  Open the original solution and ensure that it’s targeting .Net 3.5, and that the SharePoint reference is pointing to the SP 2010 (v14) DLL. Create one build defintion to do the defaults, and then a second build definition and add additional MSBuild arguments (in TFS you can also add them per queued build if you wanted to test this first) of:

/tv:4.0 /p:TargetFrameworkVersion=v4.5

* Note, both build defintions would point to the same SharePoint 2010 build server, for the compile to work, and you will also need to ensure that the .net 4.5 is installed to the SharePoint 2010 build server also (this doesn’t affect SharePoint, but is required to pick the 4.5 target when compiling).

Now, when you kick off each build it should create one as a SP 2010 compatible EXE and one as a SP 2013 compatible EXE (if we wanted we could use more arguments to alter the EXE output name to make them distinct also, such as “MyToolForSharePoint2010.exe” and “MyToolForSharePoint2013.exe”).

One code base… one thing to maintain, driven by configuration.

 

Some useful references:

http://msdn.microsoft.com/en-us/library/bb383985(v=vs.90).aspx

http://stackoverflow.com/questions/12003475/override-target-framework-from-command-line

Packaging and Deployment – ‘missing types’ compiler errors using Visual Studio 2012 and SharePoint 2010 tools

For a while now, the team and I have been dealing with a odd behavior in Visual Studio 2012 and SharePoint 2010, disruptive to the point that I actually scripted out the whole build and packaging process from the command line just to package up our WSPs (SharePoint packages).  Basically it happened like this… we has a solution with a combination of Class Library projects and SharePoint projects, and were able to compile the projects individually or as a solution in Visual Studio, but when trying to package or deploy them to SharePoint via Visual Studio we would receive a variety of errors about missing types.  These missing types were all part of the class projects that were referenced by the SharePoint projects, providing a variety of utility classes and such, which all compiled fine when simply doing a build, but were reported as missing when we attempted to create SharePoint packages.

Well with no useful information from Visual Studio, the issue just sat on the side lines until either time or frustration found me.  The fact that we could compile from the command line using MSBUILD only added to the confusion, but gave us an opportunity to ignore the issue as long as possible.  But alas, all good things must come to an end, and I found myself in a situation where I needed to actually deploy from within Visual Studio, and so I looked again at the issue.

Well with a bit of speculation, and some criticism of the SharePoint tools for Visual Studio, here’s what seemed to be going on.  The SharePoint project templates and tools are designed for moving forward, and are not friendly to changes or reworking.  This is obvious in the management of features and packages, with the unfriendly two column UI for adding and removing items.  An important thing in SharePoint packages is sequence, however only one of the many item list in the SharePoint tool UIs provides buttons for reordering and unfortunately this is not the one.  In the case of this issue, it appears to be the package additional assemblies.  As time went by and code was refactored and moved to enhance reuse and organization, more project assemblies were added to the various packages.  However, the sequence of the assemblies isn’t easy to manipulate and can intermittently cause issues packaging issues when code a lower level project is changed, as the project additional assemblies appear to be recompiled during packaging either in a weird order or with weird references.

Without spending an inordinate amount of time looking into exactly why, what seemed to help mitigate the issue, was to open the package files in notepad and reorder the additional assemblies such that they would be added in the same order that they would naturally be compiled.  This seemed to clear up the issue, allowing to the SharePoint package projects to be published and deployed again.

So the lesson here would seem to be, make sure you monitor and reorder your package additional assemblies…

Feature contents is another one to watch for order, but that’s a different story.

SharePoint – An unexpected error has occurred or Object Reference Error in a site collection after reattaching a Content Database

2013/02/16 2 comments

After removing a content database from a SharePoint 2010 web application, so that I can restore a backup (for development purposes), upon reattaching the content database I was being plagued with an assortment of error message.

These included when trying to load the site, seeing both an “An unexpected error has occurred” and a simple server information block returned, and upon checking the logs seeing:

“System.NullReferenceException: Object reference not set to an instance of an object.    at Microsoft.SharePoint.SPSite.PreinitializeServer(SPRequest request)”

This would occur on a single web front end server in the development farm (yep, I have multiple WFEs in my development environment), while the other WFEs would load fine.

After a couple different investigations, I found out that one cause of single server site corruption after reattaching a SP content db is… it’s the PowerShell SharePoint CmdLets.

If you are running PowerShell and are using the SharePoint CmdLets (SPSite for example) to connect to that site (for the content database in question), if you try to reattach the content database while that PowerShell session is still open, the reattach goes fine, but the servers where PowerShell was open will fail load the site thereafter… even after reboots and all.

You need to close the PowerShell window and then reattach the content database (either by the Central Admin UI or from a new PowerShell window if you are using scripts).

Additionally, the W3SVC and SPADMIN and SPTIMER services can all cause the same problem, so I have found that restarting those also (I bundled it up into a single PowerShell cmdlet) ensures that I never saw this issue again.