Posts Tagged ‘SharePoint’

SharePoint Tools learned at ShareCamp

April 20, 2013

I had the opportunity to attend to ShareCamp in Microsoft München and hier are some interesting tools that I saw during the lessons:

Name Description
Search query tool Really nice tool for generating search queries against SharePoint 2013. You can see the xml and field names that come from SharePoint. Really helpful when creating custom search templates.
dotPeek A free alternative to .NET Reflector by JetBrains
PowerGUI A free tool like Powershell ISE but better.
IronSP Interesting tool for development for SharePoint in Ruby. Currently under development and not simple to use without deep knowledge of the project.
Collaboration Manager A commercial tool for managing SharePoint templates including upgrades. However it costs lots of money.

Hope you find this list helpful.

Advertisements

Fixing Metadata Field Connection after importing a Website to another Farm

April 10, 2013

This is a follow up to this post, where I described how you can create new website from template using Import-SPWeb. If you use managed metadata fields in the you will find out, that these fields cannot be used after importing of the website. The reason is, that the link to the managed metadata application is broken. This script will fix it:

$url = "http://yoursitecollection"
$termStoreName = "yourTermStoreName"
$termSetName = "nameOfTheLinkedTermSet"
$listName = "nameOfTheListWithManagedMetadataField"
$fieldName = "nameOfTheManagedMetadataField"

$web = Get-SPWeb $url

$session = Get-SPTaxonomySession -Site $url

$termStore = $session.TermStores[0]

$group = $termStore.Groups[$termStoreName]

$termSet = $group.TermSets[$termSetName]

$list = $web.Lists[$listName]
$field = $list.Fields[$fieldName]
$field.SspId = $termStore.Id

$field.TermSetId = $termSet.Id
$field.Update()

$list = $web.Lists[$listName]
$field = $list.Fields[$fieldName]

$taxonomyList = $web.Lists["TaxonomyHiddenList"]

$field.SchemaXml = $field.SchemaXml.Replace($field.LookupWebId.ToString(), $web.ID.ToString())
$field.SchemaXml = $field.SchemaXml.Replace($field.LookupList.ToString(), $taxonomyList.ID.ToString())
$field.Update()

$web.Dispose()

The script relinks the managed metadata field to the termstore and fixed the link to the webid and link to the taxonomy hidden list.

Custom templates using SP-ExportWeb

March 25, 2013

When creating custom templates for users, you have following possibilities:

  1. Create a template in Visual Studio
  2. Create a template website in SharePoint and save website as a template (wsp).
  3. Create a template website in SharePoint and save it with Export-SPWeb powershell command.

Each of this solutions has its drawbacks:

Ad 1. complex and time consuming solution, prone to errors.
Ad 2. Following features are not supported: Customized permissions, running workflow instances, list item version history, workflow tasks associated with running workflows, people or group field values, taxonomy field values, publishing pages and publishing sites, My Sites, and stapled features. See following article http://msdn.microsoft.com/en-us/library/jj938033.aspx#bkmk_WhatIsTemplate
Ad 3. the taxonomy fields in the website created from template in the different sharepoint farm will be broken.

As the title suggests I will describe the third option in this article.

Creating the template

  1. Create your template in SharePoint. (Activate the features, add lists, fields and documents)
  2. Open the Powershell console and execute following command:

Export-SPWeb http://yoursite–Path "c:\temp\export.cmp"

Creating a website from the template
Create new empty website and use the Import-SPWeb to import the content from the file:
New-SPSite http://newsiteurl/ -OwnerAlias "loginname" -Name "newWebSiteName"
Import-SPWeb http://newsiteurl/ -Path "c:\temp\export.cmp" -IncludeUserSecurity

The advantage of this approach is, that if you create a new version of the template you can reimport it on an existing website. The changes in the new template will be merged with the changes in the existing website made by the users . However I recommend to create a backup from the website before reimporting.

There are two things  that remain open:

  1. The metadata fields will not be relinked to the termsets after importing into another farm.
  2. The “Self Service Creation”-like functionality is missing. There is some development that needs to be done.

Maybe next time.

 

Announcement

March 25, 2013

Recently me and my friend Radek Matouch  started a new company. We focus on development and consulting in SharePoint  and .NET. Check out our website www.codeeffect.cz if you are interested and wish us luck . 😉

High Trusted SharePoint Application Gotchas

December 10, 2012

I followed this guide and this guide to create a demo high trust applications and here’s the summary of things the I came across:

Problem
Cannot deploy the solution in general.
Fix:

  1. You cannot be logged on as sharepoint\system. Log on as another user to the server.
  2. You have to start Visual Studio Administrator (Right Click “Run as administrator” command)

