June 2008
Posted on the 16th at 2:38 PM CST
Consuming Web Services with DIME Attachments in VB.NET
FiledFiled under ASP.NET, VB.NET

In this post I will share a solution that I reached the other day regarding an InvalidOperationException that I was receiving when attempting to consume a SOAP web service with DIME attachments. Hopefully this will save you some time, as I was unable to find a good solution online when I encountered the error. DIME attachments are a Microsoft standard that has recently been deemed obsolete. Basically, it's a method of transmitting binary data via SOAP, in which the raw data is delivered after the SOAP envelope. By keeping the data outside of the envelope, it does not have to be Base64 encoded (which would be required to keep the XML valid). Subsequently, the attachment does not have to be consumed by an XML parser on the client-side. This approach dramatically increases the performance of both the client and the server. Although effective, DIME has already been replaced by a newer standard called MTOM. However, DIME is still used today by several established APIs and will probably continue to be used unless an upgrade is absolutely warranted. To work with DIME attachments, Microsoft Web Service Enhancements 2.0 will need to be used.

In my efforts to invoke the web service method and download an attachment, I constantly received the following exception...

InvalidOperationException: Client found response content type of 'application/dime', but expected 'text/xml'

This was somewhat puzzling to me because I did not know what was forcing my client to expect "text/xml". I was hoping there was a ContentType setting I could simply modify that would fix the error, but I was unable to find one. At this point, I was certain that the root of the issue was under the covers. In other words, it wasn't my code causing the problem, it had to be one of the underlying dependencies. So, I went ahead and did some digging into the MSDN documentation and found an article on the topic. One paragraph in particular grasped my attention, specifically the last sentence...

In order to use the WSE DIME support with a Microsoft .NET client application in Visual Studio, you must add a reference for the Microsoft.Web.Services2.dll assembly. Also, after adding a Web reference to the DIME-based Web service, you must modify the proxy class in the References.vb file so that it inherits from the Microsoft.Web.Services2.WebServicesClientProtocol class in WSE.

Sweet! At this point, I thought I had this all figured out. Apparently, the exception I was receiving was caused by the proxy class that is automatically generated by ASP.NET. By default, this class inherits System.Web.Services.Protocols.SoapHttpClientProtocol. According to MSDN, this inheritance will not work with DIME attachments, so it needs to be changed to a class that comes with the WSE toolkit. By using Lutz Roeder's Reflector, which is a wonderful tool, I verified that the only acceptable content types in the default proxy class are text/xml and application/soap+xml...

Disassembly in .NET Reflector

So that was definitely the problem. This glimmer of hope was shattered when I was completely unable to find the generated proxy class in my solution. Where on Earth is this References.vb file located?! It did not exist in my project because it was a "Web Site" project, and therefore the proxy class was being generated based on the WSDL and compiled on-the-fly by the web server. How do you modify code that is generated on-demand, behind the scenes, by ASP.NET? You don't. Damn!

This frustrated me quite a bit, especially since MSDN did not mention anything about my situation, which is one that I would consider to be common. What I ended up having to do was create a new class library with the sole purpose of invoking the web service. Then I replaced my web reference in the web site project with a reference to this new class libary. This theoretically simple process turned out to be a little confusing, so allow me to step you through it (note that I am using Visual Studio 2005). To begin, I added a new Class Library project to the current web site...

File | Add New Project

As already mentioned, this class library will solely perform the task of invoking the web service. So, the web reference needs to be removed from the web site project and then re-added to this new class library. When you do this, Visual Studio will generate a proxy class for the service that you will be able to modify accordingly to prevent the InvalidOperationException from being thrown. Here is a screenshot illustrating where the proxy class is located in Solution Explorer...

Reference.vb in Solution Explorer

