Subscribe to News feed

Invoking the PDF Converter Web Service from Visual Studio 2005 using vb.net

Posted at: 2:44 PM on 28 January 2011 by Muhimbi

VS2005

When we developed the Web Services Interface for our PDF Conversion engine, one of our goals was to make it as compatible as possible with legacy and non Visual Studio 2008 environments, e.g. Java and other Web Services capable systems.

Although we succeeded in making it compatible, we recently found out that when using the standard version of the aging Visual Studio 2005 environment, there are some problems with the XML serialisation of web service data.

This article explains how to invoke the Muhimbi PDF Conversion Services from a Visual Studio 2005 environment. It also provides a VB version of the C# based sample code used in our main Web Services tutorial. If you use Visual Studio 2008 or newer then please use this tutorial, unless you have some interest in the vb.net based sample code at the end of this post.

Ok, so the situation is as follows: your organisation still uses Visual Studio 2005, for whatever valid reason, and you wish to invoke the Muhimbi PDF Converter from a Visual Studio 2005 based application. Unfortunately the facility in Visual Studio 2005 that adds web references is not too happy with the default DataContractSerializer used by our WCF based service. Visual Studio 2005 uses the standard XmlSerializer, which is quite compatible, but not completely. Switching serialisers at runtime is not possible either as they are part of the data contract, which makes sense.

 

Solution 1 – Visual Studio 2005 extensions for .net 3.0

The easiest solution is to download the latest Visual Studio 2005 extensions for the .net framework 3.0. Don’t be put off by the fact that it is still a CTP, Microsoft never bothered to update it and instead pushed people to Visual Studio 2008.

Once installed you can add a Service Reference using the following URL. Please do not use the Add Web Reference option, as that uses the old way of doing it.

         http://localhost:41734/Muhimbi.DocumentConverter.WebService/?wsdl

If not already added automatically, you will need to add a regular .net reference to the following .net 3.0 assemblies as well:

    System.ServiceModel.dll
    System.Runtime.Serialization.dll

Once the service reference has been added you can either use the sample VB.NET code listed at the end of this post or the C# code in our regular tutorial. Please note that depending on how you have named things, you may need to manually change the names of the sample namespaces.

 

Solution 2 – Create web service proxy manually using SVCUTIL.EXE

If Solution 1 doesn’t work for you, or you don’t want to install the VS2005 extensions, then you can also take the manual approach that uses svcutil.exe to create the web service proxy classes in the language of your choice. If you wish you can skip steps 1 to 4 and download the pre-generated proxies for VB and C#, as well as some other sample code, here.

The procedure is as follows:

  1. You will need an updated version of svcutil.exe as the one that ships with VS2005 is not suitable, so download and install the Windows SDK.
     
  2. If not already the case, please make sure the .net framework 3.0 is installed on your system as well. An easy way to check if it has already been installed is by checking if the following directory exists:
     
    "%WINDIR%\Microsoft.NET\Framework\v3.0\Windows Communication Foundation"
     
    Download it from here if needed.
     
  3. Make sure svcutil.exe is on your path (It is most likely located at C:\Program Files\Microsoft SDKs\Windows\v6.0\Bin), and open the command prompt.
     
  4. Create a folder or navigate to the directory where you want to create the proxy classes, e.g. c:\ws_proxy and execute the following command to generate the web service proxy classes:
     
    svcutil.exe http://localhost:41734/Muhimbi.DocumentConverter.WebService/?wsdl /language:vb /serializer:DataContractSerializer /namespace:*,DocumentConverter

    This will result in the following output (note the version number of svcutil.exe).

    image 
    You can read about the various parameters, including targeting different languages, in the svcutil documentation.
     
  5. If you haven’t already created a Visual Studio 2005 project, then do so now (this sample uses vb.net for a change) and add the generated proxy file to the project.
     
  6. Create a new WinForm, add a TextBox as well as a Button to it. Please accept the default names.
     
  7. Double click the button and replace all code with the code displayed below.
     
  8. Run the application, enter the name of an MS-Word file including the full path and click the button to convert the file and display the PDF.

 

Download pre-generated proxies and source code here.
 

Imports System.IO
Imports System.ServiceModel
 
