- autocompletedemo

advertisement
Building a SharePoint Service
Application to provide auto-completion
services for AJAX-enabled rich user
controls
Contents
Introduction .................................................................................................................................................. 2
Author’s Notes .............................................................................................................................................. 3
What You’ll Need .......................................................................................................................................... 4
Required .................................................................................................................................................... 4
Optional .................................................................................................................................................... 4
Part One - The Service Application ............................................................................................................... 4
Anatomy of a SharePoint Service Application .......................................................................................... 4
SPService ............................................................................................................................................... 4
SPServiceInstance ................................................................................................................................. 4
SPServiceApplication............................................................................................................................. 5
SPServiceProxy ...................................................................................................................................... 5
SPServiceApplicationProxy.................................................................................................................... 5
Implementing the Service Application .................................................................................................. 6
Part Two – the Service Application’s Admin Interface ............................................................................... 14
The Create and Manage Application Pages ........................................................................................ 14
Part Three – The WCF Service Endpoint ..................................................................................................... 23
Part Four – The User Application Page ....................................................................................................... 24
Download the ASP.NET AJAX Control Toolkit ......................................................................................... 24
Add a New Project and Test Page ........................................................................................................... 25
Bringing It All Together ............................................................................................................................... 28
Introduction
With each new release of SharePoint, Microsoft has managed to further improve this platform’s
programmability, extensibility and manageability. Among many other exciting new features and
capabilities, the new 2010 release of SharePoint now provides developers with ASP.NET AJAX as a firstclass tool in our proverbial toolbox. AJAX has been around for some time now, and it is great to finally
see both native and custom SharePoint applications will be enabled with the same rich, interactive user
controls we’ve come to expect from quality browser-based applications. Yet another exciting
technology that ships with SharePoint 2010 is the Service Application Framework. The Service
Application Framework allows developers to create robust and scalable shared services which can be
consumed by multiple SharePoint web applications.
In this article, I’ll show you how to create and provision a SharePoint Service Application. Within the
service application I’ll define a WCF service endpoint which provides auto-completion services to
ASP.NET AJAX-enabled controls. Finally I’ll leverage this WCF service and the ASP.NET AJAX Toolkit to
provide users with a simple Geo-locator page. The Geo-locator will prompt a user for a city and state,
suggesting known values in real-time as the form’s fields are completed. Once a city and state have
been keyed, the user will be shown the specified location on a satellite map.
Author’s Notes
Admittedly, the use case set forth in this demonstration in somewhat contrived. Using SharePoint’s
Service Application Framework to simply provide AJAX controls with auto-completion services is really
beating a small nail with a big hammer. In most real-world production scenarios, such trivial
functionality could probably be achieved with a simpler site-level web service. I’ve chosen such a simple
use case so as to not distract from the primary purpose of the article, which is to illustrate how to create
and provision the skeleton of a simple SharePoint Service Application.
The topic of SharePoint Service Applications is broad and technically advanced. Areas such as scalability,
fault-tolerance, external service publishing, security, database provisioning and data backup are left for
another demonstration. That being said, in this article I will get you started by showing the basics of
creating, provisioning and hooking into the Central Administration management interface for SharePoint
Service Applications.
This demonstration is accompanied by a complete Visual Studio solution. All code artifacts covered in
this narrative are included in the solution. I will walk you through the process of creating the solution
from scratch. As I add each artifact, I will highlight its salient points, but I will assume you also have the
Visual Studio solution open to view complete code listings. There are a few utility and helper classes in
the project which I don’t cover in this narrative, as I believe these artifacts are self-evident. The Visual
Studio solution is meant to be a starting point for you to create your own SharePoint Service
Applications. I hope you will be able to take the work done here and refactor it to a launching point for
your own real-world use cases.
What You’ll Need
To follow along with this demonstration, I assume you have the following requirements installed and
functioning properly.
Required



SharePoint 2010 – WSS only will do.
Visual Studio 2010
Visual Studio 2010 SharePoint Tools
Optional



WSS 2010 SDK
.NET Reflector
Fiddler
I also assume that you are an intermediate to advanced SharePoint developer familiar with the
SharePoint object model and the latest ASP.NET, Visual Studio and SharePoint development tools.
Part One - The Service Application
In SharePoint 2010, the Service Application Framework provides you with the ability to create hosted,
middle-tier services. These shared services can then provide data or processing resources to other
SharePoint features. Native SharePoint applications such as search and Excel Services are built by using
this platform. The platform is now available in SharePoint 2010 for third parties to also build upon.
Among other things, the Service Application Framework provides:


