Plug In .NET My Services

Add Power to Your ASP.NET Applications

Markus Egger

October 30, 2009

21 Min Read
ITPro Today logo in a gray background | ITPro Today

asp:coverstory

Languages: VB| C#

Technologies: WebServices | XML | .NET My Services

 

Plug In.NET My Services

AddPower to Your ASP.NET Applications

 

By Markus Egger

 

With .NET My Services, Microsoft will introduce its firstserious stab at commercial XML Web Services. The groundwork has been laid, andthe beta SDKs have been published. Microsoft is still working on the deploymentstrategy and has yet to determine who will host the data and service fabric.The core of the infrastructure will remain the same, though, so now's a goodtime to see how you'll be able to use this important technology.

 

The basic idea of .NET My Services (NMS) is fairlystraightforward: Allow users to take widely used features, such as calendarsand address books, online and keep the information in a centralized repository,where it is available to all kinds of applications and devices. For example,most users keep their contact lists in a local database (such as MicrosoftOutlook) or in a semi-central database, such as Exchange Server. Although theExchange Server approach is more flexible than that of the local database, it'sstill an unsatisfactory approach; it's hard to find third-party providers forless-popular server products. On top of that, solutions are often expensive becausethey are proprietary and do not use easy-to-implement APIs, such as a simplestream of XML accessed across HTTP, as would be the case with XML Web Services.

 

The .NET My Services Approach

NMS takes an entirely different approach. All information(as well as the business and application logic that goes with it) is hosted ona server. This is generally known as the NMS service fabric. Applications anddevices that would like to access that information do so using standardizedSimple Object Access Protocol (SOAP) requests. This allows all XML WebService-enabled devices access to the desired information (assuming appropriateauthentication), which makes it easy to use contact lists and other informationeverywhere. Note that connectivity is not required at all times becauseapplications can store information off-line, similar to the way Outlook cachesExchange information off-line today.

 

This is nifty, but not revolutionary ... so far. Of course,it gets better. Imagine you subscribe to a magazine, such as asp.netPRO.The magazine's Web site offers subscription services, so you simply cannavigate to the magazine's URL and enter your information manually. So far, sogood. But what if you move? Well, you would contact Informant Communications(the publisher of asp.netPRO) and request an address change. Thatdoesn't sound so bad, until you realize that you also have to do this with theother 20 magazines to which you subscribe. Then, there's the MSDN subscriptionyou need to update, and you need to tell your cell phone provider and your ISPyou've moved, too.

 

Of course, I wouldn't be going into all this if NMSweren't able to help in this scenario. One of the many services provided - andkeep in mind that there are a large number of services beyond the contacts andcalendar services described in this article - is named .NET My Profile. Thisservice allows you to store information about yourself in the repository, suchas your name, addresses, phone numbers, and e-mail addresses. Of course, youdon't keep this information for your own benefit (unless you are particularlyforgetful). You keep this information to let other people and organizations"subscribe" to it. This way, asp.netPRO can add your profile to themagazine's address book. Of course, this can only happen if you grant access toyour profile. This is known as giving consent. Consent is given on a rathergranular level. Perhaps you want this magazine to have access to your businessaddress, but not your home address or phone numbers. Your friend, on the otherhand, could have access to your business andmobile phone numbers.

 

The beauty of this system is that whenever people readyour information from their list of contacts, they get the most up-to-dateinformation (again, only the part you have consented to release to them). So,your magazine arrives at your new house automatically. In fact, it arrives atthe right address even if you live in different places throughout the year.Your old high-school buddies are able to get a hold of you, as well, becausethey always have the most up-to-date phone number. In fact, a phone numberisn't even necessary. The .NET My Services-enabled phone simply can connect to"Bob" no matter what the appropriate number is.

 

Start Coding

So how do you start preparing your Web site or applicationfor this technology today? The services are not yet available, but a beta SDKis. For the most up-to-date information on the SDK, visit http://www.microsoft.com/MyServices.The SDK installs locally on your development machine or server. To install it,you need SQL Server 2000, which is used to store the information. In addition,all the XML Web Service functionality is installed locally, which requiresInternet Information Server to be installed. This configuration is known as"NMS in a box." Everything runs locally, which means you don't have to connectto a test Web site that provides the service.

 

