How to Allow anonymous access to SharePoint application pages in the _layouts directory

Often times, you need to add your own custom application pages (aspx) to SharePoint, which are deployed to the '_layouts' directory. These types of pages could consist of a custom login page, maintenance pages, or even complete web applications that you'll have live in SharePoint. But what if your web application has an authentication provider set up, such as Claims or Windows? In this article, I'll show you how easy it is to allow anonymous access to these pages without forcing a user to log in.

Create the project

  1. In Visual Studio 2010, create a new "Empty SharePoint Project" and name it "MyAnonymousWebPages".
    Click OK
  2. Enter your SharePoint site
  3. Select "Deploy as a farm solution"

Adding the custom Pages

Next, we need to map the 'layouts' directory to our project, so our files are deployed
there.

  1. Right click on the project name 'MyAnonymousWebPages' > Add > SharePoint "Layouts"
    Mapped Folder
  2. SharePoint will automatically add a folder under 'layouts' with the name of our
    project. Right click on this folder >Add > New Item > Application Page
  3. Name the page "HelloWorld.aspx"
  4. Your project should now look like this:

Allowing anonymous access

So far, we haven't done anything special. The steps we've taken is the basic approach
to adding custom application pages. In the following steps, we will inherit from "UnsecuredLayoutsPageBase". This is a base class for application pages that do not require the user to have any permissions.

  1. Open up HelloWorld.aspx.cs
  2. By default, the page is inherited from "LayoutsPageBase". Change the inheritance
    from "LayoutsPageBase" to "UnsecuredLayoutsPageBase".

    public partial class HelloWorld : UnsecuredLayoutsPageBase
  3. Next, we need to override a property of the UnsecuredLayoutsPageBase, to allow the
    anonymous access. Be sure to change the 'getter' to return true

    protected override bool AllowAnonymousAccess { get { return true; } }
  4. Add some content to your markup in the 'PlaceHolderMain'

Deploy the solution

  1. Right click on your project name, and select 'Deploy'
  2. Once deployment is complete, browse to your page by navigating to
    http://{yourSharePointUrl}/_layouts/MyAnonymousWebPages/HelloWorld.aspx
  3. See your custom page, like below (notice, by default, the ApplicationPage template
    in Visual Studio is designed to automatically inherit from the master page. You
    could instead replace the markup with markup from a standard aspx page template).





How to Rename the SharePoint Search Databases

If you have created the SharePoint Search Service Application using the GUI in SharePoint you have probably noticed that it has added some ugly GUIDs on the end of your database names. In this blog post I will show you how to get rid of them.

Renaming the Crawl Store and Property database will be pretty easy but the Admin database will take a little bit of work.

Renaming the Crawl Store and Property database

1.Open Central Administration and go to manage service applications. Now select your Search Service Application and hit manage.

2.At the bottom of the page and click modify in the Search topology Section.

3.Click on the Edit Properties for the crawl database.

4. On the Edit Crawl Database Screen go to the Database Name Field. Here you can highlight the GUID and delete it off the end of your database then click ok.

5. You can now repeat steps 3 and 4 for the property database.

Renaming the Search Admin Database

If you try to edit the Admin database you will notice that it is greyed out and you can't change it using the GUI. In order to change it we will need to use the SQL Server Managment Studio as well as powershell.

1. Open SQL server managment studio and find your search admin database. If you are not sure which one is your admin database you can find it in the Search Service application at the bottom of the page.

2. Back up the admin Database. You can do this by right clicking on the database selecting tasks then Back Up…

3. Now right click on on the Database folder and select Restore Database.

4. In the restore database window select From Device. Then click the radio button and select the backup of the admin database you just made. Now that you have the backup selected enter the new name you would like for the database in the to database field. Now you can click OK then click OK again at the database restored successfully screen.

5. Now get back on the SharePoint server and open the SharePoint Managment Shell as Administrator.

6. Now enter the following line into the PowerShell to set the identity of your Search Service Application:

$searchssa=Get-SPEnterpriseSearchServiceApplication -identity "Your Search Service Application".

7. Next we will want to pause the Search Service Application before we add the database. We will do this with the following PowerShell command:

$searchssa.Pause()

8. Now we are going to add set our newly named database as the Search Admin database. We will do this with the following PowerShell command:

$searchssa | Set-SPEnterpriseSearchServiceApplication -DatabaseName "Your newly named SharePoint Admin DB" -DatabaseServer "Your SQL Server"

9. Now we will want to resume our Search Service Application. We will do this with the following PowerShell command:

$searchssa.Resume()

10. Now go back to your Search Service Application and check your databases. The GUIDS will all be gone.

11. The database may look like it is no longer in SharePoint but if you run the command you will see that it still is:

get-spdatabase | Select Name, ID

12. Mark the ID for the old database from above then run this PowerShell command:

$olddb=get-spdatabase <ID of old DB>

13. Next we want to delete the old database so we will run the PowerShell command:

$olddb.Delete()

14. Now that we have deleted the old admin database from SharePoint the last step is to delete the old database from SQL. To do this we go into SQL Server Managment Studio right click on the old database and select delete.

15. On the next screen check the close existing connections box then click ok.





How to Migrate All Users From OCS Environment To Lync Server 2010 Pool With One PowerShell Command

Migrate All Users From OCS Environment To Lync Server 2010 Pool With One PowerShell Command

If your organization is undertaking a migration from Microsoft Office Communications Server 2007 R2 to Lync Server 2010, at some point you will be tasked with migrating all existing user accounts (and assoc. contacts / groups) from one platform to another. Below is a PowerShell command (to be executed from the Lync Server Command Shell) that will query for all users hosted on the OCS platform and then move all returned results to the specified Lync Server pool.

Get-CSUser -OnOfficeCommunicationsServer | Move-CSLegacyUser -Target "lyncpool01.microsoft.com"





Things to note when installing Service Pack 1 for SharePoint 2010

Here are a few things to watch out for that I have seen create some major issues when installing Service Pack 1 for SharePoint 2010.


1. Make sure you have all the Service Pack 1 updates you need

When installing Service Pack 1 you need to make sure you have all the right Service Pack 1 upgrades. Unfortunately, Language Packs are all individual and there is a Foundation and a Server for each one.

2. List of the SharePoint 2010 SP1 downloads:

3. Stop the User Profile synchronization service

There have been a lot of issues when installing service pack 1 related to the user profile service. Stop any running synchronizations and stop the user profile synchronization this will help to avoid these errors from happening.

4. Restart your Servers

Make sure that you restart your servers after installing all of the foundation updates and then again after installing the server updates. If you do not restart you servers you can run it to some challenging issues.

5. Cache issues

Sometimes after installing a service pack to a server you will run the configuration wizard and it will give you an error that the service pack is not installed on the server. This issue will persist even after hitting the refresh button on the configuration wizard. To resolve this issue run the powershell command below from the SharePoint Management Console. This will reset the cache file that the configuration wizard is looking to.

Get-spproduct-local

6. The Configuration Wizard Fails

There is a good chance when you are doing the SP1 upgrade that the Configuration Wizard will fail on one of your servers. If it does run the psconfig.exe command (from the 14 hive bin folder) shown below:

.\psconfig.exe –cmd upgrade –inplace b2b –force -wait


 


Enabling Lync Server 2010 for Lync Mobile Clients

As the Lync mobile clients are released so are the server side setup notes. This article will go through the steps for setting up your environment and make it ready for the Lync mobile clients.

Note: This post will be updated as the Lync community get more hands on with the service. Last update 23.12.2011

Lync Mobile features

Lync mobile client is released for Windows Phone 7, iPhone, iPad, Android and later on Nokia (Symbian). The feature set is about the same accross the platforms. There is no ability to view meeting content, video or do voice over IP. The main features is therefore

  • IM and presence
  • One Click join meetings
  • Call via work

For a detailed feature list see the TechNet article: http://technet.microsoft.com/en-us/library/hh691004.aspx

Planning for Lync Mobility

If you have a multi-homed Front End server the Mobility Service (Mcx) may sometimes fail

  • Reason: When calculating routing for a Mobility request the service makes a call to read DNS settings of the registered adapter. In some instances it is possible for the non-registered adapter to be returned.
  • This causes routing of the request to fail This is regardless subnet configuration on the second NIC
  • There should be a forthcoming Release Note or KB Article on this topic

If you use a Director it must be updated the same way as for a Front End

If you plan to support Lync Mobility and Push Notifications over a Wi-Fi you need to

Prerequisites

This Lync Mobility guide requires that your Lync solution is deployed with Lync Edge server and Reverse Proxy. This guide will only talk about Lync Mobility specific configuration

Install CU4 (November release) or later in you Lync infrastructure: http://go.microsoft.com/fwlink/?LinkID=208564.

IIS 7.5 is recommended because of some high load request limitations