Problem
Cannot deploy the solution with error: Error occurred in deployment step Uninstall App for SharePoint’: ‘Cannot connect to the sharepoint site
Fix
The current user does not have permissions on the SharePoint Config Database and Content Database. Give the user owner permissions on these two databases.

Problem
Cannot deploy the solution with error: Error occurred in deployment step ‘Install app for SharePoint’: The provided App differs from another App with the same version and product ID.
Fix
Open manifest.xml in code view and generate new guid for the app.

Problem
Cannot deploy the solution with error: Error occurred in deployment step ‘Install app for SharePoint’: We’re sorry, we weren’t able to complete the operation, please try again in a few minutes. If you see this message repeatedly, contact your administrator.
Fix
The current user has to have owner permissions on the App_Management Database.

Problem
Problem when trying to debug: Unable to launch IIS Express Web Server
Fix
Switch to full IIS.

  1. Open Properties of the AppWeb Project and uncheck the checkbox “Use ISS Express” on the “Web” app.
  2. Click Create new Virtual Directory on the same tab.
  3. Assign “full control” permissions on the folder for the application pool account.

Problem
Cannot connect to https://localhost
Fix
I did not configure IIS to run with https. I had  to change the manifest.xml of the app to replace the ~remoteAppUrl to http://localhost .

Problem
Could not load file or assembly ‘Microsoft.IdentityModel, Version=3.5.0.0 TypeInitializerException System.Runtime.InteropServices.COMException: The handle is invalid. (Exception from HRESULT: 0x80070006 (E_HANDLE))
Fix
The application pool was running in .NET Framework Version 2.0. Should be 4.0. You can change this directly in the IIS in the application pool settings.

 

Multilanguage in Navigation using Webtemplate does not work

May 15, 2012

