Skip to main content
 
Go Search
Home
Categories
Bloggers
By: Matt Morse | Posted: October 21, 2009 at 12:57 AM

I’m attending the Microsoft SharePoint Conference 2009 in Las Vegas where Microsoft has just taken the wraps off of SharePoint 2010. Since it’s a new product release and Microsoft has done a pretty good job of keeping the lid on the functionality in the new product until now, there’s a very high level of excitement and interest.

The individual breakout sessions have generally been good. I plan to write about a number of topics going forward (as I’m sure many other folks do, as well), but here are a couple of random notes that I’ve jotted down so far.

  • Microsoft announced its intent to support CMIS as part of SharePoint 2010. Specifically, this promises simpler interoperability with other ECM systems (MS mentioned EMC’s Documentum and IBM’s FileNet by name), which is good news for enterprises with heterogeneous content systems. The demonstration showed a screenshot of a SharePoint “document library” that was actually surfacing information coming from a FileNet repository. There have been solutions for this type of interop in the past that are product-specific, but not anything standards-based or built directly into the product. Microsoft is clearly trying to carve out a larger niche for itself in the ECM world.
  • A new concept of “service applications” replaces the shared services model that is used on MOSS 2007. (Andrew Connell has a good write-up on the details here; so does a MS team from the UK.) This architectural shift opens up a number of new topological options in SharePoint farm design, as an architect can decide on a service-by-service basis what should be shared between web applications or farms. For example, two farms might want to share the same user profile service, but have different search providers. In MOSS, you’d have to configure user profile replication between two separate SSPs; in 2010, it will be possible to simply have the farms share a user profile service application and have separate search service apps.
  • One more item on service applications: Microsoft has made the service application a point of extensibility (which it really wasn’t in 2007). And it’s even available in SharePoint Foundation (the new name of Windows SharePoint Services – the version of SharePoint licensed with Windows Server).
  • A couple of small (but key, in my opinion) updates to SharePoint web content management (publishing) capabilities:
    • Font lockout – Almost everyone who is first introduced to the WCM features of MOSS 2007 asks this question when they see the rich text editor for page content: “Can I keep users from changing the fonts/sizes/colors?” And now in SharePoint 2010, the answer to that is “yes.” It’s possible to restrict the ability for that type of formatting – and not only that, but it’s possible to predefine styles that may be used by content authors. It’s a small feature, but one that will go a long way for making organizations feel more comfortable with a delegated authoring environment.
    • CQWP dynamic filtering – Many WCM sites in SharePoint have “landing pages” that aggregate content of a specific type or category using the CQWP (or a variation of the CQWP). (An example of this is on the PointBridge web site: look at the SharePoint solution page there and you’ll see that there’s a blog post, a person, and a case study all related to our SharePoint practice; visit the Exchange solution page and you’ll see those page areas change to match the change in solution area.) In MOSS, you configure these types of pages by creating a page layout with a web part zone, creating a page using that page layout, then dropping a CQWP into the zone and configuring it to roll up the appropriate content based on the desired context.

      In  SharePoint 2010, the CQWP can be configured to be filtered by a dynamic token that can read a page field value from the page – meaning that the CQWP can even be integrated into the page layout itself and eliminate the need for having to manually create those rollups each time.
By: Matt Morse | Posted: May 6, 2009 at 8:45 AM

If you’ve been developing with SharePoint (or .NET web apps) for awhile, you’re likely aware that it’s generally a good practice to deploy custom code to the BIN directory of the web application and explicitly specify the least set of permissions required to execute the code contained in your assembly. (If you’re interested, here’s a write-up with a link to a slide deck covering this topic in more detail.)

On a recent project, I created a SharePoint application page to be hosted in the layouts directory. The page class inherited from LayoutsPageBase, and the ASPX file was set to inherit from this class/assembly. Pretty straightforward.

As noted above, I wanted to deploy this assembly to the application BIN directory (not GAC) and use a CAS permission policy to allow it to execute within SharePoint. However, when I did that and tried to browse to the page, I got this exception:

Request failed. at System.Reflection.Assembly._GetType(String name, Boolean throwOnError, Boolean ignoreCase) at System.Web.UI.TemplateParser.GetType(String typeName, Boolean ignoreCase, Boolean throwOnError) at System.Web.UI.TemplateParser.ProcessInheritsAttribute(String baseTypeName, String codeFileBaseTypeName, String src, Assembly assembly) at System.Web.UI.TemplateParser.PostProcessMainDirectiveAttributes(IDictionary parseData)

In most other cases in which I've gotten permissions errors in the past, the exception has indicated which specific permission I was missing (e.g. SqlClientPermission or FileIOPermission – which is very helpful, as you then know what to fix), but I knew that the issue was security-related, as it worked fine if I deployed to the GAC.

After some head-banging, I started Reflector and took a look at the LayoutsPageBase class (which I should have done much sooner…). The issue was immediately apparent:

   1: [PermissionSet(SecurityAction.InheritanceDemand, Name="FullTrust"), PermissionSet(SecurityAction.LinkDemand, Name="FullTrust")]
   2: public class LayoutsPageBase : UnsecuredLayoutsPageBase

Note the security attributes on the class. This post has a nice write-up on the specifics of InheritanceDemand and LinkDemand if you’re interested, but the upshot is that you can’t directly call into this class nor inherit from it and call inherited methods without having full trust. A step up the inheritance hierarchy to UnsecuredLayoutsPageBase shows the same attributes there, too.

So here’s the point of this post: you can’t create application pages that inherit from LayoutsPageBase (or UnsecuredLayoutsPageBase) if you want your code to run without full trust.

As I see it, here are the options:

  1. Deploy to the GAC. The is the easy way out, but for my project (which runs in a shared environment) was not option.
  2. Deploy to the _app_bin directory. SharePoint ships with a policy file that grants code in the _app_bin directory full trust. Perhaps an option, but it kind of defeats the purpose of CAS, doesn’t it? The point is that I don’t want my code to run fully trusted.
  3. Inherit from System.Web.UI.Page and manage security yourself. This was the option I chose in the end. You can inherit from the standard ASP.NET page class, but you may simply have to do some of the security things that the layouts base classes were doing for you. For example, the LayoutsPageBase class has a Boolean property called RequireSiteAdministrator, which, if true, ensures that the executing user has site collection admin rights in order to view the page. You can do this type of check yourself; it just takes a little more work. When inheriting from Page, you simply need to ensure that you add the AspNetHostingPermission (with a “Minimal” level) to your CAS declaration and deployment to the BIN with a custom CAS policy works fine.
By: Matt Morse | Posted: April 16, 2009 at 7:23 AM

Most organizations that use MOSS make use of SharePoint search in one form or another, but I’ve seen few that really get their dollar’s worth out of SharePoint’s search capability. The most common configuration that I’ve personally observed is the one that SharePoint configures automatically: all SharePoint sites are included in a single content source, and some kind of straightforward indexing schedule gets applied to make it “just work.”

And it does “just work.” The out-of-the-box relevancy engine is pretty good.

But it can be much, much better. Enter the role of the business search administrator. Burt touched on this idea in his blog a few weeks ago, and I’d like to expound a little.

First, I say business search administrator because I think many organizations think of search administration as a primarily technical role and approach it as such from a staffing perspective. (There is certainly a technical component to administering SharePoint’s search, but that’s not the subject of this particular post.) Because of the divide between business and IT in many companies, this means that search may be measured based on availability, its impact on system resources, and breadth of content sources rather than by the relevance of its results or its value to business users.

