Contents tagged with SharePoint
Start SharePoint 2013 development today...
SharePoint 2013 was recently released in beta.
There are plenty of things to start playing with and what can be easier than using a box thats in the cloud, free and ready to go!?
Sign up for a free developer trial of Office 365 here. You can get going with Napa and playing around with SharePoint 2013.
Moved to the Cayman Islands.
Those of you that know me in the physical world will know that I got a job in the Cayman Islands and have been whittering on about it for that last couple months!
Although very excited and looking forward to, what my (Spanish) fiancé would call a “real summer”, I can’t argue, the UK has painfully unpredictable weather! I’m gutted that I’m not going to be in the UK for the Olympics – totally gutted – I almost said no to the job based purely on that!
I’ll be working as a SharePoint Dev for a company called DMS Organization (note the z not s!!) – its going to take some getting used too, spelling everything incorrectly!!
Hopefully its going to be interesting challenge.
I was planning to widen the scope of this blog, to not only .net, SharePoint etc geeky code stuff, but some stuff about the Cayman Islands and the surrounded countries. Travelling is certainly high on our agenda and we plan on seeing as much as possible, using our weekends to the max!
I have never been to the Cayman Islands before and I have never lived outside of the UK before, its all new and at times its difficult to focus the mind and remember that I have to start a new job, be smart and perform for what looks like a pretty dynamic organisation. I’ve had several “first days” and don’t generally get nervous anymore – I know what I can and cant do. I’m most intrigued to see how its done in another country and the Cayman seems interesting…a UK overseas territory, having our bank holidays and some cultural aspects etc, but with what seems heavy influence from the US.
That of course is what I have inferred from speaking to a few different people who live there or have lived there – I must say, I’ve spoken to immigration a couple of times and not overly impressed, “blood from a stone springs” to mind! I’ve also been warned about “Caribbean Time” !!
Immigration is a problem, I have been granted a visa, but my fiancé cannot be a dependant on my visa, only when married can she be a dependant. This is not resolved yet and while of course Luki is going to come out, exactly on what terms has yet to be decided! Personally I think this is very old fashioned and they need to step it up – marriage is not as big-a-part of the world as it once was, we have been living together for several years – if this can be proved, like in many countries, she should be allowed.
Cayman is (apparently) famous for a its scuba diving, boasting such a place as “Stingray City”, I’ve never done scuba diving before, only snorkelling a few times, I certainly plan on doing a PADI course and seeing some of the underwater world. Again those that know me will know I love my bike (bicycle) and will be purchasing one on the island to get involved in what looks like an excellent little community. And I can’t wait to go running along the beach with a quick swim to cool me down every km!
That’s something I’ll have to get used too…Cayman uses the imperial system, crazy. Ohh…and you don’t pay income tax…a nice bonus!
Well, that’s enough about the “plans”, time for a dodgy airline meal, a quick siesta and get on with doing some of them!
A couple pics from my journey!
Train to London – progress.
Boarding!
My view!
Display content from Reusable HTML list in a MasterPage
This is as useful as it is simple!
Having a footer for example in your master page without the overhead of being responsible for its maintenance.
Here is a simple WebControl that you can reference in your master page and supply a key.
Control
Note: You might want to handle the exception better!!
public class DisplayReusableContent : WebControl { public string ContentTitle { get; set; } protected override void Render(System.Web.UI.HtmlTextWriter writer) { try { SPList rcl = SPContext.Current.Site.RootWeb.Lists["Reusable Content"]; SPQuery q = new SPQuery { Query = "<Where><Eq><FieldRef Name='Title' /><Value Type='Text'>" + ContentTitle + "</Value></Eq></Where>" }; var items = rcl.GetItems(q); if (items != null && items.Count > 0) { // Should only be 1! writer.Write(items[0]["ReusableHtml"].ToString()); } } catch (Exception ex) { writer.Write(ex.Message); } } }Register Control
<%@ Register TagPrefix="my" Namespace="$Your-Namespace" Assembly="$Assembl" %>
Use the Control
<my:DisplayReusableContent ContentTitle="Copyright" runat="server" id="ruc1" />
And that’s it – not life changing, but one for the tool-bag!
Unit testing for SharePoint 2010 development
When developing for SharePoint 2010 Unit testing is often overlooked and it shouldn’t be. It’s true that SharePoint is a product and we don’t need to test that, but the code we write to extend is the same as all other code and needs testing.
Being able to test it though does require a little thought (and potentially a change) to way to you structure your code. Getting away from running operations against SharePoint inside “CreateChildControls” for example. You could unit test this method, but personally I think of a web part like a view (or an asp.net code behind file), it’s for presentation logic, not manipulating data or running CAML queries.
The purists amongst you will probably say that this is Integration tests and not Unit tests, and I guess you are correct, I should probably interface out the SharePoint OM etc etc … you are right, but for SharePoint dev, I think this is the best way forward taking time and effort into account – “Is the juice worth the squeeze?” – for me….NO!
I know we don’t need to test the SharePoint OM, but we do need to test our CAML queries – that needs to be ran against a SharePoint implementation, and probably one provisioned with the required lists etc.
Unfortunately getting going with Unit testing in Visual Studio 2010 for SharePoint is not as easy as it should be. The problems are: SharePoint 2010 is .net 3.5 and 64bit.
- MSTest in Visual Studio cannot run tests in 64bit mode.
- Visual Studio unit test framework is .net 4 only.
- My favourite (and I think the best free) testing framework MBUnit doesn’t seem to play well with 64 bit in .net 3.5. The behaviour I see is changing the project type to .net 3.5 simply prompts VS to upgrade the project. I’ve not looked into this a great deal, but would certainly rather it worked!
The solution that seems to be most popular is NUnit. I only use NUnit for this, that’s a choice thing – its just looks dated to me! I like Icarus test runner for MBUnit – a lot!
NUnit doesn’t have great integration with Visual Studio, the few bits I found in the Extension gallery were again, .net 4 only.
I recommend you download TestDriven.net – I’ve blogged about this before – I’m a fan! It makes is super easy to debug and run tests in VS. Add an External Tool link in VS specifically for NUnit – more on that in a bit.
Creating your tests
Once you’ve installed NUnit from here, and TestDriven.net you’re ready to go..
In Visual Studio, create a class library project and add a reference to NUnit.framework (and probably Microsoft.SharePoint).
Make sure the project is targeting the .net 3.5 framework and the platform target is x64.
Consider you have this simple little helper method just to get you the URL of an item
public class Class1 : IDisposable { SPWeb _web; /// <summary> /// Inject SPWeb /// </summary> public Class1(SPWeb web) { _web = web; } /// <summary> /// Simple example of running a CAML query /// </summary> public int GetItemIDByTitle(string itemTitle) { if (String.IsNullOrEmpty(itemTitle)) throw new ArgumentNullException("itemTitle", "cannot be null or empty"); try { SPList configList = _web.Lists["Some List"]; SPQuery query = new SPQuery(); query.Query = "<Where><Eq><FieldRef Name='Title' /><Value Type='Text'>" + itemTitle + "</Value></Eq></Where>"; //Should only be 1! SPListItemCollection items = configList.GetItems(query); if (items.Count > 0) { return items[0].ID; } } catch (Exception) { throw; } return 0; } /// <summary> /// Cleanup /// </summary> public void Dispose() { if (_web != null) { _web.Dispose(); } } }You can see I am injecting an SPWeb into the class through the constructor. The method is running a little bit of CAML.
Not the most useful of code snippet I agree!!
Write this little test…
public class DummyTests { Class1 _provider; SPSite _site; [TestFixtureSetUp] public void Setup() { _site = new SPSite("http://sp2010"); _provider = new Class1(_site.RootWeb); } [TestFixtureTearDown] public void TearDown() { _site.Dispose(); _provider.Dispose(); } [Test] public void Get_Item_URL_By_Title_Test() { string itemTitle = "Some Title"; int expectedId = 1; var item = _provider.GetItemIDByTitle(itemTitle); Assert.AreEqual(expectedId, item); } }As mentioned before you have a couple of options for running the tests (there are more, you could buy ReFactor which has some nice stuff – but I haven’t got and can’t afford that!) I recommend you do both, TestDriven is great for quickly running and debugging a test and the NUnit test runner is great to see all the green ticks when running all your tests! Even if it is an old, ugly interface with more “80’s grey” than anyone should have to deal with!
Once you have TestDriven.net installed, you can simple right click on the test to debug it…
For NUnit, create add a new External Tool entry in VS. Tools –> External Tools…
In the command – be sure to target the 64bit version, actually its just nuit.exe, so I should say be sure NOT to target the x86 version!!
In the arguments text box, use the helper to get the placeholders for BinDir and TargetName, adding the “/run” argument will run the tests automatically when the nuit runner opens.
You’ll then get a new entry on the Tools menu – hit that and your tests should run….
Lovely!
More / Resources:
Call a PowerShell script from SharePoint feature reciever
This is not likely to be something you use on a day to day basis, and I can see how some people might disagree with this method – preferring to use other techniques e.g. SharePoint project types etc in VS.
I just see this as another way to skin the same cat! A very handy tool to have in your box.
I have used this for different things, but provisioning lists and adding some content to those lists a common thing. It’s much easier to use PowerShell to do certain things, deploying a solution every time is just a pain and not overly good use of time waiting for VS to do its thing and recycle app pools left right and centre – so I work with PowerShell on my dev box.
This then comes in when deploying to stage or production (yes, at this point you could create the artefacts perfectly in your VS solution, but time is money people…spending hours working and essentially still be at the same point I am now, just doesn’t interest me in the slightest – I have no interest in writing code just for the sake of writing code, it much achieve something).
However, if my project/solution were to be sold for mass reuse on farms that were totally out of my control – I would not use this method.
You need to add a reference to System.Management.Automation
I created a simple class called PowerShellProxy that has a couple of helper methods, but this being the important one!
public static void RunFromFile(string filePath, bool addSharePointSnapIn) { #region Arg Validation if (String.IsNullOrEmpty(filePath)) { throw new ArgumentNullException("filePath", "Cannot be null or empty"); } if (!File.Exists(filePath)) { throw new FileNotFoundException("File not found", filePath); } #endregion try { PowerShell ps = PowerShell.Create(); if (addSharePointSnapIn) { ps.AddScript("Add-PsSnapin Microsoft.SharePoint.PowerShell -ErrorAction Continue"); } string script = ReadFileContent(filePath); ps.AddScript(script); var result = ps.Invoke();You can then just pass in the file path of your ps1 file and you’re away. Personally I have created a folder within the Layouts folder in my VS solution – that way it’s nice and neat and easy for source control.
More:
PowerShell script to find where in a site collection a specific feature is enabled.
It's not an uncommon task to want to find out in what webs you have a specific feature enabled. This little script does just that, taking 2 params (site collection url, feature name) and simple output the SharePoint web url. Nothing fancy, but certainly a useful script to have in your toolbox!
A good example of this is where you are using content publishing going from an Enterprise internal farm to a Foundation external farm, certain feature won’t be in the Foundation farm and will cause the Content Publisher to fail, it will be so kind as to tell you what feature is causing the problem, but not where it is! Someone somewhere has enabled a feature they shouldn’t have!!!
I’m sure some “one line wizards” could optimise this script – but that’s not my bag – I’m interested in getting the job done for our clients and providing a useful script we can use again and again.
You could of course add in Disable-SPFeature command if you wanted to do that at the same time…
#Powershell script to identify where in a site collection a specific feature is enabled #Version: 1.0 #Author: Steve Clements | Perspicuity Ltd #Params: #$siteCollectionUrl - url of the site collection #$featureName - name of the feature you want to find param ([string] $siteCollectionUrl, [string] $featureName) if(!$siteCollectionUrl-or!$featureName) { Write-Host-ForegroundColorRed"You must provide a site collection url and feature name to find!" break } Write-Host-BackgroundColorDarkGreen"Feature '"$featureName"' exists in these sites" Get-SPSite$siteCollectionUrl | ForEach-Object { Get-SPWeb-Site$_ | ForEach-Object { $f=Get-SPFeature-Web$_ | Where {$_.DisplayName -eq$featureName} if($f) { Write-Host$_.Url } } } Write-Host-BackgroundColorDarkGreen"Done"Gotcha: 403 and 401 errors in SharePoint using Anonymous access
Recently I came up against a problem where I was getting 401 Unauthorized and 403 Forbidden errors in SharePoint on an extended anonymous only site.
It worked perfectly when using windows authentication, for any level of user.
In the end I tracked the problem down to accessing SPContext.Current
I found this article which states you should use SPSecurity.RunWithElevatedPrivileges when using the current context and it worked!!
A little surprising, but not unexpected the SharePoint logs showed nothing about this problem.
Check out the link above which gives a perfect little code snippet of how to resolve the problem.