Open up the Reference.vb file (if you code in C# it will be called Reference.cs) so that you can modify the Inherits statement per MSDN's recommendation...

Namespace WebReferenceName

    Partial Public Class ServiceName
        Inherits Microsoft.Web.Services2.WebServicesClientProtocol
        Inherits System.Web.Services.Protocols.SoapHttpClientProtocol


And that should be the only thing that needs changed. Prior to building, you may want to go into the class library configuration and set it to release mode so that debugging symbols are not generated. Once the library builds successfully, you will need to add a reference to it in your web site project. When you need to call the method that returns DIME attachments in your web site project, simply instantiate the web service within the class library like this...

Dim Service as New MyClassLibrary.WebReferenceName.ServiceName()


This will prevent the InvalidOperationException from being thrown. Every time you update the web reference in the class library, you will have to go back in and change the inheritance of the proxy class again, which is pretty lame. Unfortunately, this is the best solution I was able to come up with. I hope somebody finds this helpful. If you have any questions or relevant insight, please leave a comment.

Comments (7)
Permalink Comment from Dosta Je Bilo on June 18th, 2008 at 1:01 PM
My question is not about your article, but i hope you'll answer it, so here it is:
Since you were one of my favorite users on asp.net forum who had very good ideas about the forum itself, I would like to know why is your account deactivated there?
Permalink Comment from Josh StodolaEmail on June 18th, 2008 at 1:13 PM
Hi Dosta, I was banned from the forums for expressing my opinions. I would call it moderator abuse. There was a handful of moderators who disagreed with some of my replies. They insisted I stop making "controversial" posts. Since I did not feel like I was doing anything wrong, I refused, and now I am banned. Pretty stupid of them, right?
Permalink Comment from Dosta Je Bilo on June 19th, 2008 at 4:21 AM
I can't believe! Every your post I read was aimed at reducing forum's flaws and I didn't run into any "controversial" post.. Well, the history teach us that everyone who has new and different ideas first gets laughs than bans and just after that deserved credits. Unfortunately, it takes very long time that some people open their eyes..
But, look at it on the bright side - now you have enough time to write articles on your blog ;)
Permalink Comment from wbudda on June 22nd, 2008 at 1:19 PM
@dosta - how duz name calling nd puting people dwn reducing forum's flaws? josh was not nice member for that. i think thats why he is gone. seems pretty stupid of him to break tha rules and think it should be okay.
Permalink Comment from Josh StodolaEmail on June 22nd, 2008 at 1:37 PM
@wbudda I didn't put people down. I told them what they needed to hear. Name calling? I don't think so. I never called anybody names. Breaking the rules? The rules of those forums are so vague and unclear that they can be stretched and skewed by the moderators to deem ANYONE as an offender.

If you honestly think that my intentions were not good, I am sorry. Everything I said on the forums was meant to be helpful. I'll admit, sometimes I was somewhat rude when I replied to people. But, I intended on conveying my message in a way that would grab people's attention. And I still think people are benefitting from such replies to this day.

Thanks for commenting.
Permalink Comment from Dosta Je Bilo on June 28th, 2008 at 9:02 AM
@wbudda First, you'll have to explain what does "nice member" mean? Is that someone who is changing his mind just because someone else thinks it's wrong? From my point of view that is just a frightened maggot who doesn't have opinion at all. And if you want to find some "evidence" that Josh wanted to improve forum, you should check these 3 threads: http://forums.asp.net/t/1215218.aspx, http://forums.asp.net/t/1077685.aspx, http://forums.asp.net/t/1139206.aspx
Permalink Comment from winning craps systems on March 4th, 2009 at 2:42 AM
Thanks for the update of your journey.I am having some issues with calling an external web service API that returns attachments using DIME (with Web Service Enhancements 2.0). I understand that DIME has recently been deemed obsolete since they came up with something new called MTOM (with Web Service Enhancements 3.0), but I am not in control of this API configuration So I need to get this to work with DIME. Anyways, I have written my own web service with a method that will invoke this API, store the attachments on the server, and return the number of files received. It's fairly simple. It seems I am getting a complete response from the server, but the following exception is being thrown...Invalid Operation Exception: Client found response content type of 'application/dime', but expected 'text/xml'.

Guess What?

There are a few basic guidelines you should be aware of before leaving a comment…

  • If you choose to display your email address, it will not be detected by spam bots
  • Comments are limited to 3,000 characters; so far you have used none of them
  • HTML will be encoded; links and line breaks will be converted automatically
  • Comments containing five or more links will be subject to moderation

Have Your Say

← Answer this to prove you are human
 
 

Chill Out…