Built-in support for building applications using the Windows Communications Framework (WCF).
Integration with the standard SharePoint management experience, including Administration and
configuration using SharePoint Central Administration.
Anatomy of a SharePoint Service Application
SPService
A service provides a very narrow range of functionality that usually does not include end-to-end
functions that are valuable in themselves. Services typically run invisibly and have little or no UI.
Every SPService object has an Instances property that holds all the instances of the service that are
running on various servers in the farm. No more than one instance of each service runs on any one
server, but some services have multiple instances, each one running on a different server. Each instance
is represented by an object of a class derived from SPServiceInstance.
SPServiceInstance
SPServiceInstance represents an instance of a service on a server in the farm. A service instance is
independent from, and identical in functionality, to all other server instances of the same type. As long
as one service instance of a given service remains online, the service is fully functional. Service instances
may be in the ‘started’ or ‘stopped’ state. A service instance provides the host process for service
applications.
SPServiceApplication
A service application is hosted by a service instance. Service applications are generally created by
administrators. They provide the service interface, containing the administrator settings. Service
applications may own user data.
SPServiceProxy
A SPServiceProxy is simply the parent of the SPServiceApplicationProxy. It is the equivalent of a
SPService on the server side, which is the parent of a SPServiceApplication. You can also think of these
parent objects as class factories for the child objects, if that makes more sense to you.
SPServiceApplicationProxy
Service application proxies provide the public (front-end) interface to a service application. They allow
client code to consume remote service applications. Service applications may not be installed locally and
therefore cannot be called directly.
Implementing the Service Application
1. In Visual Studio 2010 I start out by creating a new Empty SharePoint project.
2. When prompted by the SharePoint Customization Wizard, I’m going to target the Central
Administration web, as this is where the service application will be deployed. Also in the wizard,
I’ll select the option to Deploy as a full-trust solution.
3. Next, I add a new class to then project and name it AutoCompletionService.cs. As with all code
artifacts in this demonstration, I’ll cover the highlights of this class, but refer to the
accompanying Visual Studio 2010 sample project for the complete listing. The
AutoCompletionService class inherits the SPIisWebService class and implements the
IServiceAdministration interface. Because this class is a persisted object, it must also be
decorated with the System.Runtime.InteropServices.Guid attribute and assigned a unique guid.
4. For serialization purposes, the AutoCompletionService class must have a default, parameter-less
constructor. This class also implements a singleton pattern to provide the means for acquiring
an instance of the local service.
5. I’ll add three more classes to the project. I’m going to name the new classes
AutoCompletionServiceProxy.cs, AutoCompletionServiceApplication.cs and
AutoCompletionServiceApplicationProxy.cs respectively.
6. AutoCompletionServiceApplication inherits from SPIisWebServiceApplication and implements
IFormattable. As a persisted object, the AutoCompletionServiceApplication class must be
decorated with the System.Runtime.InteropServices.Guid attribute and assigned a unique guid.
AutoCompletionServiceApplication overrides the abstract InstallPath and VirutalPath properties
of its parent SPIisWebServiceApplication. AutoCompletionServiceApplication also overrides the
ManageLink virtual property of SPServiceApplication.
7. AutoCompletionServiceApplication needs two methods to both provision and unprovision the
service application and its instance. These methods will be called from the UI when an
administrator creates or tears down a service application instance.
8. AutoCompletionServiceProxy inherits from SPIisWebServiceProxy and implements the
IServiceProxyAdministration interface. IServiceProxyAdministration requires the
GetProxyTypes, GetProxyDescription and CreateProxy methods to be implemented. Also of
note, AutoCompletionServiceProxy is decorated with the SupportedServiceApplication attribute
which tightly couples it to AutoCompletionServiceApplicationProxy. Refer to the accompanying
sample project for the complete class listing.
9. AutoCompletionServiceApplicationProxy inherits from SPIisWebServiceApplicationProxy.
10. Add another class titled AutoCompletionServiceInstance.cs to your Visual Studio 2010 project.
AutoCompletionServiceInstance inherits from SPIisWebServiceInstance. This class overrides the
DisplayName and TypeName properties. Again, refer to the accompanying sample project for
the complete class listing.
11. In SharePoint 2010, WCF web services are stored at the path [14 Hive]\WebServices. On most
systems the full path to this location is C:\Program Files\Common Files\Microsoft Shared\Web
Server Extensions\14\WebServices. In Visual Studio 2010, I’ll create a SharePoint Mapped
Folder to this location by right-clicking on the AutocompleteDemo project in Solution Explorer
and selecting Add > SharePoint Mapped Folder. Note the 14 hive’s WebServices folder at the
bottom of the list.
12. Next, I’m going to expand the newly created WebServices mapped folder and right-click on the
AutocompleteDemo folder below. From the context menu, I select Add > New Item. In the Add
New Item dialog, I select the WCF Service template and name the new file
YouCompleteMeService.cs.
13. I’m going to move the App.config file that was added automatically to be in the same folder as
YouCompleteMeService.cs. Then I rename App.config to web.config and delete its contents.
I’m going to create my own configuration file. In the web.config file I’ll turn on
aspNetCompatibilityEnabled, define a default endpoint for our WCF service, and also turn on
enableWebScript for AJAX compatibility. Refer to the accompanying sample project for the
complete web.config listing.
14. For some reason, Visual Studio 2010 doesn’t automatically add a WCF Service Host declaration
file to the SharePoint Project for me. At least in the VS2010 Beta, I’ll have to add this file
manually. To do so, I just add another file to the AutocompleteDemo folder below WebServices
mapped folder in the project. I select a Text file as the file type and name it
YouCompleteMeService.svc. This Service Host file will only contain a few lines declaring the
service and its factory.
15. I’m going to delete the YouCompleteMeService.cs, as I won’t be using it.
16. Now, I’ll add two more classes named AutoCompletionServiceApplicationHostFactory and
AutoCompletionServiceApplicationHost to the root of the project.
AutoCompletionServiceApplicationHostFactory inherits from ServiceHostFactory and overrides
the CreateServiceHost method.
17. AutoCompletionServiceApplicationHost inherits from System.ServiceModel.ServiceHost and
implements both the IFormattable and IDisposable interfaces.
18. Next, I expand the Features folder of the AutocompleteDemo Visual Studio project and rightclick on Feature1. From the context menu, I click Add Event Receiver. In the newly created
Feature1.EventReceiver.cs class, only the FeatureActivated method is salient to this application.
In the FeatureActivated method, I check to see if an AutoCompletionService object has ever
been created, and if not create it. Only one local AutoCompletionService will ever be needed.
After an AutoCompletionService has been created for the first time, SharePoint’s service
application management will become aware of the new service application and allow
administrators to create or manage instances of the Auto Completion Service Application from
Central Administration. I’ll make the admin pages to create and manage our service application
in Part 2.
Part Two – the Service Application’s Admin Interface
The Create and Manage Application Pages
1. In the project, I’ll add a SharePoint Mapped Folder to the [14 Hive]\TEMPLATE\ADMIN directory.
2. In Solution Explorer, I’m going to expand the newly created ADMIN mapped folder, right-click
the AutocompletionDemo subfolder, and from the context menu Add > New Item. I select a
SharePoint Application Page and name it ServiceCreate.aspx. Then, I repeat the process to add
one more page named ServiceManage.aspx.
3. The ServiceCreate page will be a popup dialog box, and as such should be modified to inherit
from SharePoint’s ~/_layouts/dialog.master master page. This page will implement place
holders for its master page’s PlaceHolderDialogHeaderPageTitle , PlaceHolderDialogDescription
and PlaceHolderDialogBodyMainSection content sections. Refer to the accompanying sample
project for the complete listing.
4. Inside the PlaceHolderDialogBodyMainSection, I add the necessary controls to gather user input
before creating the service application. This page will ask for the service application’s name,
application pool identity, and a check box to set this instance as the default.
5. Inside the ServiceCreate page’s code-behind, within the CreateNewServiceApp method is where
the new Auto Completion service application is actually created. All of the heavy lifting for
creating the service application resides with a SPLongOperation. Refer to the accompanying
sample project for the complete listing.
6. The ServiceManage page is where developer’s are free to add any user configurable settings for
the service application. The Auto Completion service application has no user configurable
options, so this page is largely left blank for the purposes of our demo. Note that this page’s
master page is ~/_admin/admin.master.
7. At this point, the Auto Completion service application can actually be deployed to SharePoint,
and instances of the service application can be provisioned in Central Administration. Of course,
the application doesn’t actually do anything yet, but the core infrastructure pieces have been
defined. To verify this, right-click on the AutocompleteDemo project in Solution Explorer and
select Deploy. The solution will deployed, and after a few seconds, you should see a “Deploy
succeeded” message in the bottom left corner of Visual Studio.
8. To verify deployment, I can open SharePoint’s Central Administration site and click on Manage
service applications under the Application Management menu heading.
9. Selecting any item in the list of services will cause the Service Applications ribbon to appear. I’ll
click the New button to see the Auto Complete Service Application list there. Now I can go
ahead and click it to create a new service application instance.
10. If all is well, I’m presented with a dialog box to create a new Auto Completion service application
instance.
11. Congratulations! If everything works on this next step, most of the hard part is over. I can go
ahead and complete the form by entering an instance name and selecting an application
identity. When finished, I click OK to provision the service application. If the provisioning
succeeded, a pair of listings for the new service application and its proxy should now be
available on the Manage Service Applications Page. I haven’t added any user configuration
options for this demonstration, but clicking the listing’s link to will visit the ServiceManage page.
12. One more step to verify the provisioning was successful is to check that the service application’s
virtual application was created in IIS. To do so, I can open Internet Information Services (IIS)
Manager from Administration Tools on the Start menu of the Windows Server running
SharePoint 2010. Next, I’ll expand the Sites node and then expand the SharePoint Web Services
node below that. I right click on one of the virtual applications below SharePoint Web Services
and select Switch to Content View.
13. I’m looking through the list of virtual applications which have guids for names. Notice
SharePoint’s built-in service applications such as MetadataWebService.svc and
WebAnalyticsService.svc. I’m looking for the virtual application with a guid for a name that that
contains our Service Host file YouCompleteMeService.svc. If everything checks out, the empty
WCF service has been provisioned.
Part Three – The WCF Service Endpoint
1. In this step, I’ll revisit the AutoCompletionServiceApplication class. In order for this class to
provide ASP.NET AJAX auto completion services, I’ll start by decorating it with the
AspNetCompatibilityRequirements attribute.
2. Next, I cause AutoCompletionServiceApplication to implement the IYouCompleteMeService
interface and its required methods. These methods will provide auto-completion data to the
AJAX-enabled input controls I’ll create in the next step.
3. Note that I’ve created a helper class to handle supplying data to the service methods. The
actual data resides in a simple, albeit lengthy text file. CitiesHelper reads said data and
performs simple Linq queries to filter on the correct city and state names. CiteiesHelper uses a
singleton pattern to avoid excessive file I/O and memory usage. In a real-world production
scenario, a more robust SQL database to house this data could have been provisioned along
with the Service Application. However, for the purposes of this demonstration a simple text file
will do fine. Refer to the accompanying project for the complete CitiesHelper code listing.
Part Four – The User Application Page
Download the ASP.NET AJAX Control Toolkit
1. The ASP.NET AJAX Control Toolkit is an open-source project built on top of the Microsoft
ASP.NET AJAX framework. It is a joint effort between Microsoft and the ASP.NET AJAX
community that provides a powerful infrastructure to write reusable, customizable and
extensible ASP.NET AJAX extenders and controls, as well as a rich array of controls that can be
used out of the box to create an interactive Web experience. I’m going to use the toolkit’s
AutoCompleteExtender to transform a plain old SharePoint InputFormTextBox into an AJAX
enabled overnight sensation!
a. I’ll create a folder called Dependencies in the same directory as the Visual Studio
solution file. I’ll need to download the ASP.NET AJAX Control Toolkit binaries from this
URL and add the AjaxControlToolkit.dll to the Dependencies folder.
b. http://www.asp.net/ajax/downloads/
Add a New Project and Test Page
2. In Visual Studio, I’m going to add a new SharePoint Empty Project to the solution and name it
AutoCompletionDemoTest. This time, I’m sure to target a regular SharePoint content
application (not Central Admin as before) from the SharePoint Customization Wizard.
3. I add a reference to the downloaded AjaxControlToolkit.dll from the AutoCompletionDemoTest
project.
4. Next, I add a reference to System.Web.Extensions .NET framework assembly from the
AutoCompletionDemoTest project.
5. I also add a project reference to the AutoCompletionDemo project from the
AutoCompletionDemoTest project.
6. The AutoCompletionDemo project is only going to contain one test page. I’m going to add a
new SharePoint Application page to the project and name it appropriately enough Test.aspx.
7. The main content section of Test.aspx is going to contain a placeholder for the map along with
text input boxes for the user to key-in city and state names.
8. Test.aspx also contains a few Javascript methods to help with retrieving and formatting the map
control based on users’ city and state input.
9. In code-behind file Test.aspx.cs is where I’m going to add control extenders for the page’s two
text input controls. These extenders will handle communicate with the WCF service’s GetStates
and GetCitiesForState web methods to provide suggested auto-completion data.
10. To tie everything together, I’ll also add a GetServicesEndpointPath helper method the test
page’s code-behind. This method will go through the Auto Completion Service Application’s
proxy to determine the default service endpoint.
Bringing It All Together
1. From Visual Studio, I’m going to re-deploy the AutocompleteDemo service application project to
Central Admin to ensure the WCF endpoint’s logic is in place.
2. Next, I’ll deploy the AutocompleteDemoTest test project to a SharePoint content application.
3. To see the end result, I can browse to Test.aspx in my SharePoint Content Application by visiting
the URL:
a. http://[myserver]/_LAYOUTS/AutoCompletionDemoTest/test.aspx
Download