Public Class Form1
 
    ' ** The URL where the Web Service is located. Amend host name if needed.
    Dim SERVICE_URL As String = "http://localhost:41734/Muhimbi.DocumentConverter.WebService/"
 
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles Button1.Click
 
        Dim client As DocumentConverterServiceClient = Nothing
 
        Try
            ' ** Determine the source file and read it into a byte array.
            Dim sourceFileName As String = TextBox1.Text
            Dim sourceFile As Byte() = File.ReadAllBytes(sourceFileName)
 
            ' ** Open the service and configure the bindings
            client = OpenService(SERVICE_URL)
 
            '** Set the absolute minimum open options
            Dim openOptions As New OpenOptions()
            openOptions.OriginalFileName = Path.GetFileName(sourceFileName)
            openOptions.FileExtension = Path.GetExtension(sourceFileName)
 
            ' ** Set the absolute minimum conversion settings.
            Dim conversionSettings As New ConversionSettings()
            conversionSettings.Fidelity = ConversionFidelities.Full
            conversionSettings.Quality = ConversionQuality.OptimizeForPrint
 
            ' ** Carry out the conversion.
            Dim convFile As Byte() = client.Convert(sourceFile, openOptions, conversionSettings)
 
            ' ** Write the converted file back to the file system with a PDF extension.
            Dim destinationFileName As String = Path.GetDirectoryName(sourceFileName) & "\" & _
Path.GetFileNameWithoutExtension(sourceFileName) & "." & _
                   conversionSettings.Format.ToString
            Using fs As FileStream = File.Create(destinationFileName)
                fs.Write(convFile, 0, convFile.Length)
                fs.Close()
            End Using
 
            MessageBox.Show("File converted to " & destinationFileName)
 
            ' ** Launch the PDF file in the registered viewer
            Process.Start(destinationFileName)
 
        Catch ex As FaultException(Of WebServiceFaultException)
            MessageBox.Show("FaultException occurred: ExceptionType: " & _
                            ex.Detail.ExceptionType.ToString())
        Catch ex As Exception
            MessageBox.Show(ex.ToString())
        Finally
            CloseService(client)
        End Try
 
    End Sub
 
    ''' <summary>
    ''' Configure the Bindings, endpoints and open the service using the specified address.
    ''' </summary>
    ''' <returns>An instance of the Web Service.</returns>
    Public Shared Function OpenService(ByVal address As String) As DocumentConverterServiceClient
        Dim client As DocumentConverterServiceClient = Nothing
 
        Try
            Dim binding As New BasicHttpBinding()
            ' ** Use standard Windows Security.
            binding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly
            binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows
            ' ** Increase the Timeout to deal with (very) long running requests.
            binding.SendTimeout = TimeSpan.FromMinutes(30)
            binding.ReceiveTimeout = TimeSpan.FromMinutes(30)
            ' ** Set the maximum document size to 40MB
            binding.MaxReceivedMessageSize = 50 * 1024 * 1024
            binding.ReaderQuotas.MaxArrayLength = 50 * 1024 * 1024
            binding.ReaderQuotas.MaxStringContentLength = 50 * 1024 * 1024
 
            ' ** Specify an identity (any identity) in order to get it past .net3.5 sp1
            Dim epi As EndpointIdentity = EndpointIdentity.CreateUpnIdentity("unknown")
            Dim epa As New EndpointAddress(New Uri(address), epi)
 
            client = New DocumentConverterServiceClient(binding, epa)
 
            client.Open()
 
            Return client
        Catch generatedExceptionName As Exception
            CloseService(client)
            Throw
        End Try
    End Function
 
    ''' <summary>
    ''' Check if the client is open and then close it.
    ''' </summary>
    ''' <param name="client">The client to close</param>
    Public Shared Sub CloseService(ByVal client As DocumentConverterServiceClient)
        If client IsNot Nothing AndAlso client.State = CommunicationState.Opened Then
            client.Close()
        End If
    End Sub
 
End Class

 

This concludes our rather long and boring story. We’ll promise that the next blog post will contain some colourful pictures.

.

0 Comments:

Post a Comment

Subscribe to Post Comments [Atom]

Links to this post:

Create a Link