If you use Hardware Load Balancer

  • You must ensure that cookie-based persistence on a per port basis for external ports 4443 and 8080 on the hardware load balancer is configured
  • For Lync Server 2010 it is important to use cookie-based persistence so that multiple connections from a single client are sent to one server to maintain session state
  • For details on how to configure, see Load Balancing Requirements.

Install the IIS feature Dynamic Content Compression (Web-Dyn-Compression) on all involved Front End servers

  • Server 2008: ServerManagerCMD.exe –Install Web-Dyn-Compression
  • Server 2008 R2: Import-Module ServerManager; Add-WindowsFeature Web-Dyn-Compression

Enabling Lync Mobility

Configure Lync Mobility Autodiscover CNAME DNS records

  • Internal: lyncdiscoverinternal.sipdomain.com
  • External: lyncdiscover.sipdomain.com
    • Point it to your Reverse Proxy FQDN if using SSL or a new publishing rule and IP if you are using port 80
    • To find you reverse proxy FQDN use this PowerShell oneliner on your Front End server
      • Get-CsService -WebServer | ft ABHandlerExternalUri

Configure listening ports for the Mobility Service (Mcx)

  • Verify that your server version is correct by running PowerShell cmdlet: Get-CsServerVersion
    • Version should be 4.0.7577.0 or newer
  • In PowerShell run the following cmdlet for internal and external listening port
    • Set-CsWebServer –Identity <internal FE Pool FQDN> -McxSipPrimaryListeningPort 5086 -McxSipExternalListeningPort 5087
  • Publish the updates to the CMS database
    • Enable-CsTopology –verbose

Download and enable the Lync Mobility

  • Do not install, but download the McxStandalone.msi and place it in the following folder on all Front End servers and Directors
  • Run the Lync Server Deployment wizard, found under Administrative tools-> Lync Server
    • In the wizard click Install or update Lync Server System
    • Choose Step 2: Setup or Remove Lync Server components
    • This will reconfigure the Lync Services on the Front End with the new listening ports
  • Verify that the server is configured correct, open IIS and check for Autodiscover and Mcx Vdirs

Update certificates on Front End and Edge/TMG

  • Still in the Lync Server Deployment Wizard choose step 3: Request, Install or Assign Certificates
  • You need to request a new certificate with the new name, make sure you get all additional SAN entries from the old certificate
  • If you use the same certificate on all Front End services you can use this PS onliner to get a list of your certificates SAN's
    • On FE: Get-CsCertificate -Type default | Select-Object -ExpandProperty AlternativeNames
  • If you use the same certificate on Edge and TMG you can run the below command to get all SAN's
    • On Edge: Get-CsCertificate -Type DataEdgeExternal | Select-Object -ExpandProperty AlternativeNames
  • To reissue the certificates using PowerShell see Ari Protheroe's blog post: http://ariprotheroe.wordpress.com/2011/12/10/reissuing-certificates-for-lync-mobile/

Configuring Push Notification

  • Push Notification is used by the Mobility Service to send notifications to Apple and Microsoft phones that has the Lync application running in the background to wake them up
  • To enable push notification run the following cmdlet:
    • Set-CsPushNotificationConfiguration -EnableApplePushNotificationService $True -EnableMicrosoftPushNotificationService $True
  • You need to enable federation with Office365 as a hosted provider if you have not already done so
    • New-CsHostingProvider -Identity "LyncOnline" -Enabled $True -ProxyFqdn "sipfed.online.lync.com" -VerificationLevel UseSourceVerification
  • You then need to set up a hosting proivder between your organization and the Push Notification Service at Lync Online
    • New-CsAllowedDomain -Identity "push.lync.com"

Publishing externally

There is two possibilities when publishing Lync Mobility through a reverse proxy

  • Publish through port 80 using the same IP as your existing Lync publishing rule
    • Pros: you don't have to update on your reverse proxy certificate with an extra SAN name
    • Cons: you need to open port 80->8080 on a new rule and it is not recommende to do this by Microsoft
    • Result: discovery information for you Lync mobile clients will get information about logon server unencrypted, the rest is encrypted the usual way
  • Publish through port 443 using the same IP as your existing Lync publishing rule
    • Pros: All traffic will be encrypted, you just need to add lyncdiscover.sipdomain.com to public name on the publishing rule
    • Cons: You need to add an extra SAN name for lyncdiscover.sipdomain.com on your reverse proxy certificate
    • Result: all traffic are encrypted
  • Take a look at Adam Jacobs blogpost at the bottom for how to create a new rule

Testing and Troubleshooting

