Wednesday, December 22, 2010

Sandbox solutions and the publishing image field type

I recently found out (to my horror) that sandbox solutions do not support (among many other things) the publishing field types. For example, if you want to use the "LinkFieldValue" class from the Microsoft.SharePoint.Publishing.Fields namespace in a sandbox solution, then you are out of luck. So far, fair enough - annoying, but fair. I figured that I can overcome this by not using that class to parse the details of the image from publishing pages, and I will write my own function that will tease out the image URL from the string that the field returns.

How naive am I!

When I tried running this: imageUrl = item[field.Internalname);

The code would time out, and not return anything. The entire page would just hang. No exception thrown or any reason given.

My solution was to use: imageUrl = item.GetFormattedValue(field.InternalName);

Apparently this gets the string value without trying to go through anything that is not supported in sandboxed solutions. Update: after a bit of more trial and error I found that the exception thrown (sometimes) is that the assembly (the publishing one) is not serialiazble:
'item[this.ImgFieldName]' threw an exception of type 'System.Runtime.Serialization.SerializationException'

Sunday, December 12, 2010

"Cannot complete this action." error when adding a field to a list (or a content type)

If you are trying to add a site column to a list, or a content type that has a site column to a list, and get the dreaded "Cannot complete this action.", then have a read below. Note - this is valid for both sharepoint 2007 and 2010.

To troubleshoot this, I turned off the custom errors to see the entire stack trace of the error. The error was thrown by the Microsoft.SharePoint.Library.SPRequest.AddField function. This lead me to read Eric's blog post about the error and he pointed me in the right direction.

It turns out that a lookup column that allows multiple selection is not supported as an indexed column. You'd expect SharePoint to validate that, and indeed you do not get that option when configuring such a column using the user interface.
However - sharepoint does not validate that when you create the site column using CAML (which is what Eric did) or using code (which is what I did).

Eric's blog post shows how you can recreate and resolve the problem if you are creating the column using XML. So just in case you are making the same mistake I was doing, this is how I resolved my issue - I just make sure none of my code-created lookup columns is both multi select AND indexed, as you can see in the code below.

SPFieldLookup newField = web.Fields.GetFieldByInternalName(newColumnInternalName) as SPFieldLookup;
newField.Title = "My Lookup";
newField.AllowMultipleValues = isMultiSelect;
newField.Group = "My Site Columns";
if (!isMultiSelect) newField.Indexed = true; else newField.Indexed = false;
newField.LookupField = myList.Fields["Title"].InternalName; newField.Update();

Sunday, November 21, 2010

The Web application at ... could not be found when creating a new SPSite object

A quick hint for anyone hitting this issue - you are trying to open a SPSite object using a URL and hitting the following error: "The Web application at [...] could not be found. Verify that you have typed the URL correctly. If the URL should be serving existing content, the system administrator may need to add a new request URL mapping to the intended application." is common, and can have several causes.

  1. The obvious: The URL does not exist on the farm. Solution: change the URL you are loading to the correct one.
  2. The not so obvious: the code is in a console or windows application which you are now running with an account that does not have permissions to connect to the SQL server. Solution: either run the application as a different user or grant the user permissions on the SQL database.
  3. The one hiding behind the sofa: the code is in a console or windows application that is compiled with platform target x86, while your SharePoint server is x64. Solution: set the platform target to "Any CPU".

Tuesday, October 19, 2010

Coming to Canada's SharePoint Summit

Hello to all my Canadian readers!

I am excited to announce that I will be speaking in the upcoming Toronto SharePoint Summit!
And not just speaking - from the looks of it I seem to be doing the most speaking of all the other speakers (I guess the organizers figured that the cost of a plane ticket from Australia needs to be covered by three sessions). Please come see me talk on:

Oh - and if anyone has recommendations what to do the week before the conference (last week of January) - please comment here! Ski resorts recommendations would be most welcome.

Saturday, October 16, 2010

PowerPivot For SharePoint

Are you in Canberra this week? even if not, you may want to read this post.

This week I am presenting in the Canberra SharePoint User Group about PowerPivot for SharePoint. I have spent the weekend reading and testing this application - mostly trying to figure out how it is different from Excel Services.

Basically, powerpivot for excel is a powerfull database analysis add on to excel that creates connections to external databases, analyses the relationships for you and allows you to create great pivot tables and charts from this relational external data. This makes creating pivot tables from complex databases very simple.

