Archive
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.
SharePoint 2013 – Manipulating the Term Store from a Feature event receiver
When manipulating the Term Store in SharePoint 2013, such as adding new groups or term sets, you might receive an “System.UnauthorizedAccessException: The current user has insufficient permissions to perform this operation.” error. You can get this error, even if your user account is a Term Store administrator, when trying make those changes within a feature’s event receiver and then activating those features directly, or via an ONet.xml reference, from PowerShell.
It seems that this isn’t really a TermStore application rights issue, but instead is the SharePoint execution privileges stopping things. When you activate the feature from the front end website (site settings) it would work fine as it seems that this page automatically calls RunWithElevatedPrivileges around any feature activation. Activating via PowerShell don’t have this call automatically, and so you might need to add this call directly into your feature event receiver.
After that, activating the feature from the web or from PowerShell will run your Term Store create code elevated and should work fine.
(PowerShell cmdlet’s don’t manifest elevation issues like this)
Using SPListItemCollections indexer to get SPListItem returns different/reset item every time appearing to not save changes
While in a hurry to test some code I discovered that calling the following will not actually save your change:
spListItemCollection[0][“Title”] = “Hello World”;
spListItemCollection[0].Update();
Instead you need to store the SPListItem returned by the first indexer call and then use it to set and update.
var spListItem = spListItemCollection[0];
spListItem[“Title”] = “Hello World”;
spListItem.Update();
This indicates that even though its a property, the indexer is giving you a new or reset instance of the SPListItem everytime you ask for the same index.
Normally I would have refactored this and used a variable from the get go and so I would have never seen this. This just goes to show even the ones that build the framework don’t even follow their own best practices so always assume the worst and store objects in variables first before using them.
The time travellers ego…
I was just watching “Back to the Future 3”, and it was at the part where they were discussing the driving their car into the future on track that didn’t yet exist. The explanation was sound at first, sure the track doesn’t exist now but in 100 years it will so we will appear and glide along…
But the earth is rotating, fast, about 1,674.4 km/h it would seem. So maybe you take that into account and travel to the exact same time of day in the future (or past), which the movie might imply by only having a date on the time circuit’s.
But the earth is also moving, fast, about 108,000 km/h through space, orbiting the sun. This means that the earths position in space tomorrow at this same time of day will 2,592,000 km away from where it is now. So only if the orbit of the earth around the sun is perfectly consistent, the best you could do is travel forward by years, so that you appear on the earth as it passes by at the perfect moment and is at the same point in its daily rotation as to pit you at the right spot on the surface.
But there’s more… Just as the earth orbits the sun in our solar system, our solar system orbits in the Milky Way Galaxy. This galactic year, as it’s called, takes anyway from 200 to 250 million earth years. That’s a pretty big margin of error, and even if you got it perfect, you would only be able to travel forward or back in steps of galactic years. That might explain why so many cartoons show people jumping back into the past and landing face to face with a T-Rex.
Now without doing a bunch of research, I would assume based on the various theories of universal expansion and contraction that our galaxy is also moving, either towards, away from, or around some other central point. So this again would mean that the odds of you moving to another moment in time where the train tracks are in the exact same point in the universe are slim to none.
So either ol’ Doc Brown was not only able to move through time but also calculate and reposition the delorean to another point in the universe based on “approximate” measurements at the high end, all while also ensuring that their forward movement was maintained relative to the surface of the earth as it spun and moved through space as though in a huge gyroscope, or… the earth is the center point for all of space time, and so all changes in time would be relative to the earth as a fixed point in space… Talk about thinking you’re the center of the universe.
All that said, it is a great movie.
XSLTListViewerWebPart with Custom List view
Locate the Views node in the list definition schema.xml file, add a new view entry, giving it a new unique baseviewid (using an already in use baseviewid will inherit the others settings without allowing you to customize anything set it the previous views using that id*); I generally start with 101 and increment from there. Set all the view settings you want, such as sorting, filters, columns, etc, and save it.
In the elements.xml file of the module containing the web part page you want to add the custom view to, add a new view node (or use an existing one) and set the BaseViewID of the view to the ID you used in the schema.xml file.
Now if you want to do this when you don’t have a list definition (schema.xml) to edit it is not supported out of the box completely in SharePoint templates. I will discuss further shortly, as we had a specific set of customizations to make and most solutions where maintenance heavy (hard-coded or implementation specific), where I instead implemented a generic method to reuse for any view.
Here, There, and Anywhere (part 1)
Technology is an amazing thing… throughout the years it has made our lives “better”. I double quote the “better” because it is a very personal thing, where better might mean more free time, more luxury, more information, and in my case better means more open sky.
This year my wife and I decided to turn our plans for the future into our plans for the day. We sold our house in Calgary, a city of over a million people, and headed to the open prairies of Saskatchewan. While in a very small town right now, our final destination will be 6 acres of country side living about 10 minute drive from Yorkton, Saskatchewan. As we meticulously plan out our new acreage home to be built next year, I think about how our ‘retirement dreams’ is a lifestyle we can enjoy in our younger years and provide to our children, all thanks to Technology.
A few years ago I decided to leave the full-time employment world and get back into contracting, seeing how much of that I could do working from home… well it can be a bit too quiet. Although you spend a lot of time with the headphones on while writing software, there is a huge aspect of the work that is collaborative and social. When I started a contract with NeoStream Technologies in Calgary, I was back to working out of an office (planned to be part time, but became full time). Well when it comes to fun places to work, NeoStream certainly ranks at the top, and I say fun in a broad sense of what I consider fun… great people, bleeding edge tech, intriguing challenges, and a very social approach to business.
So with the first contract renewal and the approaching sale of our home, the realization that I would miss the in person interaction that working in an office affords. Enter ‘Microsoft Lync’… the communication system NeoStream had recently incorporated for phone and messaging… add a few web cams, and viola, ‘Virtual Baydon’ was born. Eight hours a day, five days a week, with two way video and voice, I can see and be seen by all the team members as if I was still sitting at my desk. A camera was added to the product room, so conversations during meetings are engaging and interactive, and with desktop sharing of our onscreen planning board, everyone and everything is visible to all.
A few things were still missing, mainly due to the locations of certain events such as the morning huddle (an all staff standup meeting where we hear daily updates and announce our top tasks for the day), and our product sprint meetings. These are in areas not covered by a camera, so recently NeoStream added a large screen TV and camera to the open area for morning huddles, allowing anyone to join in, including people working offsite or from home. We even recently started having people working in other parts of the office join into the ‘Virtual Baydon’ session, so that they could contribute to conversations going on in the bull pen while continuing their work at their own desks.
I will delve into more details next time on both the work and home sides of things, but for now I must say, I didn’t expect working remotely to go so well. Apart from not being able to go for coffee, not much is different… but I am definitely enjoying not having the commute.