I have written a blogpost on how to test and troubleshoot Lync Mobile and Mobility here: Lync Server Mobility Troubleshooting Tips: http://msunified.net/2011/12/23/lync-server-mobility-troubleshooting-tips/

How to test the services

You can test that the services are working correct by accessing some URLs

To check that Autodiscover is working as expected, check the Autodiscover urls in a webbrowser

  • Get-CsService -WebServer | fl autodiscover* to find the urls
  • Example: https://<Webservices URL>/autodiscover/autodiscoverservice.svc/root/

To check that the mobility service is working use the following url

  • https://<FE pool FQDN>/mcx/mcxservice.svc

You can test the Push Notificaton Service using the following cmdlet where sip.sipdomain.com is you AccessEdgeFQDN

  • Test-CsFederatedPartner –TargetFqdn <internal edge fqdn> –Domain push.lync.com –ProxyFqdn sipfed.online.lync.com
  • Test-CsMcxPushNotification –AccessEdgeFqdn <internal edge fqdn>
  • NOTE: you may get a 30008 error when running Test-CsMcxPushNotification, but it is working anyway

You can test the Mobility Service using the following script, at this time it does not work with preconfigured CsHealthMonitoringConfiguration

1 $passwd1 = ConvertTo-SecureString "Password01" -AsPlainText -Force $passwd2 = ConvertTo-SecureString "Password02" -AsPlainText -Force
2 $tuc1 = New-Object Management.Automation.PSCredential("contoso\UserName1", $passwd1)
3 $tuc2 = New-Object Management.Automation.PSCredential("contoso\UserName2", $passwd2)
4 Test-CsMcxP2PIM -TargetFqdn pool01.contoso.com -SenderSipAddress sip:UserName1@contoso.com -SenderCredential $tuc1 -ReceiverSipAddress sip:UserName2@contoso.com -ReceiverCredential $tuc2 –v

Monitoring the Mobility Performance

There are several places you can monitor Mobility, here from TechNet:

References

MVP Adam Jacob's blog: http://imaucblog.com/archive/2011/12/09/step-by-step-microsoft-lync-2010-lync-mobility-mcx-installation-guide/
Ben Lee's blog: https://www.bibble-it.com/2011/12/10/configuring-lync-mobility-part-1
MVP Jeff Schertz's blog: http://blog.schertz.name/2011/12/deploying-the-lync-2010-mobility-service/
Lync Server Mobility Troubleshooting Tips: http://msunified.net/2011/12/23/lync-server-mobility-troubleshooting-tips/
Microsoft Lync Server 2010 Mobility Guide: http://www.microsoft.com/download/en/details.aspx?id=28355
Planning for Mobility: http://go.microsoft.com/fwlink/?LinkId=235303
Deploying Mobility: http://go.microsoft.com/fwlink/?LinkId=235304
Monitoring Mobility for Performance: http://go.microsoft.com/fwlink/?LinkId=235305





How to configure Lync Server 2010 features

Now that Lync has gone RTM and Virtual Launch is done we need to get down to business and deploy Lync to the general masses. During the time of Beta, RC and early RTM a lot of great blog articles were published about features and how to configure them. I wanted to collect the posts I find interesting here so I have them all in one place when I deploy Lync Server to my customers. I will update this article with new posts as I find them or when they get published.

Last updated: 16.10.2011





How to resolve the DelayActivity bug in SharePoint 2010 Workflows

I recently came across a problem using DelayActivity objects in custom SharePoint 2010 workflows that I'd like to discuss here, in the hopes of saving others the hours of investigation that I went through to resolve the problem (and to remind myself of the solution if I encounter this problem on a future project).

Using DelayActivity objects is pretty cool, as it allows your custom workflows to delay for a specified period of time before continuing execution. Unfortunately, the problem I was experiencing was that the workflow would never wake up after the DelayActivity.TimeoutDuration value expired.

Searching on the Internet gives a number of posts, with varying suggestions for both SharePoint 2007 and 2010. Since I'm working with SharePoint 2010, I ignored the posts on 2007, and focused on the suggestions for 2010. One of the best ones is here:

http://www.dev4side.com/community/blog/2010/12/1/bug-using-delay-activity-on-sharepoint-2010-workflow.aspx

I followed the instructions to this, and initially it worked just fine. However, as I continued my development I noticed that the problem would reappear, so this made me think that the suggested resolution was not the root cause, and that some other resolution needed to happen to definitively fix this problem.

It turns out that one final step is missing: if you are in the midst of a development cycle (as I was), you must run IISReset and restart the SharePoint Timer Service each time after you redeploy your workflow. Once I realized (and tested) this, my workflow functioned properly.

