Showing posts with label SharePoint 2013. Show all posts
Showing posts with label SharePoint 2013. Show all posts

Monday, 5 May 2014

A Web Part with this ID has already been added to this page - Creating SharePoint App

I started with creating my first ever SharePoint App for SharePoint Online following this link. However, on trying to deploy my App I received the following error -


"A Web Part with this ID has already been added to this page".


I tried removing the web part (XSLT List View Web Part) and redeploying (please note that I was using NAPA for my development here) but that didn't work


I found this interesting blog post after Googling around and I appreciate the effort put in my Dragos here. According, to the post the reference of the Web Part is stored in the Content Database in the AllWebParts table mapped with the page on which it is placed. Usually, we add a web part to the SharePoint page using the SharePoint UI and delete it the same way. This would definitely add/delete the reference of the web part from the Content Database as well. However, since I was adding and removing the reference of the web part through HTML in my app, this would obviously not trigger the database for updating the reference.


Now, as I mentioned earlier, I am using SharePoint Online and therefore, cannot interfere with the database, so Dragos' solution would not work for me and as it is interfering with the SharePoint Content Database is out of limits.


So, since I could not delete the reference of the web part mapped against my page, I changed the name of my page and redeployed. And it worked!


Doesn't really help much if you are starting with a new app, but can save a lot of time if you have already implemented major functionality in your App. Either ways, it is interesting to understand the internal functioning of SharePoint.


Once again, really appreciate the MSDN Link and Drago's Post,

Friday, 2 May 2014

Wrap Promoted Links Web Part - Display Multiple Rows

The Promoted Links List/App gives a decent effect to represent static links instead of the Summary Links Web Part or the Links List in SharePoint 2013, though I would like to mention that Summary Links Web Part does have a few advantages.


However, in most cases the number of tiles (links) exceeds the available content area and we have a to navigate through the tiles using scroll buttons. For a relatively small number of tiles most users find this acceptable. However, if the number of tiles is too large and a certain group of users have to regularly browse till the last link, you can surely count them out of your Friend's List!


So, to ease things a bit here is a simple javascript you can use to "wrap" the Promoted Link Tiles after a set number of occurrences i.e. say you would like to display your tiles in rows of four. You need to embed the below javascript in the page where you are displaying the Promoted Link Tiles.




==Script Begin==
<script type="text/javascript" src=http://code.jquery.com/jquery-1.10.2.min.js></script>
<script type="text/javascript">
$(document).ready(function () {
   
// Update this value to the number of links you want to show per row
var numberOfLinksPerRow = 4;
   
// local variables
var pre = "<tr><td><div class='ms-promlink-body' id='promlink_row_";
var post = "'></div></td></tr>";
var numberOfLinksInCurrentRow = numberOfLinksPerRow;
var currentRow = 1
// find the number of promoted links we're displaying
var numberOfPromotedLinks = $('.ms-promlink-body > .ms-tileview-tile-root').length;
  // if we have more links then we want in a row, let's continue
  if (numberOfPromotedLinks > numberOfLinksPerRow) {
    // we don't need the header anymore, no cycling through links
    $('.ms-promlink-root > .ms-promlink-header').empty();
    // let's iterate through all the links after the maximum displayed link
    for (i = numberOfLinksPerRow + 1; i <= numberOfPromotedLinks; i++) {
      // if we're reached the maximum number of links to show per row, add a new row
      // this happens the first time, with the values set initially
      if (numberOfLinksInCurrentRow == numberOfLinksPerRow) {
        // i just want the 2nd row to
        currentRow++;
        // create a new row of links
        $('.ms-promlink-root > table > tbody:last').append(pre + currentRow + post);
        // reset the number of links for the current row
        numberOfLinksInCurrentRow = 0    }    // move the Nth (numberOfLinksPerRow + 1) div to the current table row
    $('#promlink_row_' + currentRow).append($('.ms-promlink-body > .ms-tileview-tile-root:eq(' + (numberOfLinksPerRow) + ')'));   // increment the number of links in the current row
    numberOfLinksInCurrentRow++;  }
}
});
</script>
==Script End==


Please note that to display more number of tiles per row, increase the "numberOfLinksPerRow" variable. Also, it would be a good idea to give a local jQuery library reference instead of codeplex reference.


I have taken this script from the TechNet Article here.


Hopefully, you will be in the "Good Books" of all your colleagues! :)








Friday, 23 August 2013

SharePoint Document Sets - not to be confused with FOLDERS

Document Sets - in my view is a very misunderstood and commonly misused entity in SharePoint.
 
The general perception about Document Sets is that they are Folders with a Welcome Page, but there is much more to it than just that.
 
A Document Set is a separate entity while a Folder, more or less, behaves as a location. Therefore, apart from grouping related items together a Document Set can also be treated as an item in a SharePoint Library. Therefore, all operations that are applied to a SharePoint Library item can be applied to a Document Set.
 
Below is a list of features of Document Sets:
  • A Document Set contains a welcome page which can be used to give more information about what it contains. Web Parts can be added to the welcome page to give a snapshot of what the Document Set will contain.
  • It can contain separate Metadata and Site Columns from the Library in which it is contained. Metadata and Site Columns can be shared by all documents in the Document Set or can be applied to individual documents.
  • By creating Content Types inherited from Document Set, we can define default documents that will be created along with our new Content Type. Suppose, we define a Content Type for Sales Report then we can associate all Sales Reports templates with that Content Type. Each time a new Sales Report Document Set is created, all the templates will be created along with it and users can simply fill in those templates to generate their report.
  • Workflows can be associated with the entire Document Set or individual documents inside the Document Set
  • Versioning can be applied to the Document Set.
  • Specific content types can be made allowable inside a Document Set.
  • Unique permissions can be associated with a Document Set.