Here are some ways I think a business search administrator (BSA) can help increase the value that an organization gets out of SharePoint search.

  • Understand search. Maybe this one’s obvious, but the BSA needs to know something about how search works. They don’t need to know all the technical details, but a working understanding of content sources, scopes, crawl rules and schedules, and the basics of how SharePoint’s search relevancy works are good starting points.
  • Authoritative pages and demoted sites. Once the BSA understands some of how SharePoint calculates search relevance, he or she can start adding authoritative pages and demoted sites. Each search result is given a rank at index time based on its “click distance” from an authoritative page. The demoted site list (called non-authoritative pages in the administration pages) allows the BSA to manually decrease the relevance of specific content.
  • Managed properties. Creating a managed property in search enables a number of additional capabilities beyond the standard full text indexing (including property-based advanced searches). But even without leveraging those additional features, managed properties are considered more relevant than unmanaged ones by SharePoint’s relevancy calculation. For example, if you associate documents with vendors and capture the vendor name in a piece of metadata, you can make that a managed property such that when you search on the vendor name, the relevance of those documents with that vendor's name associated will be higher.
  • Scope definitions. Search scopes allow different views on the SharePoint search index based on specific inclusion and exclusion rules. For example, you can create a scope that restricts results for a search only to certain financial documents (based on your own criteria). When a user is looking for a specific financial document and searches using that scope, he or she won’t have to dig through extraneous documents from HR looking for the right file. Determination of what scopes should be created and the rules that define those scopes is a critical differentiator between a run-of-the-mill search implementation and an excellent one.
  • Thesaurus and noise word maintenance. SharePoint ships with a standard thesaurus and noise word file: it knows the basics of the language and does an adequate job of equating similar concepts and filtering out common or less meaningful words. What it doesn’t know is the details of your business. There’s no way for SharePoint to know that what you refer to as “WCI” is really the same as “Widget Capacity Index,” and that “widget” is what you call it now, but last year you called it a “whutsit.” And then there’s noise: if all your documents have your company name in them, maybe that’s really just “noise” when it comes to search.
  • Keywords/best bets. While keywords don’t impact the relevancy of the search ranking itself (see note in Brian Wilson’s blog), they do affect user perception of the relevance and freshness of the search results. In addition, while many of the settings mentioned here are common to the SharePoint farm or SSP, keywords are stored at a site collection level. This means that the keywords and best bets can be different by site collection and can return information targeted by the business purpose of each site collection. For example, you might specify a different best bet when someone searches on the words “group policy” in your HR site collection than when they search within your IT site collection.
  • Search usage analysis. Finally, search can improve with age – in fact, it can improve a lot if there’s an administrator paying close attention to the search usage information that SharePoint provides. What terms are users using to search? And what are they expecting to find when they search on those terms? What queries are not bringing back any results at all? What scopes are users using and not using? Armed with this information, the BSA can make calculated changes to authoritative pages, managed properties, thesaurus, keywords, etc. to improve the search experience. Careful usage analysis is the most critical ongoing responsibility of the BSA role.

So to the original point: why make this a business role? Because it’s likely that someone in the business knows best when content is stale or irrelevant and should be demoted. Someone in the business is often best suited to know which page(s) link to the most relevant and timely content and should be listed as authoritative. Someone in the business best knows the way users think about information and the scopes that would support that thinking. Someone in the business understands the relevant keywords, their synonyms, and the page or site to which users should be directed when search for specific items. There’s technical competence required, but to my eye, it’s a business-focused job.

See if you can take your own search installation to the next level. Try implementing this role and see how the value of your investment in SharePoint search grows over time.

By: Matt Morse | Posted: April 6, 2009 at 12:25 AM

This is a quick post with a message that may seem obvious, but I’ve seen plenty of code that makes me think maybe it isn’t. So here’s my suggestion: store your application configuration such that it matches the scope of your SharePoint feature.

To elaborate, I’ve mentioned before that SharePoint developers who come from a custom .NET development background are generally inclined to put application configuration settings in the web.config – which works fine for some things. However, what if you have a setting that needs to differ by site collection and you have many site collections in your web application? You could certainly create a site collection-specific AppSettings key for each site collection in your web.config, but that seems messy to me.