PowerPivot for SharePoint is a service application that you install from SQL2008R2 features. This adds the ability to open the workbooks that were created by powerpivot on the browser, while still remaining connected to the external database. It also adds a "powerpivot gallery" list template that creates a special document library with a nice and smooth interface to allow the users to look for the pivot sheet they want to open, and it has the default "open in browser" behaviour. The data gets refreshed and accessed on the server, so even users with weak desktops can analyse huge databases (up to 100 million rows - depending on the amount of RAM the server has). A good high level overview can be found on the powerpivot blog on MSDN, installation instructions on MSDN and a demo and a lot of marketing information on the official powerpivot site.

Two thing you should know:
to allow the web application to authenticate to the database the pivot is connected to, you will probably need to activate the "Claims to Windows Token Service" service (which is by default off if you used the configuration wizard to configure for you). Otherwise, the power pivot will keep giving you authentication errors.
The last thing is a problem with the way the powerpivot application is deployed. Don't ask me why, but there is a problem with how it is deployed, as described in this powerpivotgeek's blog post. If you get an error when opening a powerpivot gallery list, check out the geek's post for the solution (simply deploy the solution to the web application...).

So, if you are in town, come say hello and watch me install, set up, and run powerpivot in the Canberra user group. If not, you have a chance to see me next week in the South East Asia SharePoint Conference in singapore.

Monday, August 23, 2010

What do you get when you google "Visual studio 2010"?

I don't know about you, but my search engine of choice just gave me a big surprise as the first result. It only happens when you use google Australia (.com.au), not in google.com:

Am I imagining things, or is the first result a spam site? Microsoft - you may want to do something about this...

Sunday, August 22, 2010

My SharePoint 2010 How To book is now available in print

My second book is now officially published and I can stop fretting about revisions for a while. If you like, take a look at it in Amazon, where you can take a look inside!
SharePoint 2010 How To (Amazon)

If you want to buy either of my books, (paper or digital copy), you can use the following links:

Thursday, August 12, 2010

How to set values for a checkbox choice list field? (SPFieldMultiChoice)

This is a question I just recieved through my "contact" form for this blog. The person (Chris) who asked the question gave a wrong email address, so I will post the answer publicly since I believe this can help other starting sharepoint developers - especially since I saw some wrong tips coming up in google when you search for it. So here is the right way to do it.

Question: "Hi, thanks a mil for those snippets!One question: I'm trying to programatically add selected items of a checkBoxList to a SPListItem, but am not sure in what format it wants it. i.e I've added all items as you suggested - newItem["Name"] = "blah" etc, but when it comes to the field that requires the selected checkboxlist values, I'm stuck."

Answer: to set the value for a check box choice list (a field of type choice, with multiple choices allowed - showing checkboxes), you should use the SPFieldMultiChoiceValue class to set the value. This class allows you to construct the list of choices you want to set for the column by adding the string values to it. Here is an example on how to use it:

SPList sampleList =web.Lists["test"];
SPFieldMultiChoiceValue val = new SPFieldMultiChoiceValue();
val.Add("choice1");
val.Add("choice3");
SPListItem newItem = sampleList.Items.Add();
newItem["Title"] = "This is the new item";
newItem["test"] = val;
newItem.Update();

Wednesday, August 04, 2010

Using jQuery validation in a sharepoint web part

As we all know, a sharepoint page can only have one <form > tag in it. As anyone who wanted to use jQuery validation knows, the validation script needs to run on a form tag.
So how do I use the validation code in a sharepoint web part?

The answer is to run the script against the form that already exists in the page. For example, I had to write a web part with an email address field, and wanted to help the users by validating the text they entered is a valid email address on the client side (I also validate on the server side - just in case someone is running a browser with no script). This is the "Render" override code that I used:

       txtEmailAddress1.CssClass = "required email";
       base.Render(writer);
       if (SPContext.Current.FormContext.FormMode != Microsoft.SharePoint.WebControls.SPControlMode.Edit)
       {
              writer.Write(@"<script>
$().ready(function() {
    $(""#" + this.Page.Form.ClientID + @""").validate();
});
</script>
");
       }

As you can see, I am adding a css class of type "required email" for the text box, and then telling the form on the page to validate using the jquery validation plug in. This of course assumes you added the references to the jquery scripts to the page...which you may want to do as part of the web part (override oninit, and registerclientscriptblock) or as part of the master page (if you expect a lot of web parts to use it).

As for the "if (SPContext.Current.FormContext.FormMode != Microsoft.SharePoint.WebControls.SPControlMode.Edit)" line - you have to be careful that your validation does not prevent you from editing the page. For example, if you remove that "if", you will not be able to change the properties of any web part on the page without first entering a valid email address in the textbox!

I am speaking at the South East Asia SharePoint Conference!

Are you planning to be in Singapore on October 26-27 this year? You should! the speakers are being announced, and I for one will be there for at least one presentation - how to build web parts for 2010. And no, it is not going to be the regular "open visual studio, choose the web part project" presentation...get ready for big things!
See you there!