I hope this helps others when they are using DelayActivity objects in custom workflows.





How to Create Custom Edit Forms with InfoPath in SharePoint 2010

Users have the ability to display and edit properties (known as metadata) for items in SharePoint document libraries and lists. This is standard functionality that comes with SharePoint, and SharePoint provides a standard form when displaying/edit an item.

SharePoint also provides the ability for power users or developers to customize these display/edit forms, using InfoPath. I am going to run through the steps to customize a SharePoint 2010 list, to create a custom display and edit form. I will be using InfoPath 2010 (along with Visual Studio 2010) to demonstrate how you can call a web service method from the custom InfoPath form.

Customizing a SharePoint 2010 List

When you create a list in SharePoint 2010, a standard display/edit form is used, so the first step in customizing a list to use your InfoPath form is to navigate to the SharePoint list, and click on the List tab in the ribbon. This will display ribbon items for the list, and you can click on the Customize Form button, in the Customize List section (Figure 1).

Figure 1: Customize Form ribbon button for a SharePoint list

Once you do this, SharePoint creates a custom template with InfoPath 2010, based on the current columns defined for your list. You can use SharePoint Designer 2010 to verify whether a SharePoint list is using a customized list, as seen in Figure 2 (Figure 3 shows a list that does NOT have a customized InfoPath form):

Figure 2: SharePoint list with a Customized InfoPath 2010 Form

Figure 3: SharePoint list without a Customized InfoPath 2010 Form

When you click the Customize Form button in the ribbon, InfoPath 2010 Designer will open up with the customized form template created for you. At this point, you should make your modifications to the form (we will discuss this in more detail in the next section) and publish the form back to the SharePoint list. One thing to remember is that if you do not publish the form back to the list at this point (you will be prompted if you exit the form), SharePoint will not save the form template as a customized form, meaning your list will continue to use the default form.

For my example list (named TestCustomEditForm), I just published the custom InfoPath 2010 form template back to the list without making any modifications. Once this was completed, clicking on an item in the library displayed my custom form, as seen in Figures 4 and 5. The next section will discuss how to design more advanced changes to the customized form template.

Figure 4: Customized View Item Screen for a SharePoint list

Figure 5: Customized Edit Item Screen for a SharePoint list

Designing a Custom Display/Edit Form with InfoPath 2010

Once you have created a custom form template using InfoPath 2010, there are a lot of options available to you to design the form to your specifications. I am going to show you three things you can do to customize your form template: Adding a custom field that is a lookup to another SharePoint list, creating different views for the Display, Edit and New forms, and calling a web service method to retrieve data in a column when the form loads.

Adding Custom Fields

Adding a custom field is done in InfoPath 2010 Designer, and is very easy to do. Design your form template and in the lower right panel, there is an Actions section. You can click on the Add Field link, and a dialog to add your field information will be displayed (Figure 6).

Figure 6: Adding a Custom Field

Enter your information about the field you are adding, and press OK to add the field. In my example, I am adding a Genre field, which is a lookup to a SharePoint list called Genre. Selecting a value of Lookup (Information in a SharePoint list) in the Data Type entry field will configure the field to be a lookup to a SharePoint list. I also selected Genre from the Get Information From field, which appears after you select the Lookup data type.

After you have entered all the information for your field and clicked OK, the field will appear at the bottom of the Fields section. You can now drag and drop the custom field onto the form design surface, and InfoPath will create the appropriate control for you. In my example, since the Genre field is a lookup to a SharePoint list, InfoPath creates a dropdown control when I drag and drop the field to the design surface (see Figure 7).

Figure 7: Adding a Control for a Custom Field

You can now publish the modified form template to SharePoint, and you will see the Genre column added, as well as the field displayed when viewing/editing an item. Figures 8 and 9 show the list after these changes.

Figure 8: Update SharePoint list with a Custom Column

Figure 9: View Item with a Custom Column

Customizing Different Views

If you need to customize the different views (View/Edit/New Item) for a SharePoint list, you can accomplish that by creating different views in the form template in InfoPath. For my example, I created three (3) views in InfoPath: Display Item, Edit Item and New Item. The only difference between these views is the label for the Title field (of course, in a real-world scenario, your changes would be more extensive).

After these views are created, publish the form back to SharePoint, and in order to "wire up" the different views to the custom pages being used, you need to modify the web part in the different custom forms created (when you originally clicked Customize Form for the list). This is done by clicking on the Modify Form Web Parts (under the Customize List section in the ribbon) to display the different custom forms created (See Figure 10).

