asp tutorials, asp.net tutorials, sample code, and Microsoft news from 15Seconds
Data Access  |   Troubleshooting  |   Security  |   Performance  |   ADSI  |   Upload  |   Email  |   Control Building  |   Component Building  |   Forms  |   XML  |   Web Services  |   ASP.NET  |   .NET Features  |   .NET 2.0  |   App Development  |   App Architecture  |   IIS  |   Wireless
 
Pioneering Active Server
 Power Search










Active News
15 Seconds Weekly Newsletter
• Complete Coverage
• Site Updates
• Upcoming Features

More Free Newsletters
Reference
News
Articles
Archive
Writers
Code Samples
Components
Tools
FAQ
Feedback
Books
Links
DL Archives
Community
Messageboard
List Servers
Mailing List
WebHosts
Consultants
Tech Jobs
15 Seconds
Home
Site Map
Press
Legal
Privacy Policy
internet.commerce














internet.com
IT
Developer
Internet News
Small Business
Personal Technology
International

Search internet.com
Advertise
Corporate Info
Newsletters
Tech Jobs
E-mail Offers

HardwareCentral
Compare products, prices, and stores at Hardware Central!

Deploying DLLs Using Web Services
By Chris Peiris
Rating: 3.5 out of 5
Rate this article


  • email this article to a colleague
  • suggest an article

    Introduction

    The Internet is becoming the global network for business. WS-Security, cryptography libraries, and SSL encryptions are making data transfer over the Internet safer. HTTP is commonly used as the "Transport Protocol" to exchange data between organizations. GXA specifications are trying to build a common framework to create seamless communication between distributed systems on multiple platforms.

    We can exchange business information as XML representations over Web services. Complex data structures can be bundled into a DataSet to be sent across the wire. The Microsoft .NET Framework will breakdown the data into the "structure" (XML Schema) and "data" (XML). Therefore, any complex data manipulation mechanism (DataSet, DataTable, etc. ...) can be easily understood by the consumer of the Web service. But, can we deploy a DLL using Web services? Can we deploy a unit of binary execution over a Web service?

    Isn't this question addressed by the Microsoft Smart Client framework? A Smart Client application will download the DLLs from a Web server on demand. It will copy the DLLs to the client machine to execute locally. Isn't it the same as deploying a DLL over a Web service?

  • download source code

    The Difference between a Smart Client Application and DLLs over Web Services

    Dynamic link library (DLL) is a unit of execution in binary format. A Smart Client app will download the DLL to the client machine. The client DLL can be refreshed on a timer or manually. At all times the client application works with the local copy. The following image explains the architecture of a Smart Client application.


    (Figure 1 : Smart Client Architecture)

    If the server copy is updated we need to wait until the timer or manual trigger is invoked to update the client copy. This is not an issue in our Web services deployment scenario. The Web service invocation will always get the up-to-date byte stream of the DLL. The client application will always receive the latest copy of the DLL. This could be described as a "live connection" to the server. The proposed application architecture is described in Figure 2.


    (Figure 2 : Proposed Architecture - using a Web services to transfer DLL as a binary stream)

    What are the limitations? The obvious drawback is speed. A local copy of a smart client application will be faster than fetching a DLL over a Web service. We are also relaying on the client machine to use Reflection mechanisms to create Windows Forms "on the fly". Therefore, we need to have the .NET Framework installed at the client machine.

    Note: Another way to transport a DLL over SOAP is to use Web Services Extensions (WSE 1.0) as DIME attachments. I will not cover this option in this article.

    Let's investigate how to implement this functionality using a sample.

    Sample Application

    The sample application has two views. I am trying to create two presentation views (WinForms) to display different information. The logic is to transfer different binary over the wire for different parameters. The two Web forms are:

    Note: I have made the presentation interface simple in order to concentrate on the coding logic. Therefore, the Web form will have very little functionality.

    • User Form: This Web form is for general users of the system. This is mainly read-only data. Figure 3 displays the user form.


      (Figure 3: User Form)

    • Author Form: This Web form is for administrators of the system . The "Authors" can change access permissions using this view. Figure 4 displays the author form


      (Figure 4 : Author Form)

    The Web service consumer gets a different binary stream depending on the parameters we provide to the Web service (whether it is "user" or "author" ). This binary stream represents whether the user views a "User Form" or an "Author Form". Let's look at the implementation of the solution.

    There are four projects in the VS .NET Studio solution

    1. User Form Project - Windows application project
    2. Author Form Project - Windows application project
    3. Web service to deploy requested module (User or Author) - Web service project
    4. Driver program to run the Web service. - Windows application project

    The objective is to deliver different information over Web services on demand. If the we like to consume the "User data" we will transfer the User Form DLL over the Web service. The same logic applies to the Author Form DLL.

    User Form Project

    First let's look at the User Form. This form is for general users of the system. Here are the steps.

    1. Create a Windows application project.


      (Figure 5: Creating User Form Windows Application Project)

    2. Create the user form by dragging and dropping controls from the ToolBox. Here are the elements of the User form

    NameTypeDescription
    Label_HeadingLabelLabel display the heading
    Label_DetailsLabelDisplay the user text

    I have made the implementation simple to concentrate more on the Web service functionality. The form looks like this.


    (Figure 6: User Form design view)

    Author Form Project

    Let's look at the Author form. Here are the steps.

    1. Create a Windows application project.
    2. Create the user form by dragging and dropping controls from the ToolBox. Here are the elements

    NameTypeDescription
    Label_HeadingLabelLabel display the heading
    CheckedListBox_OptionsCheckedListBoxList of options to manipulate user access

    Here is the design view of the Author Form.


    (Figure 7 : Author Form design view)

    Web Service

    This is the core of the application.

    1. Create a Web service project in VS .NET IDE
    2. Name the project "WSAppDeply".


    (Figure 8 : WSAppDeploy Web service project)

  • Rename "Service1.asmx" file to "WSDeploy.asmx"
  • Create a Web method called "GetAppModule". This Web method will accept a string describing whether the user requires the "User Form" or the "Author Form". Let's have a look at the code:
    
    <WebMethod()> Public Function GetAppModule(ByVal strUserInfo As String) As DataSet
            '
            ' Return assembly as a string
            '
            Dim retSet As DataSet = Me.PrepareDataSet()
            Dim newRow As DataRow = retSet.Tables(0).NewRow()
            Dim inFile As System.IO.FileStream
            Dim binaryData() As Byte
            Dim strAssemblyName As String
            Dim strAssemblyPath As String
            Dim strBasePath As String
            Dim strError As String
    
            strBasePath = "C:/chris/articles/WS Deployment/WSAppDeploy/bin/"
    
            Try
                If (LCase(strUserInfo) = "author") Then
                    strAssemblyName = "AuthorForm.dll"
                    newRow("ModuleName") = strAssemblyName
                    newRow("ClassName") = "AuthorForm.AuthorForm"
                    newRow("MethodName") = "RunForm"
                Else
                    strAssemblyName = "UserForm.dll"
                    newRow("ModuleName") = strAssemblyName
                    newRow("ClassName") = "UserForm.UserForm"
                    newRow("MethodName") = "RunForm"
                End If
    
    
    First we initialize some variables to store data. (we will have a look at the PrepareDataSet() function later). The Web service needs to know where the DLLs are. Therefore, we need to provide the location of the DLLs. This is stored in the "strBasePath" variable.

    Note: Please make sure to copy the UserForm.dll and AuthorForm.dll into this directory. This is not the default location for the project binary executables. This is deliberately done to make the application more flexible. We can have a variable pointing to the default debug directory (of the User Form and Author Form Projects) to make our lifer easier. This creates a dependency to UserForm and AuthorForm projects. This way we can deploy the DLL as soon as it is available from myriad methods. (The DLL could be made outside of the organization and emailed to the developer. The developer will copy the DLL to the correct directory and deploy it to the client machine.)

    Then we basically use a selection construct to check the type of input. (whether it is "user" or "author"). We need some vital information to obtain the binary stream.

    • The name of the assembly (ex: UserForm.dll)
    • The name of the class (This should follow the format "Namespace.ClassName". ex: UserForm.UserForm)
    • Which method to run in the selected class. (ex: "RunForm" method)
    Let's look at the rest of the code.
    
                ' Get path to assembly to send to caller.
                '
                strAssemblyPath = strBasePath + strAssemblyName
    
                ' Open the assembly binary file.
                '
                inFile = New System.IO.FileStream(strAssemblyPath, _
                                                    System.IO.FileMode.Open, _
                                                    System.IO.FileAccess.Read)
                ReDim binaryData(inFile.Length)
                inFile.Read(binaryData, 0, inFile.Length)
                inFile.Close()
    
                ' Convert the binary input into Base64 UUEncoded output.
                '
                newRow("AssemblyBytes") = System.Convert.ToBase64String(binaryData, _
                                                             0, _
    
    
    First we read the DLL as an input file stream. Then we basically read the byte stream of the DLL into a "binaryData" array and convert it to a Base 64 String. This string is sent to the Web service consumer. (In a commercial implementation we need to encrypt this data stream. Please refer to the "Possible Extensions" section. )

    We will also perform some error handling to exit gracefully. Then we package the information in a DataSet and send it to the Web service consumer. The DataSet is comprised of the assembly name, class name, method name, and the binary stream for the entire assembly.

    
            Catch e As Exception
                Dim message As String = e.Message
            End Try
    
            ' Save the row, and accept the changes on the dataset
            '
            retSet.Tables(0).Rows.Add(newRow)
            retSet.AcceptChanges()
    
            ' Return the dataset to caller
            '
            GetAppModule = retSet
        End Function
    
    
    Let's look at the PrepareDataSet() that prepares the DataSet to store information. This function will create a DataSet that will hold four strings in a DataTable. These string will be the DLL name, class name, method name, and the DLL byte stream as a string.
    
        Private Function PrepareDataSet() As DataSet
    
            Dim newTable As New DataTable()
            Dim newSet As New DataSet()
    
            newTable.Columns.Add("ModuleName", Type.GetType("System.String"))
            newTable.Columns.Add("ClassName", Type.GetType("System.String"))
            newTable.Columns.Add("MethodName", Type.GetType("System.String"))
            newTable.Columns.Add("AssemblyBytes", Type.GetType("System.String"))
    
            newSet.Tables.Add(newTable)
    
            Return newSet
    
        End Function
    
    
    Let's see the Web service in action now. We can make the "WSAppDeploy" the "Startup Application" for the Visual Studio .NET solution by right clicking "WSAppDeploy" and selecting "Set as Startup Project". Then we compile and run the project. Let's invoke the Web service with the "user" string as our input parameter. (We are invoking the Web service to retireve the binary stream of the UserForm application over SOAP). The screen should look similar to Figure 9.


    (Figure 9 : WSAppDeploy Web service in action)

    When we invoke the GetAppModule Web method. We get the following response. (Figure 10)


    (Figure 10 : UserForm binary stream as a Web method response.)

    Observe the "AssemblyBytes" tag. This is the binary stream of the UserForm Windows Form. Let's try to focus on building a client/driver program to consume this Web service.

    Driver Program

    1. Create a VB Windows application project.
    2. Rename the default form to "DriverProgram.vb".
    3. Add a Web reference to the WSAppDeploy Web service. (Right Click on the Project | Select "Add Web Reference" to our "WSAppDeploy" Web service). Your solution explorer should look like this:


    (Figure 11 : Solution Explorer after the adding the Web reference)

  • Create a form by dragging and dropping controls from the ToolBox. Here are the elements of the driver form:

    NameTypeDescription
    Cmb_OptionCombo BoxLet the user select which view they choose (User or Author view)
    btn_InvokeButtonButton click to initiate the Web service call

    The combo box will let the user select between the "UserForm" or the "AuthorForm". The button click will initiate the Web service call to transfer the correct binary for the selected form. The design view of the driver program is similar to figure 12.


    (Figure 12: Driver program design view)

    Let's have look at the code for the driver program

    
    Private Sub btn_Invoke_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
     Handles btn_Invoke.Click
            Dim uiModule As [Assembly]
            Dim wsAppModule As New localhost.WSDeploy()
            Dim dsAppModuleInfo As DataSet
            Dim strUserInfo As String
    
            Try
                strUserInfo = cmb_Option.Items.Item(cmb_Option.SelectedIndex)
            Catch exp As Exception
                MsgBox("Please select a user type")
                Exit Sub
            End Try
    
    
    First we try to read the selected option from the combo box. A "try "and "catch" block is there to prevent any invalid input.
    
            Dim strModuleName As String
            Dim strClassName As String
            Dim strMethodName As String
    
            Try
                ' Ask Web service for an appropriate assembly
                '
                dsAppModuleInfo = wsAppModule.GetAppModule(strUserInfo)
    
                ' Retrieve names from dataset
                '
                GetModuleNames(dsAppModuleInfo, strModuleName, strClassName, 
    strMethodName)
    
                ' Turn the stream of bytes returned into an
                ' assembly
                '
                Dim assemblyBytes() As Byte
                assemblyBytes = 
    System.Convert.FromBase64String(dsAppModuleInfo.Tables(0).Rows(0)("AssemblyBytes
    "))
    
    
    Then we use the WSDeploy Web service to get a binary stream to create our client-end Windows Form. First the Web services response is read as a DataSet (the variable dsAppModuleInfo) . Then we segment the DataSet to delineate the byte stream, the assembly name, the class name, and the method name of the Web form to be created. Finally the binary stream is converted into "Base64String" and stored in an array of bytes.
    
                ' Load the assembly into memory 
                '
                uiModule = System.Reflection.Assembly.Load(assemblyBytes)
    
                ' Find the class and method within the assembly
                '
                Dim typeUIForm As Type
                Dim methodUIMethod As MethodInfo
                Dim obj As Object
    
                typeUIForm = uiModule.GetType(strClassName)
                methodUIMethod = typeUIForm.GetMethod(strMethodName)
    
                ' Invoke the method
                '
                obj = Activator.CreateInstance(typeUIForm)
                methodUIMethod.Invoke(obj, Nothing)
    
            Catch exp As Exception
                ' Error encountered - msgbox it
                '
                MsgBox("Exception: " & exp.Message)
            End Try
        End Sub
    
    
    An assembly is generated after using Reflection on the array of bytes. This is called the uiModule. Now we can extract methods from the assembly and load the Windows Form using "Activator.CreateInstance". The following is the GetModuleNames function that extracts the assembly information from the DataSet passed by the WSDeploy Web service.
    
    Private Sub GetModuleNames(ByVal dsModule As DataSet, ByRef strModuleName As
    String, ByRef strClassName As String, ByRef strMethodName As String)
            strModuleName = dsModule.Tables(0).Rows(0)("ModuleName")
            strClassName = dsModule.Tables(0).Rows(0)("ClassName")
            strMethodName = dsModule.Tables(0).Rows(0)("MethodName")
     End Sub
    
    
    That's the code folks! Let's make the driver program the "Startup Project". Now let's compile the application and run it. You should see the following window come up.


    (Figure 13: Running the driver program)

    Depending what you select, either the UserForm (Figure 3) or the AdminForm (figure 4) will appear. The appropriate binary stream is converted to a Windows Form by using Reflection mechanisms by the client machine.

    Possible Extensions

    Some of the possible extensions to our code:

    • Encrypt the DLL byte stream. This will provide additional level of security.

    • This not just for DLLs. You can use Reflection mechanisms to stream any images or data formats using similar code (i.e. Transfer JPEG images using a Web service), but I strongly recommend you to consider DIME first. (Some DIME references are in the "Further Information" section.)

    Conclusion

    This is an extension to the standard Web services XML data deliverables. We can extend our .NET XML Web services to transfer binary executables as apposes to simple data formats. The advantage is to have a "live connection" to the server and update your client machine with a stream of binary executable over SOAP.

    How To Setup the Sample Code

    1. You need to have the .NET Framework installed on your machine. (Download .NET Framework)
    2. Download the source code
    3. Extract the .zip file to a specified directory
    4. Create a virtual directory called "WSAppDeploy" in IIS to point to Web service directory.
    5. Set "WSDeployClient" project as the "Startup project"
    6. Compile and run. You should see Figure 13.

    Further Information

    Smart Client Framework

    GXA

    Web Services

    Acknowledgements

    • Mr Nigel Watson - Microsoft Australia

    About the Author

    Chris Peiris currently lectures on Distributed Component Architectures (.NET, J2EE & CORBA) at Monash University, Caulfield, Victoria, Australia. He also works as an independent consultant for .NET and EAI implementations. Recently he has been awarded the title "Microsoft Most Valuable Professional" (MVP) for his contributions to .NET Technologies. He has been designing and developing Microsoft solutions since 1995. His expertise lies in developing scalable, high-performance solutions for financial institutions and media groups. He has written many articles, reviews and columns for various online publications including 15Seconds, Developer Exchange (www.Devx.com) and Wrox Press (www.wrox.com) . He co-authored the book "C# Web Service with .NET Remoting and ASP.NET" by Wrox Press. It was followed by "C# for Java Programmers" by Syngress Press as the primary author. Chris frequently presents at professional developer conferences on Microsoft technologies.

    His core skills are C++, Java, .NET, DNA, MTS, Site Server, Data Warehousing, WAP, and SQL Server. Chris has a Bachelor of Computing, Bachelor of Business (Accounting), and Masters of Information Technology. He is currently under taking a PhD on "Web Service Trust Agents". He lives with his family in Civic, Canberra ACT. He can be reached at www.chrispeiris.com.

  • Rate This Article
    Not HelpfulMost Helpful
    1 2 3 4 5
    Other Articles
    Jul 7, 2005 - Hosting Indigo Web Services
    In the second article of his series on Indigo web services, Chris Peiris explains how to host an Indigo web service and examines the IIS, self hosting, and Windows Activation Service hosting options. He then provides step-by-step instructions and sample code for an IIS-hosted and self-hosted Indigo web service.
    [Read This Article]  [Top]
    Jun 8, 2005 - Indigo Programming Model
    In the first part of his series on Microsoft Indigo, Chris Peiris examines the basics of SOA, explains how Indigo fits into the picture and the problems it solves. He then introduces Indigo's programming model and finishes by building a sample Indigo web service using the Microsoft .Net Framework 2.0.
    [Read This Article]  [Top]
    Nov 10, 2004 - Business Intelligence with Microsoft SQL Server Reporting Services - Part 3
    Adnan Masood concludes his discussion of Microsoft SQL Server Analysis services and Microsoft SQL Server Reporting services. In the final part, he discusses Reporting Server web services and using custom code in reports.
    [Read This Article]  [Top]
    Jul 8, 2004 - Using IE's Web Service Behavior To Create Rich ASP.NET Applications
    This article explains the features of the IE Web service behavior and shows how to asynchronously communicate with an ASP.NET Web service directly from the client.
    [Read This Article]  [Top]
    Jul 6, 2004 - Using .NET and Excel 2003 To Validate E-Mails
    Calvin Luttrell shows how to validate e-mail addresses stored in Excel 2003 and provides a special function for solving that pesky problem Yahoo! mail servers cause.
    [Read This Article]  [Top]
    Jun 9, 2004 - Modifying Web Services Documentation
    This short article describes a quick and easy way to provide some security to an ASP.NET Web service by modifying its associated documentation file.
    [Read This Article]  [Top]
    Jun 2, 2004 - Kerberos Authentication with Web Services Enhancements 2.0
    Kerberos authentication is the cornerstone of Windows operating system authentication architecture. Web Services Enhancement 2.0 (WSE 2.0) extends Kerberos support to ASP.NET Web services. Chris Peiris explains the support for this new feature in WSE 2.0.
    [Read This Article]  [Top]
    Dec 15, 2003 - Realizing a Service-Oriented Architecture with .NET
    Chip Irek examines the architectural issues and component design issues of building a .NET application in a service-oriented architecture.
    [Read This Article]  [Top]
    Nov 24, 2003 - Consuming Asynchronous Web Services
    Thiru Thangarathinam shows how to use asynchronous Web services, Windows Service applications, server-based timer components and .NET XML API classes to create high-performance, scalable, and flexible applications.
    [Read This Article]  [Top]
    Nov 12, 2003 - Implementing Paging and XSLT Extensions Using XSLT in .NET - Part 2
    Part one showed how to transform XML data into HTML by using an XSL stylesheet from within a .NET application. This part explains how to make use of XSLT Extension objects and invoke a C# class method from an XSL stylesheet.
    [Read This Article]  [Top]
    Mailing List
    Want to receive email when the next article is published? Just Click Here to sign up.

    Support the Active Server Industry



    JupiterOnlineMedia

    internet.comearthweb.comDevx.commediabistro.comGraphics.com

    Search:

    Jupitermedia Corporation has two divisions: Jupiterimages and JupiterOnlineMedia

    Jupitermedia Corporate Info


    Legal Notices, Licensing, Reprints, & Permissions, Privacy Policy.

    Advertise | Newsletters | Tech Jobs | Shopping | E-mail Offers