img waterboy

Uploading large Attachments using DIME

发表于2004/11/3 8:36:00  1420人阅读


DIME (Direct Internet Message Encapsulation) is part of the Microsoft Web Service Enhancements and can be used to upload large attachments using SOAP.

I am currently working on a project that requires me to potentially upload as well as download large files via .net Webservices.

One challenge I faced was the default Request Size which is directed in the machine.config and in a hosted environment I do not have access to it. Easy enough, override it in the web.config.

Now using standard upload/download functionality in webservices forced me to convert the files to a Byte Array, this means that the actual attachment would be encapsulated within the SOAP envelope and can potentially make a 2MB file a 4 MB file. After some digging I started to take a look at DIME and found that it is extremely simple to upload files (as well as download) via a Webservice.
One advantage is that the actually attachment is not posted within the SOAP Envelope thus making uploads quite a bit faster. (There are more reasons, I don't want to get into here.)

You would have to download and install WSE first, you can get that from Microsoft here.

Let's start by creating a new Solution in VS.net and add a Webservice Project to it.

You will see that after installing the WSE you will have a new option when right clicking a Project as you can see in the Picture below.

After you click on WSE Settings 2.0 you will be presented with a Dialog that lets you confiure your WebService application, essentially it will configure your web.config and add required references to the Project.
Check both boxes as seen below.

Now let's write some code which we will use to save the file that will be sent.

Source Code:

Imports System.Web.Services
Imports System.IO
Imports Microsoft.Web.Services2
Imports Microsoft.Web.Services2.Dime


<WebMethod()> _
    Public Sub UploadFile(ByVal filename As String)
        'Initiate a Filestream that will save the FILENAME to the uploads directory
        Dim fs As FileStream = File.Create(HttpContext.Current.Server.MapPath("uploads/" & filename))
        'Getting the File Size and setting the Buffer to it.
        Dim fileLength As Integer = RequestSoapContext.Current.Attachments(0).Stream.Length
        Dim buffer(fileLength) As Byte
        'Now we simply Request the Attachment (we only have one in this example) and save it
        RequestSoapContext.Current.Attachments(0).Stream.Read(buffer, 0, fileLength)
        fs.Write(buffer, 0, fileLength)
    End Sub

And that is it, pretty simple isn't it?

The next thing we obviously need to do is write a simple client that will upload attachments to the Server.

I just added a Windows Forms Project to the Solution, put a Button and a OpenFileDialog to the form, set the OpenFileDialog to allow multiple selects and that's it.

As for the Properties of the Project you need to go to the WSE 2.0 Settings again and now you can just check the first box (both if it was an asp.net Application)

Add some imports to the Form and some code for the Button Click Event and you are almost done.

Source Code:

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        'Show the OpenFileDialog and if they hit OK we go
        If Me.OpenFileDialog1.ShowDialog = DialogResult.OK Then
            'Setting the Cursor to wait
            Me.Cursor = Cursors.WaitCursor
            'Initiate the Webservice
            Dim proxy As New DimeDemoWSE.Service1Wse

I have to stop here for a second because I overlooked it and was going nuts why something else did not work. As you see, you are referencing DimeDemoWSE.Service1WSE not .Service1 the one you wrote, VS.net will give you your standard WebService (without the WSE properties) and one (let's call it virtual one) that uses WSE; use the WSE one as above.

Source Code:

            'I want to count Total Files copied the cumbersome way.
            Dim totalfL As Integer
            'For Demo Purposes we get the time NOW ....
            Dim sTime As DateTime = Now
            'Now we just iterate through the OpenFileDialog1 Selected Files Collection
            For Each f As String In OpenFileDialog1.FileNames
                    'S is our File Extension, which we will reference in a bit
                    Dim s As String = New IO.FileInfo(f).Extension
                    'Now we define an attachement as a DimeAttachment(filetype,keep the content Type,the file name)
                    Dim attachment As New DimeAttachment(s, TypeFormat.Unchanged, Me.OpenFileDialog1.FileName)
                    'Add the attachment to our WebService Call
                    'Run it and we are basically done.
                    proxy.UploadFile(New IO.FileInfo(f).Name)
                    totalfL += 1
                Catch ex As Exception
                    MsgBox(ex.Message & vbCrLf & vbCrLf & "Filesize: " & New IO.FileInfo(f).Length.ToString)
                End Try
            Dim eTime As DateTime = Now
            MsgBox("Copied " & totalfL & " in " & DateDiff(DateInterval.Second, sTime, eTime) & " s")
            Me.Cursor = Cursors.Default
        End If
    End Sub

This is basically it. Now if you intend to upload larger files, meaning go in a total over the 4MB limit (that includes SOAP Message and stuff) you need to make some changes to the web.config of the Web Service.

We are going to set 2 values here, the overrides value of the httpRequestLimit as well as the WSE Attachement limit.
Open the web.config and set as desired.

Source Code:

   <!--Setting the Runtime limit to 8MB-->
   <httpRuntime maxRequestLength="8000" />


   <!--Setting the SOAP limit to unlimited to rely
   on WebServer limit above. Set as desired-->

And that's all Folks.

You can download the above Sample here

0 0


取 消