NMS is a bit more sophisticated than your basic XML WebService. Calls to the service fabric can include complex queries as well as aplethora of information. To accommodate that sophistication, Microsoftintroduces the XML Messaging Interface (XMI). The XMI definition is acombination of data being sent back and forth, such as contact information,calendar items, or entire documents and more; and an XML-based language namedHailStorm Data-manipulation Language (HSDL), which sends instructions to theserver. (HailStorm was the former code name of .NET My Services.) All of thatinformation is combined in a single XML document (separated by namespaces) thatis embedded into a SOAP message.

 

Many NMS acronyms start with the letters HS. It appears tobe safe to assume that HS stands for HailStorm. Therefore, don't be surprisedif these acronyms change.

 

Part of the SOAP message has to be security information.Unless proper authentication is provided, NMS will not grant access to anyinformation. In a production environment, .NET Passport provides securityinformation in the form of Kerberos security tickets. To avoid having to messwith .NET Passport in the development environment, the SDK allows you to useKerberos tickets generated by the local domain or computer. This enables thedeveloper to authenticate using local user accounts, assuming the local systemis provisioned appropriately (see the sidebar "Provisioning theService"). FIGURE 1 provides an overview of the NMSarchitecture.

 


FIGURE 1: .NET My Services is based onstandard SOAP requests made to the service fabric. .NET Passport providessecurity tickets that must be embedded into all requests.

 

A First Request to .NET My Services

You can post a simple request to NMS by composing an HSDLmessage manually. This code represents a simple query request against the MyContacts service:

 

  xmlns:hs="http://schemas.microsoft.com/hs/2001/10/core"

  xmlns:m="http://schemas.microsoft.com/hs/2001/10/

           myContacts">

   

 

The queryRequest tag defines the overall nature ofthe message. The namespace definitions are required because HSDL will beintermingled with the actual data once it is returned (and, for differentmessage types, HSDL will be sent along with the request). Most NMS examples youwill see use the hs namespace for HSDL commands and the mnamespace for the returned data. Note that the hs namespace remains thesame for all HSDL requests, and the m namespace is linked to thenamespace definition for each individual service, such as My Contacts.

 

The actual query is defined in the xpQuery tag. Theletters xp stand for XPath, which should give you an idea of the options youhave in the select attribute. For the developer, an entire NMSrepository appears as one huge XML document that can be queried using XPathpatterns. In the example in the previous code snippet, the query requestagainst the My Contacts service, all myContacts elements stored in theuser's repository are returned. The result set will contain a stream similar tothe one shown in FIGURE 2. (You'll learn about how to post the query to theservice in a bit.) This represents a typical set of tags used by the MyContacts service. Note that many more tags are available but are optional. Fora full specification of the My Contacts schema, consult the SDK documentation.

 

  xmlns:hs="http://schemas.microsoft.com/hs/2001/10/core"

  xmlns:m="http://schemas.microsoft.com/hs/2001/10/

           myContacts"

  xmlns:mp="http://schemas.microsoft.com/hs/2001/10/

            myProfile">

    

      

        

          id="B51F6919-E78F-445B-984C-8BBAD4E28C32">

          

            

            Bill

            

            Gates

            BillG

            

          

          

           id="855AF6CE-9060-4D45-A7D7-97BB1DE4981D">

            

            [email protected]

          

          

           id="97CEEAF3-51BC-41FD-A2A5-F4DE73233D17">

            

            425

            555-5555

          

        

      

    

FIGURE2: An exampleresult set for a query against the .NET My Contacts service.

 

At this point, it is important to realize that the querystatement can be any XPath pattern. For instance, you can query all contactswith the last name of Gates:

 

  xmlns:hs="http://schemas.microsoft.com/hs/2001/10/core"

  xmlns:m="http://schemas.microsoft.com/hs/2001/10/

           myContacts"

  xmlns:mp="http://schemas.microsoft.com/hs/2001/10/

            myProfile">

   

     select=

     "/m:myContacts/m:contact[m:name/mp:surname='Gates']"/>

 