Figure 10: Modifying Form Web Parts

The web part properties for each Item form (not the Default forms) needs to be modified to display the proper view. For example, Figure 11 shows the custom form for New Items. Under the Edit tab in the ribbon, select the current view to display that view in the page.

Figure 11: Selecting the View for the Web Part

You also need to modify the web part properties for the web part on the page, as seen in Figure 12. Click on the Options tab in the ribbon (under Web Part Tools), and select the appropriate view you created (from InfoPath), under the Views dropdown. Apply the change and Stop Editing to finish with your changes.

Figure 12: Modifying Web Part Properties for the Web Part

Once you make these changes for each of the views, you can see the changes when you display, edit or create a new item, as shown in Figures 13 and 14. Notice that SharePoint automatically makes the controls read only (or editable), depending on which view is being displayed.

Figure 13: Customized View Item Form

Figure 14: Customized Edit Item Form

Calling a Web Service Method from a Custom Form

Another powerful customization is the ability to call a custom web service method (to retrieve data for a field, for example). Before you can allow your custom InfoPath form to call a web service method, you need to verify the Cross-Domain Access for User Form Templates option is selected (Figure 15). This setting is found in Central Administration, under the Configure InfoPath Forms Services area (look in the General Application Settings section).

Figure 15: Customized Edit Item Form

In order to call a web service method, a data connection must first be configured in the InfoPath form template. Make sure you select a connection to receive data, and select SOAP Web service in the Data Connection Wizard (Figures 16, 17).

Figure 16: Receive Data Connection in Data Connection Wizard

Figure 17: Data Source selection in Data Connection Wizard

To complete the data connection for your web service, enter the URL to the web service and select the web service method you are using. For my example, I'm using a method titled HelloWorld, which takes no input parameters and returns a simple string value.

Once you've created this connection, you need to convert it to use a data connection file (UDCX file). This is needed for security purposes, so that the user is not prompted for credentials. Click on the Convert to Connection File button in the Data Connections window (Figure 18) for your newly-created web service connection. A dialog will appear, prompting for a URL to the data connection file (Figure 19). Enter the path and file name to a data connection file that will be created when you click the OK button. For my example, I created a Data Connection library earlier named DataConnections, and used the URL to that library when creating the UDCX file.

Figure 18: Converting a Data Connection to use a Connection File

Figure 19: Convert Data Connection Dialog

At this point, your web service method is configured for use in the template, so the final step is to wire up the method to a field on the form. For my example, I created another string field (named HelloWorld) and added a text box on the design surface. I then set the default value of the text box to be the string returned from the HelloWorld web service method. This was done by entering the Formula Editor and clicking the Insert Field or Group button to allow selection of the return value from my web service method. Please make sure you select your web service method in the Fields dropdown (it will be marked as a Secondary Data Source), and that you select the appropriate field from the dataFields node in the schema (for my example, the string being returned is title HelloWorldResult, under the HelloWorldResponse node).

Figure 20: Selecting Output from Web Service Method

Click OK to save the changes, save and republish the form template, and when you display/edit an item in the list, your web service method will be called and displayed on the dialog (Figure 21).

Figure 21: Displaying Customized Form with a Web Service call

Moving a Customized Display/Edit Form to Another Environment

So far, we've discussed how to create a customized display/edit form, and I've shown you some powerful customizations you can make to your form. You may be wondering how to deploy this custom form from a development environment to a different environment (staging and/or production). I have found that the process is a bit different than you would expect.

Normally, when InfoPath form templates are created in a development environment, it's a simple matter to "repoint" the publishing URL to your target environment and republish the template. Unfortunately, since this form template is going against a SharePoint list, we do not have access to repoint the publishing URL to a list in the target environment. Due to this limitation, the only way to get your custom form to a different environment is to save your customized list (which will include the form template and any content you might want to include) to a list template. You can then install this list template on your target environment, and create a list in that environment, based on the list template. The only other changes you would need to make is to repoint your web service method call (if you're using one) to the web service in your target environment. You would do this by editing and republishing the InfoPath form template in your target environment.

Conclusion

Customizing the display/edit forms for SharePoint 2010 lists and document libraries is simple and provides a new level of customizing your SharePoint environment. Adding a bit of custom code can take this customization even further, if you need additional functionality not available with just SharePoint lists. I hope this article has helped you understand how to customize the display/edit forms using InfoPath 2010, and if you have any additions, I would love to hear about them.





How to Create and debug a FAST Search for SharePoint pipeline extensibility stage in C# and PowerShell