Below are a couple of features not available with a Document Set, when compared with a Folder:
  • Document Sets cannot be nested i.e. Document Sets cannot contain Document Sets
  • Document Sets, as the name clearly suggests, cannot be associated with SharePoint Lists.
To enable Document Sets within your site you need to activate the Document Set feature which is available at the site collection level.

Document Sets are not available with SharePoint Foundation 2010.

Below are certain links for further reading:
For limitations of Document Sets refer this link: http://www.sharepointanalysthq.com/2011/09/document-set-limitations-and-considerations-in-sharepoint-2010/

 

Monday, 12 August 2013

Configure LDAP Authentication for your SharePoint 2010 or 2013 site

Recently, I tried configuring LDAP authentication for my SharePoint 2013 application.

Obviously, in case of SharePoint 2013 we need to use Claims based authentication and we need to configure three configuration files:
  • Security Token Service web.config
  • Central Administration web.config
  • The specific web application web.config.
There are many blogs explaining the details of these configurations. Here is an interesting link that explains stuff in detail - http://sharepointchick.com/archive/2010/05/06/configuring-claims-and-forms-based-authentication-for-use-with-an.aspx

However, there is one important task that you need to perform on your LDAP server to ensure that the authentication is successful. You need to give administrative permissions to the following accounts on your LDAP server:
  • Security Token Service application pool account
  • Central Administration application pool account
  • Web application app pool account.
This simple task had me hung up for quite a few hours (or days, I can't really recollect).

The interesting thing here is that SharePoint does not give you the specific error that it cannot access the LDAP directory straight away. It throws in a lot of generic errors such as - User credentials cannot be authenticated, please check user name and password. And somewhere amongst these generic errors is hidden your real error that it cannot access the LDAP server objects for authentication.

Monday, 8 October 2012

Convert existing SharePoint Web Application from Classic mode to Claims mode authentication results in all users getting "Access Denied" error or only view rights of the site

Scenario -
I had an existing SharePoint site that I had created with Classic mode authentication (not a good idea!) and due to certain requirements which needed to be implemented in this site I had to convert the site to Claims based authentication. Though I do not "claim" to be an expert in configuring "Claims" authentication I was aware of the simple process of converting Classic mode authentication to Claims mode.

As is true in most cases, I had commitments to meet and converting the site to Claims mode seemed an easy bit and was at the bottom of my priorities. However, after setting up most pieces of my site (which had anonymous access enabled, by the way) when I converted my site to claims mode I was surprised to see that I could no longer access my site with full privileges except with "System Account". Luckily, since I had anonymous access I was able to atleast browse the site with my other admin users and what I saw is that the user names appeared as "i:0#.w|domain\username". With the System Account I checked for the permissions of the site and the permissions were as earlier, nothing had changed. But, still no access.

Solution -
Please take a backup of your web application before running any of these scripts (it is a good idea to take a backup before running any major Powershell script) as it atleast helped me save face.

First of all below is the powershell script to convert classic mode site to claims mode

$webapp = Get-SPWebApplication -Identity "http://serverURL"
$webapp.UseClaimsAuthentication = $true
$webapp.Update()

As mentioned above after running this script access for my users was altered (removed, rather). Here is what you need to do in addition. But make sure you have your backup ready. The script is as follows -

$webapp = Get-SPWebApplication -Identity "http://serverURL"
$webapp.MigrateUsers($true)

Thats it! Seems pretty simple but it took me around 10 hours of searching before I reached this solution (makes me feel pretty dumb if you reached here in 5 minutes).

Caution! Caution! Caution! -
OK! There was a reason I asked you to have a backup before running scripts. This is what happens when you run the above mentioned scripts:

On executing the first script (to enable claims authentication) the SharePoint Content Database is made ready for claims based authentication but the already existing site users, who in my case were windows users, are not "migrated" to be understood by claims authentication. But SharePoint assumes all users to be claim users and renders them so. Therefore, a normal windows user - "Domain\UserName" appears as "i:0#.w|Domain\UserName". Furthermore, it uses the username in this same format to check for its permissions but does not find a matching entry for the user as the database has windows users - "Domain\UserName". So, the site will give you an access denied or, in my case, anonymous access privileges.

Note that the System Account will work since it's "Domain\UserName" is never used and System Account is a keyword used by SharePoint for your application pool identity. Therefore, it remains unaffected.

To overcome this situation we use the second script to "migrate" the users. MigrateUser($true) will convert all user accounts to claims format. After running this script user accounts are converted in the database to claims format, therefore, user names are read correctly by SharePoint, therefore, permissions for users are associated correclty by SharePoint and therefore, the site permissions work correctly.

Something very important to note here is that ideally, MigrateUser($false) should convert the user names back from claims format to the normal format, but it does not do so. This script will throw an exception and no change will be made to the database - so once you are in claim mode you cannot go back. Please refer this post to revert from claim mode to normal mode. Also note that these scripts are running on Web Applications so they will affect all site collections in that web application

Lessons learnt - I feel, that if you are creating a new web application in SharePoint 2010 always use Claims Mode Authentication as it gives you flexibility and you can avoid wasting your time on "migrating" users back and forth. Probably that is the reason why SharePoint 2013 has done away with Classic mode authentication and has only Claims-based Authentication.