This query uses a second namespace named mp. That'sbecause each name stored in the contacts repository is a profile as you wouldfind it in the My Profile service. Therefore, the myContacts schema uses themyProfile schema for the name information of each contact. To run this query,the namespace must be defined in the query. This type of construct is common in.NET My Services. Another example would be the myCategories schema, which alsois used by My Contacts as well as by other services.

 

You may wonder why the select attribute isn't setin the queryRequest tag but is set in a nested tag instead. The reasonis simple: You can embed as many xpQueries into each query request as you want.Therefore, the query shown here is perfectly valid:

 

  xmlns:hs="http://schemas.microsoft.com/hs/2001/10/core"

  xmlns:m="http://schemas.microsoft.com/hs/2001/10/

           myContacts"

  xmlns:mp="http://schemas.microsoft.com/hs/2001/10/

            myProfile">

   

     select=

     "/m:myContacts/m:contact[m:name/mp:surname='Gates']"/>

   

     select=

     "/m:myContacts/m:contact[m:name/mp:surname='Egger']"/>

 

So how do you send that request to the service fabric?There are several options. You could use a standard SOAP request, perhaps byusing the Microsoft SOAP Toolkit. You also could use some of the proxy objects providedby Visual Studio .NET. Or you can use a command-line utility. Either way, youwill end up with a SOAP request under the hood. Part of the SOAP request has tobe security information. To keep things simple at first, I recommend startingout with the command-line utility (hspost.exe) the SDK provides. It takes careof all the SOAP- and security-related issues, to allow you to focus on NMSfunctionality.

 

Assuming you store one of the previously defined queriesin a file called query.xml, you can post it to the service in the followingfashion:

 

hspost.exe -smyContacts -f query.xml -o Markus

 

Note that you need to provide the name of the service asthe -s parameter - this is case sensitive - as well as a user namethat's provisioned for the My Contacts service (see the sidebar "Provisioningthe Service").

 

Initially, you probably will see an empty result setbecause you won't have any contacts stored in the repository. FIGURE 3 shows aninsertRequest that adds a new contact to your address book. Store thatHSDL command in query.xml and post it to the server in the same manner as youposted the original query. Notice how I mixed HSDL commands together withactual data in FIGURE 3. This demonstrates the importance of using namespaces.

 

Once you have added information to the repository, rerunthe original query to see the new contact stored in your repository. You willnote that the result set is more verbose than the result set shown in FIGURE 2.The reason is that this time, the result set contains SOAP information as wellas information about the query, and whether it was successful (the statusattribute is most important here). FIGURE 3 shows the complete result set,including the SOAP-related tags. Luckily, you don't have to worry about theSOAP information in most cases, assuming you are using ASP.NET and the VS .NETproxy objects (more about this later in the article).

 

            http://schemas.xmlsoap.org/soap/envelope/

 xmlns:hs="http://schemas.microsoft.com/hs/2001/10/core">

  

    

      

      http://schemas.microsoft.com/hs/2001/10/core#response

      

      

      http://localhost

      318DAD61-63BE-11D6-AF2A-0030AB07C808

      318C2631-63BE-11D6-AF2A-0030AB07C808

      

    

    

  

  

    

     xmlns:hs="http://schemas.microsoft.com/hs/2001/10/core"

      xmlns:m="http://schemas.microsoft.com/hs/2001/10/

              myContacts"

     xmlns:mp="http://schemas.microsoft.com/hs/2001/10/

               myProfile">

      

        

          

           id="B51F6919-E78F-445B-984C-8BBAD4E28C32">

            

             id="D9B853E6-1F3D-491B-9C2C-D0088F82EA4E">

              

              Bill

              

              Gates

              

              BillG

              

            

            

             id="855AF6CE-9060-4D45-A7D7-97BB1DE4981D">

              

              [email protected]

            

            

             id="97CEEAF3-51BC-41FD-A2A5-F4DE73233D17">

              

              425

              555-5555

            

          

          

           id="396F7136-875B-4594-B575-296DD411C144">

            

             id="E820C8B3-511E-4E46-BFCB-5378F5268A29">

              

              Mickey

              

              Mouse

              

              Mickey

              

            

            

             id="2E2B7C26-B8BA-481F-9711-DC0164291AE0">

              

               [email protected]

            

          

          

           id="3927C2E7-DA4B-48DB-A56C-7C1E54CCB678">

            

             id="316FBDB0-7CEC-4463-B8B4-B4BD1110AB2C">

              

              Donald

              

              Duck

              

              Donald

              

            

          

        

      

    

  