Here are my suggestions for where you should think about storing your configuration information, based on the scope of your feature:

Feature Scope Configuration
Farm
  • SPConfigStore
Web Application
  • SPConfigStore
  • web.config
Site Collection (SPSite)
  • SPConfigStore
  • List in root web of site collection
  • Properties collection on root web
Site (SPWeb)
  • SPConfigStore
  • List in web
  • Properties collection on web

The references to SPConfigStore here refer to this CodePlex project submitted by Chris O’Brien. Note that items in the store are grouped by “Category,” so use of the SPConfigStore approach requires some thought about naming conventions and how the categories will be assigned.

The code below shows an example of the use of the Properties collection on an SPWeb:

   1: /// <summary>
   2: /// Returns a property value stored in an <see cref="SPWeb" /> instance
   3: /// </summary>
   4: /// <param name="web"></param>
   5: /// <param name="name">the name of the property to retrieve</param>
   6: /// <returns>the value for the property; empty string if property doesn't exist</returns>
   7: private static string GetWebSetting(SPWeb web, string name)
   8: {
   9:     if (web.Properties.ContainsKey(name))
  10:     {
  11:         return (string)web.Properties[name];
  12:     }
  13:     else
  14:     {
  15:         return string.Empty;
  16:     }
  17: }

Next time you fill out the “Scope” attribute of your feature.xml, make sure your plan for configuration management matches your application.

By: Matt Morse | Posted: April 5, 2009 at 11:43 PM

Creating custom timer jobs within SharePoint enables a SharePoint developer to add a scheduled component to a SharePoint application. (Looking to get started with timer jobs? Andrew Connell has a good write-up on MSDN.)

On a recent project, I created a couple of custom timer jobs and ran into some interesting behavior related to the job locking that I don’t think is documented very well at the moment.

When you create a custom timer job, you inherit from SPJobDefinition. A couple of the constructors for the job allows you to specify a value for the lock type used by the job. This value is set as an enum of type SPJobLockType.

The MSDN documentation details the available values for the SPJobLockType enum as follows:

ContentDatabase Locks the content database before processing. 
Job Locks the job to prevent it from running on more than one machine. 
None No locks.


These values work about as you’d expect (if you can tell what to expect from the descriptions) for single WFE farms.

However, for farms with multiple WFEs, I think this information is sketchy at best and inaccurate at worst. Here’s how I’d modify the documentation based on my own experience:

ContentDatabase Locks the content database before processing. If more than one WFE is part of the farm, only schedules the job to be executed on a single WFE. If that WFE is removed from the farm, the job is not scheduled on any other WFE automatically, so the job will no longer be executed until 1) the WFE is added back to the farm or 2) the feature that registered the job is deactivated and reactivated.
Job Locks the job to prevent multiple instances from running on the same machine. Job will be scheduled on every WFE in the farm and execute on all of them. (Note that this is quite different from the MSDN description; Andrew Connell’s article alludes to this same definition I’ve given.)
None No locks. Job will be scheduled on every WFE in the farm and execute on all of them without checking for running instances.

 

I think you’ll find it a challenge if your desire is to have design in which the job is managed by the farm in such a way that it executes from only one machine and will be fault-tolerant such that if one WFE is not in the farm, it will simply execute on another WFE. It appears to me that the only option for accomplishing this scenario is to use the “Job” or “None” lock types. This schedules the timer job to execute on each WFE server. You can then implement custom communication between WFEs (via the database, remoting, or some other method) to have the WFEs determine that only one of them will execute at any one time. It’s not a great solution – and it’s one that feels like it should have been done already as part of the SharePoint farm infrastructure – but it’s functional.

 


 About Matt Morse

Practice Manager - SharePointMatt Morse is a practice manager for PointBridge. He has over 10 years of experience in application architecture and development, working in a variety of industries, including banking, manufacturing, ... [more]

 Tag Cloud

 My Articles

 ‭(Hidden)‬ Admin Links