For my sample extensibility stage I decided to create a module counting the number of words in a document. To count the number of words you have to get hold of the extracted text in the file being indexed.

There is a special crawled property set in FAST for SharePoint only available inside the indexing pipeline. This property set has three fields: a field named "body" which contains the extracted text of the crawled item, the field "data" which is the binary content of the source document in base64 encoding, and "url" which is the link used when displaying results. The sameple stage will make use of the "body" field.​

First I created a new property set to hold the the crawled property I will emit from my program. I could have used one of the existing ones, but I find it easier to have my custom properties in a separate property set for maintenance purposes. I name the property set "mAdcOW" and assign it an arbitrary guid. You can get a GUID in PowerShell with the following command:


 
1 [guid]::NewGuid()

The PowerShell command to create a new property set/category with my random guid looks like this:


 
1 New-FASTSearchMetadataCategory -Name "mAdcOW" -Propset FA585F53-2679-48d9-976D-9CE62E7E19B7

The guid is important as it is later used in the pipeline extensibility configuration. Default, the property set will add newly discovered properties as they are seen during the crawl. This saves us the work of manually creating the crawled properties we are going to be using. In a production environment you would, however, script up the crawled property to avoid the need of crawling before you map the crawled property to a managed one.

For maintainability I create my own folder below the FASTSearch root for my module named C:\FASTSearch\pipelinemodules. Replace C:\FASTSearch with your actual FS4SP location.

Custom stage in C#

Now over to the actual pipeline stage. In Visual Studio create a new Console Application named "WordCount".

2011-04-23-How-to-Create-and-debug-a-FAST-Search-for-SharePoint-pipeline-extensibility-stage-in-C-Sharp-and-Powershell-1.png

