Tuesday, April 21, 2015

SSRS - “The item '.rdl' cannot be found. ---> Microsoft.ReportingServices.Diagnostics.Utilities.ItemNotFoundException: The item '.rsds' cannot be found” in multi server SharePoint farm

I came across above exception when modifying the data source of SSRS reports using reporting services SOAP web service. Following is the detailed exception I received.

“System.ApplicationException: Failure in ActivateFeature for feature “<Feature>” on site: “<Site>” ---> System.Web.Services.Protocols.SoapException: The item 'http://sp13/Reports/TestReport.rdl' cannot be found. ---> Microsoft.ReportingServices.Diagnostics.Utilities.ItemNotFoundException: The item 'http://sp13/Reports/TestReport.rdl' ' cannot be found.   
at System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse(SoapClientMessage message, WebResponse response, Stream responseStream, Boolean asyncCall)”

To resolve the issue I had to follow the steps given below

1. Check if you have installed SSRS Service and Proxy in all SharePoint Servers   

I found out above services were installed only in my application server. So I had to configure it in all WFE servers

  1. Install-SPRSService
  2. Install-SPRSServiceProxy

2. Recreate the SSRS Service application

above actions solved my issue :)

Thursday, April 9, 2015

SSRS - System.Web.Services.Protocols.SoapException: The permissions granted to user 'NT AUTHORITY\ANONYMOUS LOGON' are insufficient for performing this operation. when using ReportingServices2010.asmx in web applications with multiple authentication providers

I came across above exception when accessing SSRS reports using reporting services SOAP web service. Following is the detailed exception I received.