FIGURE3: This is a fullquery response, including SOAP information.

 

What's Blue and Red and Black AllOver?

In .NET My Services, all data elements (nodes) arecolor-coded. There are blue, red, and black nodes. Blue nodes are elements ofhigh importance - self-contained entities, so to say. Examples of blue nodeswould be myContacts, contact, emailAddress, and name.These nodes can be queried, inserted, updated, and deleted.

 

Red nodes are important, also. But they're notself-contained. A good example would be surname. Although you can queryfor a specific last name, you cannot insert another last name into therepository all by itself - it must be embedded into a contact element,which is a blue node. Similarly, you cannot delete the last-name node withoutdeleting the blue node that contains it.

 

Black nodes are opaque to your queries. You cannot usethem for filtering, and they cannot be inserted or deleted by themselves.However, they still represent significant pieces of information and, in manycases, are required nodes (depending on the schema definition). An example of ablack node is the title tag on the name entity. Although it is returnedwith every request, you couldn't query the repository for a contact with acertain title.

 

If you are using VS .NET proxy objects to access NMS, youhave a proxy object for each blue node at your disposal. There is a myContactsobject as well as a contact and an emailAddress object (amongmany others). Red and black nodes, however, don't have corresponding objects.Instead, they are accessed as properties of the blue-node objects.

 

Create NMS Code in VS .NET

To access .NET My Services from a VS .NET Web application,simply create a new Web application project. As always, you can use the .NETlanguage of your choice for your project. I'm going to start with a VisualBasic .NET example here, and I'll move on to a C# .NET example later in thearticle.

 

The .NET My Services SDK provides two assemblies to beused with VS .NET: ServiceLocator and HSSoapExtensions. Theseassemblies provide wrapper objects as well as extensions to the default SOAPclasses that take care of security issues, such as embedding appropriatelyencrypted user credentials into the SOAP header. To use these assemblies,simply add them to your project by right-clicking the project in the SolutionExplorer and selecting Add Reference.

 

Beyond that, NMS services are references like any otherWeb services. Therefore, you need to add Web references to the services youwould like to use (right-click on the project and select AddWeb Reference). Depending on your setup and whether you work in adevelopment or production environment, the URL for the Web Service DescriptionLanguage (WSDL) file will be something along these lines: http://localhost/wsdl/myContacts.wsdl.

 

Note that by default, the new Web reference will have thename of the server, such as localhost. I recommend renaming the references tosomething more descriptive, such as myContacts. The query request against theMy Contacts service, a code snippet you saw toward the beginning of thearticle, shows the setup of my demo project. The myProfile and myWallet Webreferences have been added, as well, because those are used by the My Contactsservice.

 


FIGURE 4:A sample project with the required local references and Web references.

 

Now that you configured the project appropriately, you areready to access the service. The basic idea is simple: First, create a queryRequestTypeobject and a collection of xpQueryType objects (you will only need one xpQueryTypeobject in this example). This is the VS .NET representation of the queryRequestand xpQuery tags. The select statement can be specified using the selectproperty of the xpQueryType object. Then, the whole query request isposted to the service using the myContacts service object that isgenerated by the ServiceLocator proxy object.

 

The ServiceLocator object is very useful because itcan connect to a dynamically configured service based on the URL passed to theobject's constructor. Note that adding Web references to your project doesn'treally link you to a service on a specific site. VS .NET simply reads the WSDLfile to which it is pointed and creates local proxy objects based on theinformation found in the WSDL file. From that point forward it doesn't really matterwhere the service resides, as long as the WSDL doesn't change.

 

The service locator object also keeps a log of all theinformation retrieved from the service. This is a bit of a trap for ASP.NETdevelopers, though. Generally, ASP.NET will not have access to the specifiedfile, unless you make sure the ASP.NET user account has appropriate accessrights.

 