I created a webtemplate (http://msdn.microsoft.com/en-us/library/ms434313.aspx) in SharePoint and added following localized Navigation Bar to the top the navigation in the onet.xml:

<NavBar Name="$Resources:osrvcore,SspAdministrationTopNavBarTitle;" ID="1002">
<NavBarLink Name="$Resources:osrvcore,HelpText;" Url="default.aspx" />
 </NavBar>

then I created a web site based on the template and turned the multilanguage on.

The problem is that the navigation bar stays always in one language and is never localised to current language of the website. If I use the same xml file in the sitetemplate everything works correctly.

The problem is recognized as designed by Microsoft and there is only workaround available.

Solution

  1. Delete the navigation from the onet.xml
  2. Recreate the Navigation with code.

Creating the navigation programmatically

  • Create the xml file called navigation.xml with the navigation and let it be deployed to the layouts folder. The file should have following structure:
</div>
<?xml version="1.0" encoding="utf-8" ?>
<NavBars>
<NavBar Template="templatename">
<NavBarLink Url="$Resources:cmscore,List_Pages_UrlName;/page1.aspx" Name="$Resources:osrvcore,HelpText"/>
 <NavBarLink Url="$Resources:cmscore,List_Pages_UrlName;/page2.aspx" Name="$Resources:osrvcore,HelpText"/>
</NavBar>
</NavBars>
  • Load the xml file:
public IList<NavigationNode> GetNavigation(string templateName)
{
{
var fileName = SPUtility.GetGenericSetupPath("TEMPLATE\\LAYOUTS\\navigation.xml");
var navigation = new List<NavigationNode>();
var data = new XmlDocument();
data.Load(fileName);
var xpath = string.Format("/NavBars/NavBar[@Template='{0}']/NavBarLink", templateName);
var nodes = data.SelectNodes(xpath);

foreach (XmlNode node in nodes)
{
navigation.Add(new NavigationNode
{
Name = node.Attributes["Name"].Value,
Url = node.Attributes["Url"].Value
});
}

return navigation;
}
}
  • Add the navigation nodes to the top navigation. There is also handling if the url contains resources that have to be replaced
foreach (var navigationNode in GetNavigation(templatename))
{
var parsedUrl =  ParseNavigationUrl(navigationNode.Url, web.Language);
var spNavigationNode = new SPNavigationNode(navigationNode.Name, parsedUrl, true);
web.Navigation.TopNavigationBar.AddAsLast(spNavigationNode);
}
private static string ParseNavigationUrl(string url, uint language)
{
var resourceExpression = GetResourceExpressionFromString(url);
if (string.IsNullOrEmpty(resourceExpression))
return url;
var localizedString = SPUtility.GetLocalizedString(resourceExpression, string.Empty, language);           return url.Replace(resourceExpression, localizedString);
}
private static string GetResourceExpressionFromString(string text)
{
if (string.IsNullOrEmpty(text))
return string.Empty;
var dollarIndex = text.IndexOf("$");
var semicolonIndex = text.IndexOf(";");
if ((dollarIndex == -1) || (semicolonIndex == -1))
return string.Empty;
return text.Substring(dollarIndex, semicolonIndex - dollarIndex + 1);
}

SharePoint 2013 v15 What’s new?

May 2, 2012

I recently found following document SharePoint 15 Technical Preview Interoperability API Documentation. Here can we find some parts of the new SharePoint 15 API.

Here are some information, which you could find interesting. Please keep in mind, that what I write here are only guesses and I can be totally wrong.

Market place

I found following classes: SPApp, SPAppCatalog, SPAppInstance. These new classes suggest that Microsoft will release a market place for the next version of SharePoint. What role will be playing Sandboxed Solution. There exists even a licensing model for the marketplace. The SPWebapplication was extended with the method IsUserLicensedForEntity. The Application will be loaded into SPWeb according to the methods SPWeb.LoadAndInstallApp. You can read more about it here. However in czech.

Extensive usage of JSON

There are following new classes JsonReader, SPFieldServerStub, SPFieldLookupServerStub. These classes contain methods for creating and reading JSON objects. So it will be possible to read information about field in Javascript.

SPFieldLookup.GetJsonClientFormFieldSchema

Details: Gets an object containing field schema information for client rendering.

So we can read also the information about the field definition in Javascript.

SPFileRightsManagementSettings

New Dataholder for SPFile properties. The  class has  following properties:

  • AllowPrint Gets or sets a value indicating whether the viewer can print the document.
  • AllowScript Gets or sets a value indicating whether the viewer can run script on downloaded document.
  • AllowWriteCopy Gets or sets a value indicating whether the viewer can write on a copy of the downloaded document.
  • DocumentAcceExpireDays Gets or sets the number of days before a downloaded document will expire
  • GroupName Gets or sets the group name (email address) to which the permission applies.

SPSite.CompatibilityLevel

Gets the major version of this site collection for purposes of major version-level compatibility checks. For which version is the Site Collection designed?

SPUtility.GetLayoutsFolder

Returns the versioned layouts folder for the specified site collection.

According to this we can have different versions of laouts folder for different webs. The laouts folder is not Farm scoped anymore.

OAuth

Class SPOAuth2BearerCredentials and namespace Microsoft.SharePoint.IdentityModel.OAuth2. Support of OAuth2 like Windows Live ID, Twitter, Facebook?

ClientContext extensions

Microsoft.SharePoint.Client.Search.Query

We can start search queries directly from the Client Object Model

Microsoft.SharePoint.Client.Search.SearchExecutor

We can start multiple search queries  in batch.

Microsoft.SharePoint.Client.File

OpenBinaryStream:  We can open the file from server on the client.

 

 

Google Id/Windows Authentication in SharePoint 2010 using Windows Azure

December 11, 2011

In this article I will describe how to enable signing in using Google Id, Windows Open Id, Facebook or Yahoo account to a SharePoint 2010 site collection. As authentication provider I will use Windows Azure Platform.
Here are the steps you have to do:

Configure the Azure platform

  1. Create an account on Windows Azure Platform using your Windows Live Id. There is 90 days evaluation period available on Windows Azure that is free, additionaly the Access Control Services I will use as authnetication provider are free at least until December 2012. During the registration process you will be however asked to fill in you credit card number. For more information about pricing see this.
  2. After you created your azure account go to the Windows Azure management portal  https://windows.azure.com/.
  3. In the portal click “Services Bus, Access Control & Caching ” and then “Access Control”. See following picture
  4. Click new to create a new namespace and select a unique name for the namespace and the region where your server exists and click “Create namespace” button
  5. Wait until the namespace is activated. It takes several minutes
  6. Click the newly created namespace and then “Access Control Service”
  7. Click “Identity providers” and add the providers that should be used in your SharePoint site collection for the authentication. See folllowing image.
  8. Click Relying party application button in the left tab and add a new Relying application and fill the form as marked in the following image. The url should be the url of your sharepoint web application.
  9. Also check the “Create new rule group”
  10. Now click the “Rule groups” and click Generate. The form should look like this afterwards:
  11. Click save.
  12. Click  “Application Integration” under “Development” tab. Then “Login pages” and then your relying service application.
  13. Copy the content of the textbox und option 1. It should look like this https://yournamespace.accesscontrol.windows.net:443/v2/wsfederation?wa=wsignin1.0&wtrealm=http%3a%2f%2fsharepoint2010%2f
  14. For now you are done with the azure platform configuration. Now go to your SharePoint server where should be the claims authentication enabled.

Create and export new certificate

  1. Run following command “MakeCert.exe -r -pe -n “CN=<yournamespace>.accesscontrol.windows.net” -sky exchange -ss my”. The Makecert.exe can you find in this folder: C:\Program Files\Microsoft Office Servers\14.0\Tools
  2. Here http://msdn.microsoft.com/en-us/library/gg185932.aspx  you can find a description how to export the newly created certificate for the communication betwen SharePoint and Azure.
  3. Once you have the file go back to Azure platform to your namespace and click “Certificates and keys” and click “Add” button in the “Token signing” section.
  4. Upload the exported certificate and leave the other setings to default

Configure SharePoint to use claims
Run following script. Replace following things:

  1. Path to the certificate
  2. Password of the certificate
  3. $realm (it is the Url you gave in the Relying Application Settings as Realm). Mind the slashes.
  4. $signinurl It is the url from step 17
  5. The names of the providers.

Add-PSSnapin "Microsoft.SharePoint.PowerShell"

$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2("yourcertificatename.pfx","yourpassword")

$map1 = New-SPClaimTypeMapping "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" -IncomingClaimTypeDisplayName "Email" -SameAsIncoming

$realm = "http://sharepoint2010/"

$signinurl = "https://yournamespace.accesscontrol.windows.net:443/v2/wsfederation?wa=wsignin1.0&wtrealm=http%3a%2f%2fsharepoint2010%2f"

New-SPTrustedIdentityTokenIssuer -Name "Azure ACS" -Description "Windows Azure ACS v2" -Realm $realm -ImportTrustCertificate $cert -ClaimsMappings $map1 -SignInUrl $signinurl -IdentifierClaim $map1.InputClaimType

New-SPTrustedRootAuthority -Name "Azure Test Token Signing" -Certificate $cert

$issuer = Get-SPTrustedIdentityTokenIssuer
$authority = Get-SPTrustedRootAuthority
$issuer.ProviderUri = $signinurl
$issuer.Update

Check if the things work:

  1. Open central administration and open Web application
  2. Click Create new Web application
  3. Switch to claims authentication
  4. Check the “Azure ACS”
  5. Create new web application
  6. Create new site collection
  7. Set the permissions on the site collection that the users have access to the site collection
  8. Log in with your Google Id to the site collection

References:  Travis Nielsen blog

RunWithElevatedPrivileges throws Access Denied Exception

May 8, 2011

There are more reasons why you can receive this exception. The obvious one is that you use SPContext in the elevated block. For more info see this post . I will  describe a less obvious reason in following article. The RunWithElevatedPrivileges method runs the code under the account of the application pool. In the productive environments has the application pool account only limited privileges. Generally the permissions are so defined that you can do anything you want in the current site however if you try to run e.g following code:

var webApp = SPWebApplication.Lookup(new Uri("http://localhost/sites"));
webApp.Sites.Add("http://localhost/sites/", "user", "email");

you will receive the access denied exception. So how to solve this problem:

  1. Define an account that has only the needed permissions to perform the desired operation. In this specific scenario, you can define a user that has self service site creation permissions and modify the code that it uses self service site creation.
  2. Run the code, that throws exception under the specified account. You can achieve this for example so, that you open the SPSite impersonated. See this.

Creating Loops in SharePoint Designer 2010 Workflows

October 7, 2010

By default SPD 2010 does not allow possible infinite loops to be added to a workflow. Here is the guide how you can do it:

  1. Open SPD 2010
  2. Add a new Workflow
  3. Add new IfElseActivity and fill in the conditions and the actions you want to loop through
  4. Save the workflow
  5. Go to Alle Files -> Workflows -> Your workflow name  folder and open  “your workflow name.xoml” file as xml.
  6. Locate the lines that look like this:

<IfElseActivity x:Name="ID411">

<IfElseBranchActivity x:Name="ID412">

<IfElseBranchActivity.Condition>

<RuleConditionReference ConditionName="__Rule_ID412" />

</IfElseBranchActivity.Condition>

And replace if with something like this:


<WhileActivity x:Name="ID411">

<WhileActivity.Condition>

<RuleConditionReference ConditionName="__Rule_ID412" />

</WhileActivity.Condition>

&nbsp;

Keep in mind that you have to remove also the ending tag of the IfElseBranchActivity.  Keep also in mind that if you have multiple activities in the IfElseActivity taht you have to encapsulate these activities into one single SequenceActivity.

Now you can Publish your workflow back to SharePoint.

One drawback of this approach is that SPD does not support designing of a whileactivity in the worklow designer so you have to change the activities direct in the xoml file or you can replace the whileactivity again with ifelseactivity, do your changes and replace it again.

You have to also modify the web.config of the web app where you want to deploy your workflow because by default is the WhileActivity disabled. Locate following line


<authorizedType Assembly="System.Workflow.Activities, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" Namespace="System.Workflow.*" TypeName="WhileActivity" Authorized="False" />

and set the “Authorized” attribute to True.