in

SharePoint Blogs

The Best Place for SharePoint-related Blogs

Tommy Segoro

This is Tommy Segoro's blog.
  • CompleteSharepoint.NET - Open Source Content Management System on top of WSS 3.0

    INTRODUCTION

    Hi everyone, I've just written a content management system on top of WSS 3.0. I'm utilising my solution template and I've provided the source code for free. Please go to http://www.completesharepoint.net. I tried to mimic MOSS 2007 functionalities but in their simpler version. It has page editing toolbar, custom page layout, custom publishing content type, etc. Please have a look on the screenshots below:

    Please note that this is still in beta mode. You can download the source code but you will find so many things that can be improved. Thanks everyone I hope to hear some feedback.

     

    Page Editing Toolbar

     

    Editing a Page

     

    Creating a Publishing Page

     

    Custom Site Actions Menu

  • Sharepoint Solution Syntax Part 2

    INTRODUCTION

    Continuing from my previous post http://www.sharepointblogs.com/tommysegoro/archive/2008/09/14/sharepoint-solution-syntax.aspx I will discuss further on the syntax required for creating other elements of Sharepoint. In my previous posting, I've mentioned to you about how to create site definition, master pages, page layouts, content types and fields using feature. In this posting, I will mention about creating web parts, event receivers and feature receivers.

     

    WEB PARTS

    To create web parts you will need the following structure:

     

    Inside HelloWorldWebPart.webpart you have:

    <webParts>
    <
    webPart xmlns="http://schemas.microsoft.com/WebPart/v3">
    <
    metaData>
    <
    type name="WSPBuilder.WebParts.HelloWorldWebPart, WSPBuilder, Version=1.0.0.0, Culture=neutral, PublicKeyToken=6109cdf7233db6c5" />
    <
    importErrorMessage>Cannot import this Web Part.</importErrorMessage>
    </
    metaData>
    <
    data>
    <
    properties>
    <!--
    standard Web Part properties -->
    <
    property name="ChromeType" type="chrometype">Default</property>
    <
    property name="Title" type="string">Hello World Web Part</property>
    <
    property name="Description" type="string">Use to create classic Hello World excitement</property>
    <
    property name="CatalogIconImageUrl" type="string">/_layouts/images/IMAGE.GIF</property>
    </
    properties>
    </
    data>
    </
    webPart>
    </
    webParts>

    Inside Elements.XML:

    <Elements xmlns="http://schemas.microsoft.com/sharepoint/">
    <
    Module Name="WSPBuilderWebParts"
    List="113"
    Url="_catalogs/wp"
    Path="dwp"
    RootWebOnly="true">
    <
    File Url="HelloWorldWebPart.webpart" Type="GhostableInLibrary" >
    <
    Property Name="Group" Value="WSPBuilder Web Parts" />
    </
    File>
    </
    Module>
    </
    Elements>

    Inside Feature.xml:

    <Feature
    Id="8E7D1D5E-4A07-4857-AD5A-EAC3D1A20391"
    Title="WSPBuilder Web Parts"
    Description=""
    Hidden="FALSE"
    Scope="Site"
    xmlns="http://schemas.microsoft.com/sharepoint/">
    <
    ElementManifests>
    <
    ElementManifest Location="elements.xml"/>
    </
    ElementManifests>
    </
    Feature>

     

    FEATURE RECEIVERS

    For feature receivers you will need the following syntax:

     

    Inside Feature.xml:

    <!-- _lcid="1033" _version="12.0.4518" _dal="1" -->
    <!--
    _LocalBinding -->
    <
    Feature Id="6873B8E8-848D-461d-9494-9422E354AE6B"
    Title="Test Site Feature Receiver"
    Description="This is the feature that sets the CompleteSharepoint.NET publishing lists without approval."
    Version="1.0.0.0"
    Scope="Web"
    Hidden="False"
    DefaultResourceFile="core"
    ReceiverAssembly="SPTemplateLand, Version=1.0.0.0, Culture=neutral, PublicKeyToken=a829755eafa973db"
    ReceiverClass="SPTemplateLand.FeatureReceivers.MyFeatureReceiver"
    xmlns="http://schemas.microsoft.com/sharepoint/">
    </
    Feature>

    You will then need to create your feature receiver class.

     

    EVENT RECEIVERS

    With event receiver, you need to have the following syntax:

    The first feature is the feature that deploys your custom list. You can get the syntax from CustomList feature that Microsoft has deployed inside the FEATURE folder of your 12 hive.

    Inside Feature.XML:

    <?xml version="1.0" encoding="utf-8"?>
    <
    Feature Id="EAD2A016-DB17-4f7b-94CE-A3EC6CF5D815"
    Title="My Custom List Feature"
    Description=""
    Version="1.0.0.0"
    Scope="Web"
    DefaultResourceFile="core"
    xmlns="http://schemas.microsoft.com/sharepoint/">
    <ElementManifests>
    <
    ElementManifest Location="CustomList.xml" />
    </
    ElementManifests>
    </
    Feature>

    Inside CustomList.XML (note the Type property):

    <?xml version="1.0" encoding="utf-8"?>
    <
    Elements xmlns="http://schemas.microsoft.com/sharepoint/">
    <
    ListTemplate
    Name="CustomList"
    Type="10050"
    BaseType="0"
    OnQuickLaunch="TRUE"
    SecurityBits="11"
    Sequence="410"
    DisplayName="$Resources:core,custList;"
    Description="$Resources:core,custList_Desc;"
    Image="/_layouts/images/itgen.gif"/>
    </
    Elements>

    The second feature is then the feature that deploys the Event Receiver feature.

    Inside Feature.XML:

    <?xml version="1.0" encoding="utf-8" ?>
    <
    Feature Id="9EF6A5A1-AF0A-494e-BB78-93BA3730E6EC"
    Title="Custom List Event Receiver"
    Description="An Event handler that supports the addition/modification/deletion of list items throughout various sites in the collection."
    Version="1.0.0.0"
    Hidden="FALSE"
    Scope="Web"
    xmlns="http://schemas.microsoft.com/sharepoint/">
    <ElementManifests>
    <
    ElementManifest Location="Elements.xml"/>
    </
    ElementManifests>
    </
    Feature>

    Inside Elements.xml (note the ListTemplateId and the Type property of the event):

    <?xml version="1.0" encoding="utf-8" ?>
    <
    Elements xmlns="http://schemas.microsoft.com/sharepoint/">
    <
    Receivers ListTemplateId="10050">
    <Receiver>
    <
    Name>SPTemplateLandEventReceivers</Name>
    <
    Type>ItemDeleted</Type>
    <
    SequenceNumber>10000</SequenceNumber>
    <
    Assembly>SPTemplateLand, Version=1.0.0.0, Culture=neutral, PublicKeyToken=3ea47656c35c3a98</Assembly>
    <
    Class>SPTemplateLand.EventReceivers.CustomListEventReceiver</Class>
    <
    Data></Data>
    <
    Filter></Filter>
    </
    Receiver>
    <
    Receiver>
    <
    Name>SPTemplateLandEventReceivers</Name>
    <
    Type>ItemUpdated</Type>
    <
    SequenceNumber>10000</SequenceNumber>
    <
    Assembly>SPTemplateLand, Version=1.0.0.0, Culture=neutral, PublicKeyToken=3ea47656c35c3a98</Assembly>
    <
    Class>SPTemplateLand.EventReceivers.CustomListEventReceiver</Class>
    <
    Data></Data>
    <
    Filter></Filter>
    </
    Receiver>
    <
    Receiver>
    <
    Name>SPTemplateLandEventReceivers</Name>
    <
    Type>ItemAdded</Type>
    <
    SequenceNumber>10000</SequenceNumber>
    <
    Assembly>SPTemplateLand, Version=1.0.0.0, Culture=neutral, PublicKeyToken=3ea47656c35c3a98</Assembly>
    <
    Class>SPTemplateLand.EventReceivers.CustomListEventReceiver</Class>
    <
    Data></Data>
    <
    Filter></Filter>
    </
    Receiver>
    </
    Receivers>
    </
    Elements>

    You will then need to build your custom event receiver class that inherits from SPItemEventReceiver.

     

    CONCLUSION

    So there you go. Hope this helps. To be continued.

  • Sharepoint Team Development with Visual Studio 2005 2008 Part 4

    INTRODUCTION

    Hello hello...I've said in my last post http://www.sharepointblogs.com/tommysegoro/archive/2008/09/25/sharepoint-team-development-with-visual-studio-part-3.aspx that that post was going to be the last post in this series. But I actually lied!

    In this post I will focus more on the tools. I've played around with another 2 tools: SPTemplateLand and WSPBuilder and in this post I will list the advantages and disadvantages of using both tools (once again these are only based from my experience). So please agree/disagree with me. Thanks.

     

    TOOLS AND MORE TOOLS

    I just tried 2 new tools for generating features and solutions for me: SPTemplateLand (http://www.codeplex.com/sptemplateland) and WSPBuilder (http://www.codeplex.com/wspbuilder). Both are excellent tools to generate the solution file automatically.

    I will start with SPTemplateLand first.

     

    SPTEMPLATELAND (http://www.codeplex.com/sptemplateland)

    Advantages:
    - Generation of the WSP file automatically.
    - Simple yet fulfilling the purpose.
    - Not relying on any executables for it to run.
    - Easy to modify for any projects.
    - Deploy files to the correct location.

    Disadvantages:
    - No Visual Studio built-in commands.
    - You have to have at least one feature definition in your project otherwise the manifest.xml will not render correctly and you won't be able to add your solution to Sharepoint using the STSADM command.
    - If you want to deploy your DLL to GAC, you have to copy it manually inside the DLL folder.
    - No batch scripts by default so you have to remember the STSADM syntax for installing, deploying and upgrading the solution.
    - Key.snk is not part of the solution so you have to create and sign your assembly manually.
    - No reference to Microsoft.Sharepoint and System.Web automatically. You have to add them manually.

    In general, I like this solution template as it's very simple and yet fulfilling its purpose to generate and deploy WSP automatically. Things that I mention in the Disadvantages section are not really major. They of course will be improved in future versions hopefully.

     

    WSPBUILDER (http://www.codeplex.com/wspbuilder)

    Advantages:
    - Built-in Visual Studio project template. It's very nice to have a project which namespace and assembly names have been automatically-generated based on the project name.
    - Yet still quiet simple to use.
    - Deploy files correctly to the correct location.
    - Key for signing your assembly is now part of your project.

    Disadvantages:
    - Relying on the executable.
    - No Visual Studio built-in commands.
    - Config file may be confusing. There are so many options that you can enable/disable and the documentation is rather not clear. 
    - Doesn't have any batch scripts so you have to remember the STSADM commands for installing, deploying and upgrading your solution. You may also need to add your WSPBuilder.exe to the PATH environment variables so you can run it from anywhere within your folder.
    - No reference to Microsoft.Sharepoint and System.Web automatically. You have to add them manually.

     

    CONCLUSION

    So there are just some of my findings with those tools. I've got nothing to against any of these tools. If they've been working for you then please keep using them. I kept saying this over and over again, it doesn't matter what tools you use as long as they can help you deploying your solutions and features automatically.

    I've also created my own please go to http://www.codeplex.com/vs2008sp which is kinda similar with the tools I've mentioned above except it has built-in Visual Studio build commands.

     

  • Custom Document Library using List Definition Schema.XML Version Not Appearing on Office Documents

    Do you know that the "URL" property of the Schema.XML on your custom list definition can make the version selection in your Office applications disappearing when you're trying to check-in your document?

    OOTB it should be:

     

    But an incorrect URL property in the SCHEMA.XML will cause it to look like below:

     

     

    The version selection somehow disappears!

    So what's the problem? The problem is this:

    <List Name="My Custom Documents" Title="My Custom Documents" Description="" Direction="0" BaseType="1" Url="Lists/MyCustomDocuments" .........

    You can NOT have the word "Lists" in the URL.

    Same with your list instance in your Elements.XML (if you deploy your custom list using feature):

    <ListInstance FeatureId="6E99D423-7EB9-4FD3-9654-DAC0B96C1827"
    Title="My Custom Documents"
    TemplateType="101"
    Url="Lists/MyCustomDocuments" />

     

    Remove the word "Lists" from the URL so it becomes:

    <ListInstance FeatureId="6E99D423-7EB9-4FD3-9654-DAC0B96C1827"
    Title="My Custom Documents"
    TemplateType="101"
    Url="MyCustomDocuments" />

     

    Fiuh...I spent hours trying to fix this.

    Hope this helps.

    Tommy Segoro

  • Sharepoint Team Development with Visual Studio 2005 2008 Part 3

    This is the third and last part of Sharepoint Development using Visual Studio series. For previous part:
    http://www.sharepointblogs.com/tommysegoro/archive/2008/09/04/sharepoint-team-development-with-visual-studio-part-2.aspx

    Note: Just change the part-x bit to go to the other series of this posting. 

     

    INTRODUCTION

    I've shared to you about the different Sharepoint project types, the development methodology approach and the tools. In this particular posting I will share to you on how to plan your Sharepoint development. I've talked a bit about this in my previous posting about how you should plan your content types and fields first. Sure, requirements change but at least you reduce your "headache" if you can get as much content types and fields done as possible. In this particular posting I will share to you on how I normally approach the site creation, the implementation of features, etc.

     

    THE TOOLS

    Once again I will repeat this over and over again: You HAVE TO utilise solution and features deployment for team development. Please find on my previous post regarding the tools I've used. Anyway, I will use my own solution template for creating solutions and features on my examples/projects. Please download from http://www.codeplex.com/vs2008sp.

     

    SITE CREATION

    Personally I will go down the custom site definition path. I will not modify OOTB site definition (eg. modifying STS's ONET.XML directly) because when you start modifying OOTB files, they may get overridden by service packs or patches that Microsoft releases. With custom site definition, too you can select what features to be activated upon creating a new site, what files to appear, etc which makes sense for me.

    My fellow Sharepoint developer mentioned to me before that he prefers to use PowerShell to activate the features because he can see whether feature activation succeeds or not rather than you create your site first then getting an error message. If any of you uses PowerShell to create your site/activate your features, can you please share your experience? Anyway, I personally will go down the custom site definition path because it's easier for me to categorise which site will use what features, which site use what pages, what lists to instanstiate, etc. See example below of my custom ONET.XML:

    <Configuration ID="1" Name="Blank">
    <
    Lists>
    <
    List FeatureId="00BFEA71-2062-426C-90BF-714C59600103" Type="103" Title="Page Order" Url="Lists/Page Order" />
    </
    Lists>

    <Modules>
    <
    Module Name="DefaultBlank" />
    </
    Modules>

    <SiteFeatures>
    <!--
    BasicWebParts Feature -->
    <
    Feature ID="00BFEA71-1C5E-4A24-B310-BA51C3EB7A57" />
    <!--
    Three-state Workflow Feature -->
    <
    Feature ID="FDE5D850-671E-4143-950A-87B473922DC7" />
    </
    SiteFeatures>

    <WebFeatures>

    <!-- CUSTOM FEATURE -->
    <!--
    SITE ACTIONS -->
    <
    Feature ID="69CCBDEB-6B71-4fb6-9A2E-93EBB8D792D8" />

    <!-- PUBLISHING LISTS CREATION -->
    <
    Feature ID="67A06416-3D36-44c9-8980-F10FA0181B27" />

    <!-- SET PUBLISHING LIST WITHOUT APPROVAL -->
    <
    Feature ID="6873B8E8-848D-461d-9494-9422E354AE6B" />
    <!--
    MASTER PAGES -->
    <
    Feature ID="5522E091-66EA-40e8-9C62-D08861A96225" />
    <!--
    MODIFY NAVIGATION -->
    <
    Feature ID="2F74B5BA-BDA9-435d-84DC-DF3CA1E741A2" />

    <
    Feature ID="00BFEA71-4EA5-48D4-A4AD-7EA5C011ABE5" />
    <!--
    TeamCollab Feature -->
    <
    Feature ID="F41CC668-37E5-4743-B4A8-74D1DB3FD8A4" />
    <!--
    MobilityRedirect --> <!-- CUSTOM FEATURES -->
    <!--
    Content Type Binding -->
    <
    Feature ID="678C0C06-1053-455b-8767-867B6B37EA75" />
    </
    WebFeatures>
    </
    Configuration>

    Therefore, when I need to create a particular site that will require particular features to be activated, I can easily go to Site Actions -> Create Site and create a site that uses my custom site definition and it will then have the correct activated features.

    For creating custom site definition I always start from the OOTB ones. To create WSS-related site definitions, start from STS. For Collaboration Portal starts from SPS and for MOSS Publishing starts from BLANKINTERNET.

     

    THE PROJECT

    I personally will divide the project into 3 sub-projects:
    - Features
    - UI
    - DLL

    The Features project will contain feature-related stuff (except features that deploy UI such as master pages, CSS, page layouts and javascripts). So in this project you will have features that contain feature receivers, features that deploy web parts, features that deploy content types and columns, etc.

    The UI project will contain UI-related stuff such as feature that deploys master pages and page layouts, feature that deploys images, CSS and javascripts.

    The DLL project contains all code-behind related stuff (feature receivers, event receivers, custom fields, user controls, web-part code, etc). Why I divide the code into a separate project? It's because when you're deploying the DLL it won't affect the other elements (eg. Features and UI). The other elements will still run as normal yet you can deploy as many changes to your code as possible.

     

    UI ELEMENTS

    I will deploy CSS and images that are related to the UI directly on file system using feature. I will not upload images that are related to UI to Sharepoint image library. The reason is, when it comes to updating them, it's very-very easy and quick to re-deploy a new set of CSS, javascripts or images to a file system rather than uploading those files to Sharepoint.

    For master pages and page layouts, I will also move away from using Sharepoint Designer and I will NOT un-ghost them. Updating them will be very easy and they can be source controlled using TFS/VSS if you're not using Sharepoint Designer to update them. When you want to update them, you can just re-deploy your UI project and it will upgrade all of your master pages and page layouts in the file system.

     

    CUSTOM PAGES FOR DISPLAYING NON-SHAREPOINT INFORMATION

    Let's say you need to display information from your MS CRM but in the context of Sharepoint (and inheriting the Sharepoint permission for viewing that page, etc), I will personally go down the custom page layout (or application page path). This way you can then code your page to use Sharepoint permission. In your Sharepoint custom page you can then have user controls that will display information from MS CRM.

    Example: http://myintranet/Pages/ViewCustomer.aspx or http://myintranet/_layouts/ViewAdmin.aspx.

     

    TESTING

    Various testings can also be executed on a Sharepoint application (same as usual custom applications). With unit testing however, you will need to have Sharepoint installed on your machine because stuff like retrieving list item from a list, etc will require you to connect to a Sharepoint list. When I divide my projects into those 3 categories, I can easily test the DLL project without even deploying my UI and my Features (although I will need to have the actual list to be created on my Sharepoint site if I need to retrieve items from it).

     

    DEVELOPMENT PROCESS

    The development process can be the same per general custom application development. With those 3 sub-projects I have, I can check-in check-out files/features/user controls/master pages, etc and my fellow developers can then get latest and run Install/Upgrade and he will suddenly have the latest files on his Sharepoint site. That's the beauty of solution and feature deployment. It allows you to do team development.

     

    BUILD and UAT PROCESS

    The build and UAT process can also be the same as per general custom application development. I can use TFS (or other tool) to build my 3 sub-projects, deploy the features/solutions to the Test server then I can run Install/Upgrade script. The Sharepoint site on the Test server will then have the latest features and files installed.

     

    CONCLUSION

    So this will be the end of the team development series hope that you enjoy reading them and please share your experience. The team development process may take more time than just modifying things directly through the Sharepoint GUI but it's worth it. It will make your code maintenance a lot easier, it also allows you to perform code review (making sure that everyone is on the same page in terms of writing feature, code and solutions) and updating/upgrading your files will be a lot easier.

    To download sample code please go to http://www.smallbusinesshosting.com.au/SampleProject.zip.

    Cheers.

  • Sharepoint Timer Service Crashes Fix

    INTRODUCTION

    I'm currently working at a client where they haven't got SP1 installed and the environment hasn't been setup correctly. Somehow this service crashes all the time.

     

    THE WORK AROUND

    The work around to this problem is for me to create a batch script which I then call through Windows Scheduled Task. I schedule the WST to run this script every 10 minutes.

    The content of the script is very-very little:

    net start "Windows Sharepoint Services Timer"

    That's it! At least the timer service has been running stable because every time it crashes, it's automatically started by the script.

     

    Hope this helps,
    Tommy 

     

     

  • MOSS BDC, Search and Web Service: Modifying Search Results Web-Part

    INTRODUCTION

    This post is related to my other post regarding securing search results for currently-logged-in user in Sharepoint when querying BDC Web Service entity:
    http://www.sharepointblogs.com/tommysegoro/archive/2008/09/17/moss-bdc-search-and-web-service-securing-the-search-results-for-particular-user.aspx

    I'm now interested in how I can modify the search results web-part to display the actual entity name. OOTB it will give you EntityType.aspx. So if your entity type is called FileEntity the search results web-part will render FileEntity.aspx everywhere! I want to render Filename1.aspx, Filename2.aspx, etc.

    OOTB:

     

    THE SOLUTION

    1. Add a meta-data property mapping in SSP. Let's give it a name: TommyFilename and add mapping to the BDC crawled property. 

    2. Edit the Search Core Results Web-Part -> Results Query Options -> Selected Columns. Add your custom managed-property in here.

    <root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">    <Columns>        <Column Name="TommyFilename"/><Column Name="WorkId"/>        <Column Name="Rank"/>        <Column Name="Title"/>        <Column Name="Author"/>        <Column Name="Size"/>        <Column Name="Path"/>        <Column Name="Description"/>        <Column Name="Write"/>        <Column Name="SiteName"/>        <Column Name="CollapsingStatus"/>        <Column Name="HitHighlightedSummary"/>        <Column Name="HitHighlightedProperties"/>        <Column Name="ContentClass"/>        <Column Name="IsDocument"/>        <Column Name="PictureThumbnailURL"/>    </Columns>    </root>   

    3. Edit the Search Core Results Web-Part XSL under Data View Properties. Go to around line 111:

    OOTB:
      <span class="srch-Title">
       <a href="{$url}" id="{concat('CSR_',$id)}" title="{$url}">
        <xsl:choose>
         <xsl:when test="hithighlightedproperties/HHTitle[. != '']">
             <xsl:call-template name="HitHighlighting">
              <xsl:with-param name="hh" select="hithighlightedproperties/HHTitle" />
             </xsl:call-template>  
         </xsl:when>
         <xsl:otherwise><xsl:value-of select="title"/></xsl:otherwise>
        </xsl:choose>
       </a>
        <br/>
       </span>

    Modify that to:
      <span class="srch-Title">
       <a href="{$url}" id="{concat('CSR_',$id)}" title="{$url}">
        <xsl:choose>
         <xsl:when test="tommyfilename[. != '']">
             <xsl:value-of select="tommyfilename"/>
         </xsl:when>
         <xsl:otherwise><xsl:value-of select="title"/></xsl:otherwise>
        </xsl:choose>
       </a>
        <br/>
       </span>

    NOTE: The property name HAS TO BE LOWER CASE! Remember we named it TommyFilename before, didn't we? It won't work if you use TommyFilename but it will work if you use tommyfilename.

    That's it! You can then see below:

     

    APPENDIX

    To check what XML it returns, edit that XSL Data-View Properties again and replace the content with:

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="
    http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:template match="/">
    <xsl:copy-of select="*"/>
    </xsl:template>
    </xsl:stylesheet>

    Save the web-part then view HTML Source of the page then you can see something like below:

    <All_Results>
      <Result>
        <id>1</id>
        <tommyfilename>charlie_and_the_chocolate_factory_06.jpg</tommyfilename>
        <workid>5</workid>
        <rank>819</rank>
        <title>FileEntity.aspx</title>
        <author></author>
        <size>0</size>

    ...................

    The custom property is actually recognized using ALL lower case naming convention. That is why TommyFilename will not work.

     

    Hope this helps,
    Tommy

  • MOSS BDC, Search and Web Service: Securing the Search Results for Particular User

    INTRODUCTION

    MOSS BDC is an excellent offering from Microsoft. It allows you to pull data from external sources and bring the meta-data into MOSS which can then be indexed in Search. I have no problem in setting up User Profiles, OOTB MOSS Search, NTFS Search, etc but I'm very-very interested in setting up BDC with Web Service. MOSS has already had capability to securing search results on file system and Exchange public folder search but what about web service? What about if I want to search my custom CRM using PHP and I want to filter the security based on the user who performs the search? How do we do that?

    In this post I will share with you what I've done. The example I posted is searching file system using web service but you can modify the code easily to accomodate your needs.

     

    KNOWLEDGE LEVEL

    This article is quiet advanced. You have to understand how BDC works (the use of Entity, Finder, etc).

     

    THE STEPS

    1. Define your Entity. Entity is an object which BDC can understand. BDC can't understand your PHP CRM but it can understand BDC Entity if you wrap your PHP CRM into an Entity. For example:

    [Serializable]
    public class FileEntity
    {
    public FileEntity(){} public FileEntity(string name, string filename, DateTime dateCreated, DateTime dateLastUpdated)
    {
    this.name = name;
    this.filename = filename;
    this.dateCreated = dateCreated;
    this.dateLastUpdated = dateLastUpdated;
    }

    private string name;
    private string filename;
    private DateTime dateCreated;
    private DateTime dateLastUpdated;

    public string Name
    {
    get { return this.name; }
    set { this.name = value; }
    }

    public string Filename
    {
    get { return this.filename; }
    set { this.filename = value; }
    }

    public DateTime DateCreated
    {
    get { return this.dateCreated; }
    set { this.dateCreated = value; }
    }
    public DateTime DateLastUpdated
    {
    get { return this.dateLastUpdated; }
    set { this.dateLastUpdated = value; }
    }

    }

    Step 2. Use Microsoft's BDC Editor to create your BDC Definition .XML file.
    I will not explain how to use the tool in this blog. Please read the documentation. I've supplied with an XML file resulting from that tool so you can modify yourself.

    Step 3a. Define the methods for each finder in your web service.
    Step 3b. Define your Finder.
    Finder is the method that is used by Search to retrieve search results for your entity. There are some finders that are used:
    - Finder: To retrieve ALL entities. Used by search results.
    - SpecificFinder: To retrieve a particular entity. Used when you click on a search result and that link will bring you a specific Entity details.
    - IdEnumerator: Enumerate the ID of each Entity. Each entity must be identified by an ID and this method will collect the IDs.
    - AccessChecker: This is the method that is called by the search results whether an Entity can be accessed or not by a particular user. If user doesn't have access to a particular entity, that entity won't be displayed in the search results.

    It will be clearer if you download the source code. Open the XML and the web service project then you will know how to assign web service method to a finder.

    And this is how the AccessChecker is configured as web method:

    [WebMethod]
    public System.Int64 CheckAccess(string name, string username)
    {
    IMPLEMENT YOUR SECURITY CHECK HERE!

    if (username.ToLower().Contains("sharepoint"))
    return 0; --> RETURN 0 MEANS THE USER DOESN'T HAVE ACCESS

    return 1; --> RETURN 1 MEANS THE USER HAS ACCESS

    }

    The username input variable will be populated by the current logged in user in Sharepoint.

    In BDC XML please have a look below:

    - <Method Name="CheckAccess"> -->> The Web service method name as above
    - <FilterDescriptors>
      <FilterDescriptor Name="fd" Type="UserContext" /> --->> Return current logged in user in Sharepoint
      </FilterDescriptors>
    - <Parameters>
    - <Parameter Direction="In" Name="name">
      <TypeDescriptor TypeName="System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" IdentifierName="name" Name="name" />
      </Parameter>
    - <Parameter Name="username" Direction="In">
      <TypeDescriptor Name="username" TypeName="System.String" AssociatedFilter="fd" />  -->> Pass logged in user to username variable of the method
      </Parameter>
    - <Parameter Name="out" Direction="Return">
      <TypeDescriptor Name="out" TypeName="System.Int64" />
      </Parameter>
      </Parameters>
    - <MethodInstances>
      <MethodInstance Name="CheckAccess" Type="AccessChecker" ReturnParameterName="out" />
      </MethodInstances>
      </Method>
      </Methods> 

    Step 4. Create a crawl rule with the following settings:

    - Path: bdc2//*
    - Include all items in path, Crawl complex URLs

    Step 5. Register security trimmer.

    stsadm -o registersecuritytrimmer -ssp "MOSS SSP" -id 0 -typename "Microsoft.Office.Server.ApplicationRegistry.Search.QueryProcessorSe