Once you instantiate the service locator object, you canuse its GetService method to generate a service object of a certain type(myContacts in this example) for a specific user. (In the SDK, this is alocal user name that is provisioned to access the service). Voil ! Now you havethe service object you need to post a request to NMS using the Querymethod. The Query method returns a queryResponseType object,which contains one or more query results. In the current example, you willretrieve one query result, which contains a number of items (contacts). Now allthat's left to do is iterate over all the contacts in the first result set anddisplay the information to the user.

 

FIGURE 5 shows the VB .NET code required to take all thesesteps. You can put this code into an event of your default Web form (such asthe Page_Load event).

 

Dim myCont AsNew myContacts.myContacts()

Dim Contact AsNew myContacts.contactType()

DimqueryResponse As myContacts.queryResponseType

DimqueryRequest As New myContacts.queryRequestType()

Dim xpQuery AsNew myContacts.xpQueryType()

DimxpQueryArray() As myContacts.xpQueryType = {xpQuery}

 

Dim serviceLocator = _

 New Microsoft.Hs.ServiceLocator.ServiceLocator(_

 "http://localhost/myServices","c:\logfile.txt", True)

 

' Replace theuser name with a provisioned name.

myCont =serviceLocator.GetService( _

 GetType(myContacts.myContacts),"markus")

 

xpQuery.select= "/"

queryRequest.xpQuery= xpQueryArray

 

queryResponse =myCont.query(queryRequest)

 

If queryResponse.xpQueryResponse(0).Items(0).contact _

 Is Nothing Then Exit Sub

 

