Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Consuming .NET My Services from Managed C++

0.00/5 (No votes)
4 Feb 2002 1  
This white paper guides you through the process of writing a client application that will consume a sample .NET My Services service

Introduction

As part of the Microsoft� .NET initiative, Microsoft is introducing a user-centric architecture and set of XML Web services, named .NET My Services (formerly codenamed "HailStorm.") Building upon the capabilities of Microsoft .NET Alerts and Microsoft .NET Passport, .NET My Services is a family of XML Web services that, when available in 2002, will allow users to securely store and control access to personal information.�The .NET My Services platform is a collection of XML Web services that are invoked over the Internet by means of industry-standard protocols including SOAP, XML, and Universal Description, Discovery, and Integration (UDDI). .NET My Services authenticates users, provides the ability to send alerts, and stores personal information, including contacts, e-mail, calendar, profile, lists, electronic wallet, physical location, document stores, application settings, favorite Web sites, devices owned, and preferences for receiving alerts.

This white paper guides you through the process of writing a client application that will consume a sample .NET My Services service.� The client will be written using Managed C++, Visual Studio .NET, and the .NET My Services SDK. There are additional steps that the user will have to take when, compared to a Visual C# or a Visual Basic client application. This white paper assumes you are familiar with the Visual Studio XML Web Services model for creating and consuming generic web services from client applications. (See Visual Studio .NET documentation for Creating and Accessing XML Web Services using Managed Extensions for C++, Visual Basic or Visual C#)

As a way to encourage developers to start developing applications that will use these services, Microsoft released at the Professional Developers Conference in October 2001 the .NET My Services SDK � This contains sample services as well as 2 open source projects that allow Visual Studio to integrate with Hailstorm services.� These open source projects are written in Visual C# and provide additional functionality to Visual Studio so users can seamlessly deal with the specific characteristics of .Net My Services described below.

First, it is important to understand that .NET My Services uses a central meta-service named .NET Services. This service brokers the interactions between clients and the other .NET Services such as .NET Contacts or .NET Wallet. The centralized .NET Services also manages the provisioning of other services on behalf of users and conveys the location of other services to clients at run time. So a client application must negotiate a transaction with the central .NET My Services before addressing a specific requested service like .NET Contacts or .NET Wallet.

.NET My Services also uses the Kerberos authentication protocol and encrypts all SOAP packets in order to ensure the security of user's private data. This means that all client applications must provide the functionality to request Kerberos authentication tickets and present those in all SOAP requests. Also, the client must encrypt SOAP requests and decrypt SOAP responses.

All of the technologies used in the .NET My Services service locator and encryption are based on open standards and are documented so .NET My Services developers are free to develop their own application layers to handle these features. However, .NET My Services SDK contains two shared source projects that will address these issues. For Visual C# and for Visual Basic, the user only needs to include references to these projects in their client applications in order to take advantage of their functionality that will essentially allow the developer to code for .NET My Services as if they were any other Web Service.

We will provide the additional steps needed to workaround some limitations of the Add Web Reference dialog for Managed C++ client applications that consume web services using strongly typed datasets. In future releases of Visual Studio .NET these additional steps will not be necessary. �

First we need to build the HsSoapExtension solution provided in the SDK to obtain HsSoapExtension.dll. We will need this later

  1. Create a new MC++ Application project and call it MyServiceClient.

  2. At the command line, navigate to the MyServiceClient� project directory and run the following command:
  3. disco http://localhost/WSDL/myFavouriteWebSites.wsdl.

    This command downloads soaprp.xsd, myFavouritewebsites.wsdl and generates results.discomap. The resulting.discomap file describes the dependencies between the wsdl and the xsd files. We now have to add these files to the project.

  4. In Visual Studio, right click on the Project node, select the Add menu item and then the �Add Existing item� subitem. You can browse to the location of your project and select the 3 files previously created in that location: �soaprp.xsd, myFavouritewebsites.wsdl and results.discomap. This will add the 3 files to your project. See figure below.
  5. Right click on the results.discomap file, select Properties, and change the �Tool� option value to �Web Service Proxy Generator�.

  6. Right click on theresults.discomap file, select Properties, and change the �Tool� option value to �Custom Build Tool�.

  7. Copy the previously built HsSoapExtension.dll from the .NET My Services SDK solution folder �to your project�s source folder.

  8. Add /reference:HsSoapExtension.dll to the csc.rsp file located in %SystemRoot%\ Microsoft.NET\Framework\v1.0.xxxx�where xxxx is the version of the .NET Framework.

  9. Build the solution. This will cause the C# proxy class to be generated for the web service: results.cs, that will in turn be built into results.dll. Note: For Managed C++ applications, all proxy classes are generated in C#, regardless of whether they are for �.NET My Services or other web services.

To actually use the .NET My FavoriteWebSites service we have to perform just one more step:

In the MyServicesClient.cpp file add the following lines:

 #using <HsSoapExtension.dll>
 #using <references.dll>

Now everything is set up to call the actual My Service service. The following sample client code shows how to add a web site to your Favorite Web Sites, query for it and delete it. You can find the complete solution at the link mentioned in the beginning of this document.

Sample client code:

int _tmain(void)
{
    Microsoft::Hs::ServiceLocator::ServiceLocator* serviceLocator = 
               new Microsoft::Hs::ServiceLocator::ServiceLocator("http://localhost/myServices">http://localhost/myServices", 

                                                                 "c:\\logfile.txt", true);
    try
    {
        //

        // Use the service locator to find and initialize the myFavoriteWebSites service / proxy

        //

        // TODO: if you are querying for a different user, specify the username instead 

        // of calling User.GetCurrentUser()

        // NOTE: User.GetCurrentUser will not work inside an ASP.NET application

        //

       
        myFavoriteWebSites* myFav = dynamic_cast<myFavoriteWebSites*> 
             (serviceLocator->GetService(System::Type::GetType("myFavoriteWebSites"), 
                                                               User::GetCurrentUser()));
           
        //

        // create a new favoriteWebSite

        //

        favoriteWebSiteType* newWebsite = new favoriteWebSiteType();
        localizableString* title = new localizableString();
        title->lang = S"en";
        title->Value = S"Hello.NET";
        newWebsite->title = new localizableString*[1];
            newWebsite->title[0] =title;
        newWebsite->url = S"http://www.microsoft.com";
        catType* cat = new catType();
        cat->ref = S"system";
        newWebsite->cat = new catType*[1];
            newWebsite->cat[0] = cat;
        //

        // create an insertRequest and call insert

        //

        insertRequestType* insertRequest = new insertRequestType();
        insertRequest->select=S"/"; //we're going to insert into the root of the service

        insertRequest->Items = new Object*[1];
            insertRequest->Items[0] = newWebsite;
        insertResponseType* response = myFav->insert(insertRequest);
        //

        // check to make sure the operation was successful

        //

            if(response->selectedNodeCount != 1 || 
               response->status != responseStatus::success)
        {
            throw new Exception(S"Error inserting the new favoriteWebSite " + 
                                S"into myFavoriteWebSites");
        }
        //

        // now we've inserted the new favoriteWebSite, let's query for it

        //

        queryRequestType* queryRequest = new queryRequestType();
        xpQueryType* xpQuery = new xpQueryType();

        //NOTE: the m: prefix is declared automatically in the SoapExtension 

        //for the current service

        xpQuery->select=S"/m:myFavoriteWebSites/m:favoriteWebSite[./m:title='Hello.NET' " +
                        S"and ./m:url='http://www.microsoft.com']";

        //add the xpQuery to the xpQuery array

        queryRequest->xpQuery = new xpQueryType*[1];
            queryRequest->xpQuery[0] = xpQuery;
        queryResponseType* queryResponse = myFav->query(queryRequest);
        //

        // get the returned favoriteWebSite out of the response

        //

        favoriteWebSiteType* returnedWebSite = dynamic_cast<favoriteWebSiteType*> 
             (queryResponse->xpQueryResponse[0]->Items[0]);
       
        //

        // check to make sure the operation was successful

        //                   

            if(String::Compare (returnedWebSite->title[0]->Value, S"Hello.NET") != 0 || 
               String::Compare (queryResponse->xpQueryResponse[0]->status , S"success")!= 0)
        {
            throw new Exception(S"Error retrieving the new favoriteWebSite " +
                                S"from myFavoriteWebSites");
        }       
        //

        // display the webSite in a messageBox

        //

            MessageBox::Show(String::Concat (S"The following favoriteWebSite was returned " +
                                             S"from myFavoriteWebSites: ",
                                             returnedWebSite->title[0]->Value));
       
        //

        // replace the cat/@ref attribute value

        //

        topLevelAttributeType* redAttribute = new topLevelAttributeType();
        redAttribute->name = S"ref";
        redAttribute->value = S"newvalue";
        replaceRequestType* replaceRequest = new replaceRequestType();
        replaceRequest->select=S"/m:myFavoriteWebSites/m:favoriteWebSite/m:cat/@ref[.='system']";
        replaceRequest->attribute = new topLevelAttributeType*[1];
            replaceRequest->attribute[0] = redAttribute;
       
        //

        // delete the website

        //

        deleteRequestType* deleteRequest = new deleteRequestType();
        deleteRequest->select = S"/m:myFavoriteWebSites/m:favoriteWebSite[./m:title='Hello.NET' " +
                                S"and ./m:url='http://www.microsoft.com']";
            deleteResponseType* delResponse = myFav->__identifier(delete)(deleteRequest);
         
        //

        // check to make sure we operated on at least one element and that the response 

        // indicates the operation was successful

        //

            if(delResponse->selectedNodeCount == 0 || delResponse->status != responseStatus::success)
        {
            throw new Exception(S"Error deleting the new favoriteWebSite from myFavoriteWebSites");
        }
            MessageBox::Show(S"Successfully deleted the favoriteWebSite from myFavoriteWebSites");
       
       
    }
    catch(SoapException* se)
    {
        //

        // write the SoapException to the console

        //

            Console::Write(S"A SoapException was thrown\n\nException:\n");
            Console::WriteLine(se->ToString());
            Console::Write(S"\n\nExtended SoapFault information returned from .NET My Services:\n");
            Console::Write(se->Detail->InnerXml);
    }
    catch(Exception* ex)
    {
        //

        // write the exception to the console

        //

            Console::WriteLine(ex->ToString());
    }
    Console::WriteLine(S"Press return to exit." );
    Console::ReadLine();
   
    return 0;
}

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here