“System.ApplicationException: Failure in ActivateFeature for feature "<Feature>" on site: '<Site>' ---> System.Web.Services.Protocols.SoapException: The permissions granted to user 'NT AUTHORITY\ANONYMOUS LOGON' are insufficient for performing this operation. ---> Microsoft.ReportingServices.Diagnostics.Utilities.AccessDeniedException: The permissions granted to user 'NT AUTHORITY\ANONYMOUS LOGON' are insufficient for performing this operation.
at System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse(SoapClientMessage message, WebResponse response, Stream responseStream, Boolean asyncCall)
at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters)
at Microsoft.SqlServer.ReportingServices2010.ReportingService2010.CreateCatalogItem(String ItemType, String Name, String Parent, Boolean Overwrite, Byte[] Definition, Property[] Properties,”

To resolve the issue I had to include following code segment when calling the web service

  1. ReportingService2010 service = new ReportingService2010();
  2. service.Credentials = CredentialCache.DefaultCredentials;
  3. service.Url = "http://sp13/_vti_bin/ReportServer/ReportService2010.asmx";
  4.  
  5. var authCookie = HttpContext.Current.Request.Cookies["FedAuth"];
  6. if (authCookie != null)
  7. {
  8.   var fedAuth = new Cookie(authCookie.Name, authCookie.Value, authCookie.Path, string.IsNullOrEmpty(authCookie.Domain) ? HttpContext.Current.Request.Url.Host : authCookie.Domain);
  9.   service.CookieContainer = new CookieContainer();
  10.   service.CookieContainer.Add(fedAuth);
  11. }

Friday, April 3, 2015

Deploy Advanced Search Box web part to SharePoint 2013 using module

We use Advanced Search Box to refine our search using keywords, managed properties and result types.This is very useful tool when the SharePoint environment contains a large amount of data.

image

There can be situations where you need to add this web part to custom web part pages programmatically. This task was very easy in SharePoint 2010 environments as this web part (AdvancedSearchBox.dwp) is available in web part gallery. Unfortunately this web part is no longer available in web part gallery in SharePoint 2013.

In this article I’ll show how to make that web part available in web part gallery so you can add it to pages later. Following are the steps I used to deploy the web part to the gallery

1. Navigate to the search center and execute sample query to get Advanced Search option

image

2. Edit the Advanced Search page and edit web part properties if required

image

3. After customizing properties, export the web part

image

4. Navigate to your visual studio solution and add a new Module. Include exported web part in that module

image

5. Modify Elements.xml as below

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  3.   <Module Name="WebParts" Url="_catalogs/wp" RootWebOnly="TRUE">
  4.     <File Path="WebParts\AdvancedSearchBox.dwp" Url="AdvancedSearchBox.dwp" Type="GhostableInLibrary">
  5.       <Property Name="Group" Value="Default Web Parts"></Property>
  6.     </File>
  7.   </Module>
  8. </Elements>

6. Deploy and activate the feature. Now the web part should be available in web part gallery

image

After the web part is deployed to the gallery we can easily add it to pages programmatically by using current page’s Limited Web Part Manager (SPWeb.GetLimitedWebPartManager)

Saturday, March 14, 2015

Create managed properties and map to crawl properties programmatically using a feature

This is the second part of the article series, regarding explicitly creating crawl properties and later map in to managed properties.

In this article I will show how to create managed properties and map to explicitly created crawl properties using a custom feature.

1. Create classes for managed property and crawl property collections

  1. public class CrawlPropertyInfo
  2. {
  3.     public string Category { get; set; }
  4.     public string Name { get; set; }
  5.     public ManagedDataType Type { get; set; }
  6. }
  7.  
  8. public class ManagedPropertyInfo
  9. {
  10.     public string ManagedPropertyName { get; set; }
  11.     public ManagedDataType Type { get; set; }
  12.     public string Description { get; set; }
  13.     public List<CrawlPropertyInfo> CrawledProperties { get; set; }
  14. }

2. Create method to map crawl properties to managed properties

  1. public static void SetManagedPropMappings(List<ManagedPropertyInfo> managedPropertyList)
  2. {
  3. try
  4. {
  5.     SPServiceContext serviceContext =
  6.         SPServiceContext.GetContext
  7.         (SPServiceApplicationProxyGroup.Default, SPSiteSubscriptionIdentifier.Default);
  8.  
  9.     var searchProxy =  serviceContext.GetDefaultProxy(typeof(SearchServiceApplicationProxy))
  10.         as SearchServiceApplicationProxy;    
  11.  
  12.     SearchServiceApplicationInfo info = searchProxy.GetSearchServiceApplicationInfo();
  13.  
  14.     SearchServiceApplication application = SearchService.Service.SearchApplications.
  15.     GetValue<SearchServiceApplication>(info.SearchServiceApplicationId);
  16.  
  17.     SearchObjectOwner searchOwner = new SearchObjectOwner(SearchObjectLevel.Ssa);
  18.     Schema schema = new Schema(application);
  19.  
  20.     ManagedPropertyCollection properties = schema.AllManagedProperties;
  21.  
  22.     foreach (ManagedPropertyInfo managedPropertyInfo in managedPropertyList)
  23.     {
  24.         var prop = from pr in schema.AllManagedProperties
  25.                     where pr.Name == managedPropertyInfo.ManagedPropertyName
  26.                     select pr;
  27.  
  28.         ManagedProperty currentProperty = null;
  29.         //create if managed property is null
  30.         if (null == prop || prop.Count() == 0)
  31.         {
  32.             currentProperty = properties.Create(managedPropertyInfo.ManagedPropertyName, managedPropertyInfo.Type);
  33.         }
  34.  
  35.         foreach (CrawlPropertyInfo crawledProperty in managedPropertyInfo.CrawledProperties)
  36.         {
  37.             List<CrawledPropertyInfo> crawledProperties = application.GetAllCrawledProperties(crawledProperty.Name, crawledProperty.Category, 0, searchOwner);
  38.  
  39.             if (prop != null || prop.Count() > 0)
  40.             {
  41.                 currentProperty = prop.First();
  42.                 CrawledPropertyInfo ci = crawledProperties[0];
  43.                 MappingCollection mpc = currentProperty.GetMappings();
  44.  
  45.                 int i;
  46.                 for (i = mpc.Count - 1; i >= 0; i--)
  47.                 {
  48.                     mpc.RemoveAt(i);
  49.                 }
  50.                 currentProperty.Update();
  51.  
  52.                 Mapping map = new Mapping();
  53.                 map.CrawledPropertyName = ci.Name;
  54.                 map.CrawledPropset = ci.Propset;
  55.                 map.ManagedPid = currentProperty.PID;
  56.                 mpc.Add(map);
  57.                 currentProperty.SetMappings(mpc);
  58.                 currentProperty.Update();
  59.             }
  60.         }
  61.     }
  62. }
  63. catch (Exception ex)
  64. {
  65.     //handle error
  66. }
  67. }

3. From the feature activated in feature receiver, call above method with managed properties

  1. public override void FeatureActivated(SPFeatureReceiverProperties properties)
  2. {
  3.     SPSite site = properties.Feature.Parent as SPSite;
  4.     if (null != site)
  5.     {
  6.         List<ManagedPropertyInfo> managedPropertyList = new List<ManagedPropertyInfo>();
  7.         ManagedPropertyInfo testProperty = new ManagedPropertyInfo
  8.         {
  9.             ManagedPropertyName = "TestManagedProperty",
  10.             Type = ManagedDataType.Text,
  11.             CrawledProperties = new List<CrawlPropertyInfo> {
  12.                     new CrawlPropertyInfo{
  13.                         Name = "ows_TestCrawlProperty",
  14.                         Category = "SharePoint",
  15.                         Type = ManagedDataType.Text
  16.                     }
  17.             }
  18.         };
  19.  
  20.         managedPropertyList.Add(testProperty);
  21.         SetManagedPropMappings(managedPropertyList);
  22.     }
  23. }

4. After activating the feature you can see a managed property is created and mapped to a crawl property

image

Wednesday, March 4, 2015

SharePoint 2013 – Create custom Crawl Properties using PowerShell

Sometimes we need to create, custom site columns and some search related logic which requires above columns as managed properties within the same SharePoint solution (WSP). But as we all aware, following steps need to be done to map site columns to managed properties.
image
How can we do this without full crawl ?

As a solution, I create crawl properties using PowerShell prior to the solution deployment. Using the SharePoint solution I create managed properties and map them to crawl properties. Then after sometime, we can run full crawl to finish the process.

I split the article in to two section, to make it clear.
In this post I’ll discuss about creating Crawl Properties using PowerShell. Following are the steps used to create crawl properties

1. Get value for property set parameter from existing category. In my case I added the property to SharePoint category
  1. $searchapp = Get-SPEnterpriseSearchServiceApplication
  2. $cat = Get-SPEnterpriseSearchMetadataCategory -SearchApplication $searchapp -Identity SharePoint
  3. Get-SPEnterpriseSearchMetadataCrawledProperty -SearchApplication $searchapp -Category $cat -Limit 1

I got “00130329-0000-0130-c000-000000131346” as the result

2. Determine Crawl Property names
If your site column is ClientName, then the Crawl Property name will be ows_ClientName

3. Create Crawl Property using PowerShell
  1. New-SPEnterpriseSearchMetadataCrawledProperty -Category SharePoint -IsNameEnum $false -Name "ows_CustomClientName" -PropSet "00130329-0000-0130-c000-000000131346" -SearchApplication $searchapp -VariantType 72
  2.  
  3. New-SPEnterpriseSearchMetadataCrawledProperty -Category SharePoint -IsNameEnum $false -Name "ows_CustomProperty" -PropSet "00130329-0000-0130-c000-000000131346" -SearchApplication $searchapp -VariantType 72
  4.  
  5. New-SPEnterpriseSearchMetadataCrawledProperty -Category SharePoint -IsNameEnum $false -Name "ows_CustomCountry" -PropSet "00130329-0000-0130-c000-000000131346" -SearchApplication $searchapp -VariantType 72

4. That will create Crawl Properties in Search schema
image

Tuesday, February 17, 2015

Resolve error “The base type <Page> is not allowed for this page. The type <Type> could not be found or it is not registered as safe” when deploying application pages with code behind using a module to SharePoint

When we deploy application pages to SharePoint, sometimes we need to deploy them to libraries or root instead of “Layouts” folder and may be with some code behind. By default SharePoint will issue above error since it violates its derived Code Access Security principles.

image 

In this case we need to explicitly add the safe control entry to web.config file. There can be following concerns.

  • What if there are multiple modules ?
  • What if we need to fully automate the deployment process without anyone manually touching config files ?

Luckily, there is a solution provided by Visual Studio itself. We can add a safe control entry to module by following the steps given below.

1. Right click your module and click Properties

image 

2. Select Safe Control Entries and Expand to add one

image

3. Add new entry and fill content accordingly

image

4. Deploy the package again

Now the page renders as expected.

image

Sunday, February 15, 2015

Presentation–Enhance user experience for Search using display templates

Recently I did a presentation on “Search Display Templates” at Sri Lanka SharePoint forum. In that session I discussed about display templates in general and different customization options.

If you need more information on Display Templates, you can refer these posts I have written so far.Following is the presentation I did