For Each Contact In _

 queryResponse.xpQueryResponse(0).Items(0).contact

  ' Add code to generate output...

  Response.Write("

  • " +Contact.name(0).fileAsName.Value)

    Next

    FIGURE5: Retrieving allcontacts from the repository and displaying the result in a Web form.

     

    In this example, I only use the fileAsName propertyof the first name stored with each contact for display. Of course, you can usemany other properties. Thanks to IntelliSense, it is very easy to find all theavailable properties. Also, keep in mind that all the objects are simplywrapper objects for blue elements defined in the myContacts schema. Red andblack elements of that schema are properties on those objects, so it is veryeasy to relate the schema documentation provided by the SDK to the proxyobjects (that are not documented, so far).

     

    Of course, the output generated by FIGURE 5 is notparticularly pleasing to the eye. Microsoft ships an example with the NMS SDKnamed myContactsUI. The code used to retrieve the list of contacts is basicallyidentical to the code presented in this article, but, because of the talent ofMicrosoft's graphic artists, the result is optically much more impressive.FIGURE 6 shows a screen shot of that example.

     


    FIGURE 6: The list of contacts as it isdisplayed by the myContactsUIexample that is part of the .NET My Services SDK.

     

    The same sample provides a good example of how to insertand update contacts. The basic idea remains the same except that this time, insertRequestType,replaceRequestType, insertResponseType, and replaceResponseTypeobjects are used instead of the query ones. You probably already guessed thatinstead of calling the Query method on the service object, you need touse Insert and Replace. The actual contact information isattached to the request.

     

    The myCalendar Service

    So far, all my examples used the My Contacts service.However, most services work the same way, with the exception of the data format(or schema) of the response. For instance, the My Calendar service storesdifferent information than the My Contacts service, so the data structure willbe very different. However, you will still post insert, update, query, anddelete requests to that service in the same fashion as you post those requeststo the My Contacts service.

     

    Note that some services support additional HSDL commands.A good example is the getFreeBusyDataand getCalendarDays requests the MyCalendar service supports. These types of requests only make sense for thecalendar service. getCalendarDays, for instance, retrieves all eventswithin a certain date range.

     

    To demonstrate the use of the My Calendar service, I'mgoing to walk you through a C# example. First, create a C# ASP.NET application.Add references to the ServiceLocatorand HsSoapExtensions assemblies aswell as a Web reference to the myCalendar WSDL file (http://localhost/wsdl/myCalendar.wsdl).

     

    FIGURE 7 shows the C# code required to query all thecalendar items within a certain date range using the getCalendarDaysRequest object. Note that the code is very similarto the VB .NET version that queries contacts (again, see FIGURE 5). The biggestdifference is that in C#, object types are not automatically typecast as theyare in VB .NET, so they require some manual coding, as you can see in the codethat calls the GetService method onthe service-locator object. Beyond that, the main difference is that the getCalendarDaysRequest object onlysupports one query at a time, which saves you the trouble of having to create acollection of query objects.

     

    //Createinstance of myCalendar service.

    ServiceLocatorserviceLocator = new

     ServiceLocator(SettingSupport.MyServicesUrl,

     "c:\ getCalendarDays.txt", false);

     

    // Replace theuser name with a provisioned one!

    myCalendarmyCal = (myCalendar) serviceLocator.GetService(

        typeof(myCalendar), "markus");

     

    //Create requestelement.

    getCalendarDaysRequestrq = new getCalendarDaysRequest();

     

    //Assign thebounds of the query.

    rq.startTime =new DateTime(2000,01,01);

    rq.endTime =new DateTime(2002,01,01);

    rq.removeRecurrence= false;

     

    //Execute thequery.

    getCalendarDaysResponserp = myCal.getCalendarDays(rq);

     

    //Only iterateif the response includes data.

    if(rp.selectedNodeCount > 0 )

    {

      foreach (getCalendarDaysResponseEventqresponse in

       rp.@event)

      {

        // Display the data...

     

        Response.Write("

  • " + qresponse.body.title.Value +

                    qresponse.body.startTime.ToString() +

            qresponse.body.endTime.ToString());

      }

    }

    FIGURE 7:Querying a range of calendar items from the My Calendar service using C#syntax.

     

    Again, you can put this code into one of the events firedby your default Web form, such as the Page_Load event. Make sure youreference the required assemblies. You can do so by adding the following threelines of code to the very top of the cs file that goes with your default Webform:

     

    using Microsoft.Hs;

    usingMicrosoft.Hs.ServiceLocator;

    using.myCalendar;

     

    .NET My Services provide a very powerful set of featuresimplemented in a centralized fashion. With ASP.NET, these services are verystraightforward to implement. At this point, all that remains to do is wait forMicrosoft to release the service and decide on a deployment method.

     

    The filesreferenced in this article are available for download.

     

    Markus Egger is the president of EPS Software Corp., asoftware development and consulting firm located in Houston, TX. He specializesin consulting for object-oriented development, Internet development, B2B, andWeb Services. Markus is a speaker at industry conferences, and he has writtenarticles for a variety of publications. He is the publisher of ComponentDeveloper Magazine. If you have more questions about .NET My Services, Markuswould be happy to answer your e-mail. You can contact Markus at mailto:[email protected]or visit him online at http://www.eps-software.com.

     

    Provisioning the Service

    .NET My Services is designed to work with .NET Passportauthentication and the Kerberos security tickets that Passport provides.However, this is not required when running the locally installed SDK. In thatcase, you can use local user accounts for authentication, as long as the systemis provisioned for each account and service you would like to use. The SDKprovides a utility named hsprov.exe. With this utility, you can provisionindividual services in the following fashion:

     

    hsprov.exe -lhttp://localhost -o markus -s myContacts

     

    The -l parameter specifies the server name, whichalso can be the local machine name. The -o parameter defines the username. If provided, the defined name has to be a valid user account. If omitted,this defaults to the user that's logged on. The -s parameter defines theservice. You have to provision each service individually. Note that the servicename is case sensitive.

     

    In all the examples provided in this article, you willhave to replace the user name used for authentication (markus) with the username for which you provisioned the system.

     

    The Status of .NET My Services

    Microsoft is currently reconsideringthe architecture of .NET My Services. Originally, Microsoft had planned to hostall the services on its own data center and charge .NET My Service integratorsas well as NMS users (for certain services only). Now, Microsoft has changedthe strategy to let customers install the services on their own data centers.Microsoft still plans to use the services to enrich the company's Web sites,such as msn.com, but the goal to host all the services in a centralized placeseems to have been abandoned.

     

    Some news services also report about a concept calledFederation, which allows individual .NET My Services islands to be linkedtogether and to create the illusion of a centralized repository.

     

    How all of these things will work, we have yet to see.Watch for new Microsoft announcements throughout the next few months.

     

     

     

Read more about:

Microsoft
Sign up for the ITPro Today newsletter
Stay on top of the IT universe with commentary, news analysis, how-to's, and tips delivered to your inbox daily.

You May Also Like