Wednesday 20 November 2013

Promoted Links popup does not work on publishing pages


Today my colleague could not get new Promoted Links webpart to work when setting it to open the links in a dialog popup. Earlier the same day it worked perfectly.

The reason seems to be related to publishing pages. It works on team site pages, but not on publishing pages.



If you debug the site you get the following javascript error:
"Unable to get property 'ShowPopupDialog' of undefined or null reference"

The html a tag generated is the same for the page in SitePages (where it works) and for the page in Pages (where it doesn't work). Eg this is not the issue.

The masterpage is the same (seattle.master). Eg this is not the issue either.

Perhaps the javascript file is loaded in the page layout? Or at least the object containing the ShowPopupDialog is initialized in the pagelayout? (or in case of a master page it it clearly not loaded).

It must of cause be a bug, but unfortunately I haven't found a solution just yet. Next step is to digg into where exactly the SP.UI.ModalDialog object is initialized. Hopefully this will give some answers on why it is null.

Thursday 7 November 2013

Save as template missing

Publishing sites can NOT be saved as a template.
When you enable the publishing feature, the "Save site as temple" will disapear.

Wednesday 9 October 2013

Query SharePoint 2013 (on-premise, online, 365) list WITHOUT any code deployment

As a consultant you often get a task where you need to make some shiny and neat functionality to an existing site. But you are not allowed to make code-solution or there is simply no budget for that. What to do...?

In SharePoint 2013 many of these tasks can be done with out-of-the-box webparts, some JavaScript and CSS.

Lately I had customer who wanted two dropdown boxes on a list form to be related. If you choose the option "Fruits" in dropdown box one, you should only be able to select fruits in dropdown box two:

[PICTURE]

In short

So what I basically did was to call the rest webservices to query a list with all the fruits, vegetables and other choices for the drop down with a ajax call from jQuery. I put all this "code" in a Content Editor Web Part and placed it on the "New Form" and "Edit Form" for the list containing the drop down boxes.

Step by step

La la la... (shorthand for: "coming soon")

Wednesday 22 May 2013

Run as a diffenrent user account eventhough your computer is not a part of the domain

As a consultant you often need your computer is not a part of your clients domain, however you need to run programs on their servers as a domain account given to you.

"Right-click" -> "Run as" does not work..

But THIS PowerShell command will do the trick:
  • runas /netonly /user:domain\username cmd.exe

TIP: How to Run Programs as a Domain User from a Non-domain Computer
Pretend You’re On The Domain With Runas /NetOnly

SharePoint 2013 reading

SharePoint 2013 development
http://msdn.microsoft.com/en-us/library/jj162979.aspx

How to: Create a page layout in SharePoint 2013
http://msdn.microsoft.com/en-us/library/jj822368.aspx

Cross-site publishing in SharePoint 2013
http://msdn.microsoft.com/en-us/library/jj163225.aspx

Scenario: Create SharePoint sites by using cross-site publishing in SharePoint Server 2013
http://technet.microsoft.com/en-us/sharepoint/jj872721

How to set up a product-centric website in SharePoint Server 2013
http://blogs.technet.com/b/tothesharepoint/archive/2013/02/14/how-to-set-up-a-product-centric-web-site-in-sharepoint-2013.aspx


Tuesday 26 March 2013

Design your system according to SharePoint boundaries and limits

When designing the architecture of a SharePoint solution it is fairly important to design so that it will not exceed the limits listed by Microsoft in SharePoint Server 2010 capacity management: Software boundaries and limits.


Friday 22 March 2013

Best practices for using fine grained permissions in SharePoint 2010

Error! "You cannot break inheritance for this item because there are too many items with unique permissions in this list".
This may be the error you get when trying to add a new item to a list with unique permissions on the items.

Microsofts best practices on that one:



Best practices:

  • Only set unique scopes on parent objects such as folders.
  • Do not create a system with many uniquely permissioned objects below an object that has many scopes.

If your business requires that you more than 50,000 uniquely permissioned items in a list or document library, then you must move some items to a different list or document library. 

The above is a quote from Microsoft's "Best practices for using fine-grained permissions": http://technet.microsoft.com/en-us/library/gg128955.aspx

My advice: Instead of making one list with broken permissions for n number of groups. Can you in your solution make a design where you make n number of lists each with only permissions broken on list level. Items will inherit from the list then.

How to avoid it in future systems

SharePoint is often used in large companies with a lot of employees/users, generating and sharing a huge amout of data. But never may all employees see all data.
In SharePoint you can control exactly who can see the data by setting permissions on secureable objects (site, lists, list items etc.). You can be tempted to break permission inheritance as it then is easier to make a system architecture that fits with your companies business logic with regard to permissions.

However be warned! This is NOT the best practice!
Try to make a design that do not break inheritance unless it is really necessary.
If you do not design your system wisely you will reach the limits when your system is in use and may be critical for the daily operation. However you will be forced to do a long and painful redesign of your system. In all this time it will not be up and running!

I lately ran in to a problem where I was dealing with a solution with a list containing 50,000 items all with unique permissions. This hit the boundary of what is supported. This called for a redesign. A perfect one! But fast!

To save you self the trouble read the best practices from Microsoft regarding fine grained permissions in the document here: http://technet.microsoft.com/en-us/library/gg128955.aspx

How to restrict the user only see list items created by him/her

This can be achieved in a couple of ways including coding an eventreceiver listening on ItemAdding or a workflow when items are added.

However the easiest would probably be to modify the default view and add the following filter:


The users should not have permissions to change the view though!

Wednesday 27 February 2013

Error - All items returned by SPQuery

When you form your caml to be used with an SPQuery remember not to include the <Query></Query> tag. Begin with the <Where> tag.

Correct - The following will only return the item with the title "Listitem One":
  • <Where><Eq><FieldRef Name='Title' /><Value Type='Text'>Listitem One</Value></Eq></Where>
Wrong - The following will be some weird reason return all list items:
  • <Query><Where><Eq><FieldRef Name='Title' /><Value Type='Text'>Listitem One</Value></Eq></Where></Query>

Tuesday 26 February 2013

Create a cross site lookup field without code

Out of the box you cannot create a cross site lookup field in SharePoint. You must create a new field type (code) to do this.
However the other day I came across a easy workaround where you don't have to code anything:

  1. Create your lookup list on the parent site
  2. On the parent site create a lookup site column that looks into the list created in step one.
  3. On the subsite create a list that should use the information stored in the list on the parent site.
  4. Add an existing column to the list (the column created in step two).

See also: Creating a cross site lookup field without code


Tuesday 19 February 2013

Error occurred in deployment step 'Activate Features': The parent content type specified by content type identifier 0x010100C568DB52D9D0A14D9B2FDCC96666E9F2007948130EC3DB064584E219954237AF3900242457EFB8B24247815D688C526CD44D does not exist.


  • Solution: Activate the publishing features.

In this case you probably have a pagelayout that inherits from the "Article Page" content type (which is a part of the publishing pages).

Wednesday 13 February 2013

Getting the full url in the code behind of a SharePoint page in the layouts folder

The issue

I had a situation where I had created a sub site collection and a deployed a asmx websercice to a subfolder in the layouts folder.
From codebehind I used HttpContext.Current.Request.Url to get the url of the web service.

If I in the browser entered the address:
  • http://server/sites/subsitecol/_layouts/webservice.asmx
I got the url
  • http://server/_layouts/myfolder/webservice.asmx
in the codebehind. Notice it has omited the path to the sub site collection.

My workaround

The RawUrl contains the path to the sub site collection. However it is server relative, so I build the absolute url like this (there might be better ways to construct the absolute url):

var uri = new UriBuilder(HttpContext.Current.Request.Url);
uri.Path = HttpContext.Current.Request.RawUrl;
var absoluteurl = uri.Uri.AbsoluteUri;


Thursday 7 February 2013

Upgrade a feature with PowerShell

When you wnat to add new fields to an existing content type in SharePoint you make a new version of the feature - an upgraded version. You deploy the new wsp package with an SPUpdateSolution command.
But you are not done yet! It is only deplyed to the server. You must tell SharePoint explicitly too look for a new version of the feature, and upgrade the feature to this version.
Oddly you cannot do this through the interface - you must do it through code. This can be done in C#, (Visual Basic?), or in PowerShell.

To upgrade a feature in PowerShell you do this:

  • $s = Get-SPSite -Identity 'insert url of the web where the solution is deployed'
  • $features = $s.QueryFeatures('web',$true)
  • foreach($feature in $features){if($feature.DefinitionId -eq ‘72dc4341-4404-413c-b8ab-22e5723fdbec'){$feature.upgrade($true)}}

This will upgrade the feature with id "72dc4341-4404-413c-b8ab-22e5723fdbec".

Monday 4 February 2013

Your Search Cannot Be Completed Because This Site Is Not Assigned To An Indexer

I had this very annoying error when trying to search my SharePoint Server 2010 single server development machine through code (using the KeywordQuery and FullTextSqlQuery classes).
The search crawler was running and searching from the SharePoint UI returned the expected results.

What you need to do is to...
  • Start the "SharePoint Foundation Search"service.
  • then go to the select "Manage Content Database Settings" page and select the server running the SahrePoint foundation search service at the drop down menu

Central Administration -> Application Management -> Manage services on server


Central Administration -> Application Management -> Manage Content Database -> (click on database name)



This was not intuitive to me as I was running SharePoint Server Enterpise. And the "SharePoint Server Search" service was already running. Also it strikes me as odd as you do not have the FullTextSqlQuery in SharePoint foundation - you need to have the Enterprise version.

Close and re-open web parts

If you wanna hide a web part for a while so that you can re add it to the page later without having to reconfigure all of it settings this is what you do:

Close the web part from the web part drop down menu (the arrow that appears in the top left cornor of the web part when you hover over it):




When you later wanna re enable it, you click add web part as normal,k however this time you click the "Closed webparts group" and add it from here:


Friday 25 January 2013

Disable "Attach Security Warning" in Visual Studio 2010 when attaching debugger

In regedit change the following key from 0 to 1:


HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\10.0\Debugger\DisableAttachSecurityWarning

The annoying security warning when attaching the debugger

Set the "DisableAttachSecurityWarning" to "1" in the registry database


Thursday 3 January 2013

Adding a new field to a content type by upgrading a feature

Working with content types that are already deployed can be tricky.
Working with feature upgrade is a pain in the b... as well. In fact I'm amazed how poorly it is handled in SharePoint taking into consideration how common a task it should be.

Quite often you need to add an extra field to a content types which has already been deployed and associated with a list.

After a lot of trying I finally found a solution that is working for me.


Vesa Juvonen has made a very good blog on the subject here:

WebTemplate training materials – Lab 4 - Upgrading existing sites with feature versioning


It's a fairly big and complex thing, so will not rewrite it all here.
But in short terms the things you have to do and be aware of is:

  • Make a new Elements.xml for your new field.
  • Do NOT add the field to the existing content type Elements.xml file!
  • In the xyz.Template.xml file for your feature that deploys your content type (= the feature you want to upgrade), add UpgradeActions, ApplyElementManifests, CustomUpgradeAction (see snippet below)



  <UpgradeActions>
    <VersionRange BeginVersion="0.0.0.0" EndVersion="3.0.0.0">
     
      <ApplyElementManifests>
        <ElementManifest Location="FieldsV2\Elements.xml" />
      </ApplyElementManifests>

      <CustomUpgradeAction Name="AddFieldToContentType">
        <Parameters>
          <Parameter Name="FieldId">58757B21-3BDD-4AC7-BCE5-ACFC025735E2</Parameter>
          <Parameter Name="ContentTypeId">0x0100906acb18801a416680c0017602a462d7</Parameter>
          <Parameter Name="UpdateChildren">true</Parameter>
        </Parameters>
      </CustomUpgradeAction>
     
    </VersionRange>


  • Add an event reciever for the feature and implement the FeatureUpgrading method. Here programmatically add the new field to the content type.


        public override void FeatureUpgrading(SPFeatureReceiverProperties properties, string upgradeActionName, System.Collections.Generic.IDictionary<string, string> parameters)
        {
            SPWeb web = ((SPSite)properties.Feature.Parent).RootWeb;
            switch (upgradeActionName)
            {
                case "AddFieldToContentType":
                    string fieldId = parameters["FieldId"];
                    string contentTypeId = parameters["ContentTypeId"];
                    bool updateChildren = true;
                    bool flag;
                    updateChildren = bool.TryParse(parameters["UpdateChildren"], out flag);
                    UpdateManager.AddFieldToContentType(web, contentTypeId, fieldId, updateChildren);
                    break;

                default:

                    break;
            }

        }


        public static void AddFieldToContentType(SPWeb web, string contentTypeId, string siteColumnId, bool updateChildren)
        {
            try
            {
                SPContentType type = web.ContentTypes[new SPContentTypeId(contentTypeId)];
                type.FieldLinks.Add(new SPFieldLink(web.Fields[new Guid(siteColumnId)]));
                type.Update(updateChildren, updateChildren);
            }
            catch (Exception ex)
            {
                // TODO write to log
                //throw;
            }
        }

  • Now implement the FeatureActivating method in a similar manner in order to make the upgraded functionality of the feature available for new installations of the feature as well (else it will only get added when the feature is upgraded).
  • Now deploy your wsp package. After it is deployed you must programmatically upgrade the feature. This is done by first making a query on features that needs upgrading, and then calling the Upgrade methode on the feature. This can be done with C# code or in PowerShell.

In this approach the CustomUpgradeAction tag was used in the fefature template.xml file. There is also a out of the box tag for adding a feature to an existing content type which can be used. It is called: "AddContentTypeField". However I have not have any success with using this. I have read that it should not work reliably with all culumative updates of SharePoint. Mayby trhis is why? I'm not sure. However I can not work with it. You could have a scenario where it works in your development environment, but not in production.