ShareThis

SharePoint Looking for Resource Files in Feature Path Instead of Hive or App_GlobalResources

We were getting series of log entries in the SharePoint log saying “Failed to open the file <Resource file path>” and “Failed to read resource file <Resource file path>”.

We had the correct resource files deployed in <14 hive>\Resources and App_GlobalResources folder of the Web application. But SharePoint was actually looking for the resource files in custom feature folder paths in the 14 hive.

04/23/2013 16:00:21.13 w3wp.exe (0x1120) 0x15B8 SharePoint Foundation          General                        b9y9 High Failed to read resource file "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\Template\Features\DE.Int.Base_GlobalListDefinitions\Resources\Resources.resx" from feature id "9a9dff4b-bf05-7db9-9e10-6ed3cbb5d958". 36db8de3-5278-47ea-ada5-23e50aae5047

04/23/2013   16:13:07.60   w3wp.exe (0x1FA8)   0x1918   SharePoint Foundation   General   b9y3   High   Failed to open the file 'C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\Template\Features\DE.Int. Base_GlobalListDefinitions\Resources\Resources.resx'. 0b97f720-de7b-4fbb-b4d2-65c842184855

Finally it turn out to that we have specified resources for feature titles and descriptions but we haven’t specify the optional "DefaultResourceFile" property of the feature to retrieve Feature XML resources.


Definition for DefaultResourceFile property in MSDN says:
Optional Text. Indicates a common resource file for retrieving Feature XML resources. If you do not specify a resource in the file, SharePoint Foundation looks by default in %ProgramFiles%\Common Files\Microsoft Shared\web server extensions\14\TEMPLATES\FEATURES\FeatureName\Resources\Resources. Culture.resx. However, if you want to provide a shared core resource file for all the Features in your application, you can specify an alternate file through which to access resources by using DefaultResourceFile. For example, if you set DefaultResourceFile="MyFile", SharePoint Foundation looks in %ProgramFiles%\Common Files\Microsoft Shared\web server extensions\14\Resources\MyFile. Culture.resx to retrieve localized resources for your Feature.

So our issue was fixed by specifying the appropriate resource file name in the feature properties.


Overwrite Translations in Default Language from User Specified Text in an Alternate Language

As I blogged in another post, Multilingual User Interface feature (Alternate languages) in SharePoint 2010 allows a logged on user to change the language to one of the supported alternate languages configured by the site administrator.

For an example, in a SharePoint site if alternative languages feature is enabled and let’s say English is set as the default language of the site and Spanish is added as an alternative language. Now if we change the site title using English UI, it won’t affect the Spanish site. But if we want, there is an option in SharePoint to overwrite the site title as well as description in alternate language UIs, from the user specified text in the default language.


However, in a scenario where set of Spanish authors update content in this site, they might want to use the Spanish UI to change the website title in English UI. There is no out of the box option to support this scenario and we will have to write some custom code here.

Option 1: we can add a custom action link in Site Settings page and link to an application page with piece of custom code.
Option 2: With the application page approach, users or administrators have to manually trigger the update when needed. If we want it to work seamlessly, without the need to click another link after changing site title, we can use a timer job to copy the changes.

With either approach following piece of code can be used to copy the site title and description between alternate languages. It basically uses the TitleResource and DescriptionResource properties of the SPWeb object.

private void OverwriteSpanishTranslations()
{
  CultureInfo englishCultuInfo = new CultureInfo(1033);
  CultureInfo spanishEsCultuInfo = new CultureInfo(1034);

  using (SPSite site = new SPSite(SPContext.Current.Site.ID))
  {
    using (SPWeb web = site.OpenWeb(SPContext.Current.Web.ID))
    {
      // Title
      string titleSetInEnglishUI = web.TitleResource.GetValueForUICulture(englishCultuInfo);
      web.TitleResource.SetValueForUICulture(spanishEsCultuInfo, titleSetInEnglishUI);

      // Description
      string descriptionSetInEnglishUI = web.DescriptionResource.GetValueForUICulture(englishCultuInfo);
      web.DescriptionResource.SetValueForUICulture(spanishEsCultuInfo, descriptionSetInEnglishUI);

      web.Update();
    }
  }
}

Custom Action Link in Site Settings – SharePoint 2010

SharePoint does not have an event handler firing on web updates. There are event receivers for WebMoving/ WebMoved, but they won’t fire on events like web title update. Therefore one option to perform some action after updating particular properties in web is to have a custom link in the site settings page of the web.

For example let’s say we want to update the titles for rest of the alternative language sites after changing the title of one of the webs. We can simply have a custom action in the site settings screen.


We can implement the action as clicking on this link will redirect the user to a _Layouts page where we have our custom code implemented to perform the required task.


This custom action can be created using an empty SharePoint element deployed by a feature.


Below is the elements.xml file for the Element. Here “GroupId” specifies the group in site settings page where the link should appear. Here is a list of the default custom action group IDs in MSDN. It is also possible to add a custom group in the site settings page. Here is the CustomActionGroup Element definition in MSDN. “UrlAction Url” specifies the _layouts page consisting of our custom code, while “Rights” specifies the set of rights that the user must have for the link to be visible. If this optional property is not specified, the action always appears in the list of actions.

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">

  <CustomAction
    Id="TitleAlternateLanguages"
    GroupId="Customization"
    Location="Microsoft.SharePoint.SiteSettings"
    Title="Title - Alternate Languages"
    Rights="ManageWeb"
    Sequence="41">
    <UrlAction Url="_layouts/AlternativeLanguages/prjaltlansetng.aspx"/>
  </CustomAction>

</Elements>

Hide Forms Pages from Anonymous Users – SharePoint 2010

When we enable anonymous access in a SharePoint Publishing site, SharePoint Forms pages are also accessible to anonymous users. That means users can browse pages library, content in custom lists, etc. If the website is a public facing site, this might not be the preferred behavior.
 
So one option to prevent anonymous users from accessing these pages is to set permissions accordingly. We can enable/disable anonymous access for individual lists. Here the advantage is we can let certain lists accessible by anonymous users, but on the other hand configuration needs to be done in each list individually.
 
Another option to restrict access to list views is to use out of the box feature called ViewFormsPagesLockdown Feature. View Forms Pages Lockdown Feature is a hidden feature, which if activated removes the View Application Pages permission, and the Use Remote Interfaces permission. The View Application Pages permission is the one that allows anonymous users to access Forms pages. So after activating this feature, when anonymous users try to access form pages by directly typing the URL, they will get Unauthorized Access message.
 
ViewFormPagesLockDown Feature:
 
 
In order to activate “ViewFormPagesLockDown” feature,
 
Enable-SPFeature -Identity 7c637b23-06c4-472d-9a9a-7c175762c5c4 -Url <site URL>
 
Note: If anonymous access was enabled before activating this feature, we need to disable and enable anonymous access again after this feature activation. Anonymous access settings can be changed form _layouts/setanon.aspx page.