In Program.cs I have the following code:


 
01 private static int Main(string[] args)
02 {
03 #if DEBUG
04 Thread.Sleep(1000 * 90);
05

How to Converte a Custom SharePoint 2010 Master Page into a Search Center Master Page

This is a topic that I've been asked probably a hundred times since the SharePoint 2010 bits were released. Before I get into how I solve it, I'll provide a little back story. To quote from my upcoming book, Professional SharePoint 2010 Branding & UI Design:
There are three site templates to choose from when creating search sites in SharePoint 2010: Enterprise Search Center, Basic Search Center, and FAST Search Center. Unlike most other sites in SharePoint 2010, these sites do not have v4.master or even nightandday
.master applied to them; instead, they have minimal.master applied to them. If you have a custom master page that is based on v4.master, nightandday.master, or even one of the typical starter master pages and apply it to one of these search center sites, you notice that the search center doesn't work properly. This is because the page layouts and pages that are created by default for these search center sites are hard coded specifically to work best with the way minimal.master is coded.
In fact, if you apply v4.master to one of the Search Centers, the search box seems to be removed from the page… when actually it is still on the page, just hiding up in the pop-out breadcrumb menu:
image
As you can tell, this is less than ideal. Also problematic is the fact that the default minimal.master that is applied to the search centers doesn't really contain traditional navigation or ways of navigating back to the parent site. So how do you get custom branding to work with the search center in SharePoint 2010? You have some options:
  1. Create a new custom master page based on minimal.master
  2. Adjust the page layouts or pages in the search center, to use the standard content placeholders (UPDATE: Here is a nice sandbox solution to help do this for you. In many cases this might be the best course of action if you are comfortable using 3rd party solutions: http://sp2010searchadapters.codeplex.com/ )
  3. Create a new custom master page with some minor adjustments for the way search centers work
For this post, we will focus on the third option. For simplicity, I will walk you through actually converting v4.master to work for the search centers. This can be useful if you want to show the typical SharePoint2010 navigation and UI that is normally hidden for the search center. The concepts here would work just as well with your own custom master page, in fact I have tried it a couple times with my own. Also, I will assume you understand the basics of working with master pages in SharePoint Designer 2010:
  1. Make a copy of v4.master (or whatever other custom master page you are working with) and give it a new name like v4_searchcenter.master.
  2. Edit the new master page and locate and remove the PlaceHolderTitleBreadcrumb. This will allow the pop-out breadcrumb to still function properly:
    <asp:ContentPlaceHolder id="PlaceHolderTitleBreadcrumb" runat="server">
    <SharePoint:ListSiteMapPath
    runat="server"
    SiteMapProviders="SPSiteMapProvider,SPContentMapProvider"
    RenderCurrentNodeAsLink="false"
    PathSeparator=""
    CssClass="s4-breadcrumb"
    NodeStyle-CssClass="s4-breadcrumbNode"
    CurrentNodeStyle-CssClass="s4-breadcrumbCurrentNode"
    RootNodeStyle-CssClass="s4-breadcrumbRootNode"
    NodeImageOffsetX=0
    NodeImageOffsetY=353
    NodeImageWidth=16
    NodeImageHeight=16
    NodeImageUrl="/_layouts/images/fgimg.png"
    RTLNodeImageOffsetX=0
    RTLNodeImageOffsetY=376
    RTLNodeImageWidth=16
    RTLNodeImageHeight=16
    RTLNodeImageUrl="/_layouts/images/fgimg.png"
    HideInteriorRootNodes="true"
    SkipLinkText="" />
    </asp:ContentPlaceHolder>
  3. Next, add the PlaceHolderTitleBreadcrumb back right before the PlaceHolderMain. This will allow the search center to inject the search box in a good location:
    <asp:ContentPlaceHolder id="PlaceHolderTitleBreadcrumb" runat="server"></asp:ContentPlaceHolder>
    <asp:ContentPlaceHolder id="PlaceHolderMain" runat="server"/>
  4. Move PlaceHolderPageTitleInTitleArea (and any supporting HTML) to a hidden panel because this placeholder isn't used the same way in the search center:
    <asp:ContentPlaceHolder id="PlaceHolderPageTitleInTitleArea" runat="server" />
    <asp:Panel visible="false" runat="server">
    <asp:ContentPlaceHolder id="PlaceHolderPageTitleInTitleArea" runat="server" />
    </asp:Panel>
  5. For v4.master you will also want to remove ClusteredDirectionalSeparatorArrow and <h2></h2>. It won't make sense to show these at the top now:
    <SharePoint:ClusteredDirectionalSeparatorArrow runat="server"/>
    <h2></h2>
  6. Next, several lines of CSS need to be added to make sure things look right for the search center. You can add them to the <head> section of the master page:
    <style type="text/css">
    /* remove left margin */
    .s4-ca {
    margin-left: 0px;
    }
    /* remove gray background at top (optional) */
    .srch-sb-results {
    background:transparent none repeat scroll 0 0;
    }
    /* clean up top padding on 1st search page */
    .srch-sb-main {
    padding-top: 20px;
    }
    /* remove centering on 1st search page (optional) */
    .srch-sb-results4 {
    margin: inherit;
    padding-left: 20px;
    }
    /* remove background color on 1st search page (useful for colored designs) */
    .ms-bodyareaframe {
    background-color: transparent;
    }
    /* ------------------------------------------ */
    /* -- CSS that may be req. to reset the search styling -- */
    /* ------------------------------------------ */
    /* fix height of area above search results */
    td.ms-titleareaframe, div.ms-titleareaframe, .ms-pagetitleareaframe {
    height: auto !important;
    }
    /* fix border color on search results */
    .ms-main .ms-ptabrx, .ms-main .ms-sctabrx, .ms-main .ms-ptabcn, .ms-main .ms-sctabcn {
    border-color: #eeeeee;
    }
    /* fix arrangement of body area on search results */
    .srch-sb-results {
    height: auto;
    }
    /* fix positioning of prefs and advanced link on results */
    .ms-sblink {
    display:block;
    }
    /* fix the color of the prefs and advanced link on results */
    .ms-sblink a:link, .ms-sblink a:visited, .ms-sblink a:hover {
    color:#0072BC;
    }
    </style>
    5. Save the new master page, and check in / publish as a major version and approve it. Apply this master page to only the search center, and apply it as site master page while leaving system master page set as v4.master.

UPDATE: Some commenters have pointed out that if you want to edit pages in the Search Center (and who doesn't?) these changes result in a double ribbon scenario. I haven't fully tested this fix, so I'd be curious to hear about the results, but it looks like this would fix it:

  1. Add <asp:ContentPlaceHolder id="PlaceHolderGlobalNavigation" runat="server"/> to the hidden panel.
  2. Remove <div id="s4-ribboncont">…</div> and ALL of its contents.
  3. Add in its place this line: <asp:ContentPlaceHolder ID="SPNavigation" runat="server"></asp:ContentPlaceHolder>

This should fix the double ribbon issue, but you also LOSE the top popout breadcrumb and the quick edit/save button at the top left of the ribbon.

Here are screenshots of the final result:
image
image
You can employ these same techniques on your own master pages to create search center specific branding.

If you had trouble following the code changes you can download the completed v4 search center master page: v4_SearchCenter.zip