How to extract binary attachment from a WCF SOAP response? - c#

I'm writing a .Net 3.5 solution which is consuming a 3rd party WCF web service. The proxy client for the SOAP service was generated by VisualStudio as a service reference.
A SOAP response from the service includes attachments in the data, as I can see it in fiddler. The attachments have a href field which points to a CID reference. The proxy client that VS 2012 has created when returning the object which includes the attachments doesn't include any binary data, but it does include the href field with the CID reference in it.
As captured using fiddler, this is the SOAP response attachment data including the cid:xxxx ref:
<attachments>
<cmn:attachment href="cid:52b2d8a50035921e80bf1540" len="309" name="DOC1.rtf" type="application/rtf" xmime:contentType="application/rtf"/>
</attachments>
And in the raw output in fiddler, the attachment data can be seen with the matching cid:xxxx ref:
------=_Part_22_12445037.1389617382038
Content-Type: application/rtf
Content-Location: DOC1.rtf
Content-ID: <52b2d8a50035921e80bf1540>
Content-Transfer-Encoding: binary
{\rtf1\ansi\ansicpg1252\deff0{\fonttbl{\f0\fnil\fcharset0 Calibri;}}
{\*\generator Msftedit 5.41.21.2510;}\viewkind4\uc1\pard\sa200\sl276\slmult1\lang9\f0\fs22 Doc 1\par
\par
Test information inside an attachment for KM retrieval.\par
\par
Here's something else I've written for use in testing.\par
}
Here is a screenshot of the available fields from the returned object:
How do I access that attachment data so I can actually download the file?

Normally with WCF and SOAP, your file binary is encoded as a base64 string somewhere in your response, however I don't see in what you've posted here the kind of long data string I'd be expecting.
If what you're showing here is just the header from the response, you might check the body of the response message,too, since the header has a size limit, but the body the message doesn't - it's therefore the likely place for your binary payload.

Wouldn't it be easier to return a byte[] in one of the entities you are returning, and then work from that on your client to reconstruct the file?
Are you using MTOM? Because WCF does not support SwA (Soap with attachments) out of the box.

Turns out that the issue was due to the way the 3rd party API was returning the response, the MTOM data was not correctly formatted so WCF was ignoring the binary data.
The way I got around this was by using a bespoke class which basically uses an HttpRequest to talk directly to the web service and extract/parse the binary data out of the response.

Related

.NET Web API WebHook won't accept XML

Via Postman I am receiving the the following response:
The WebHook request must contain an entity body formatted as JSON
With the help of some online tutorials I set up a webhook receiver that successfully reads in events from GitHub.
The next hurdle is being able to to receive a request containing XML data. I brought in the relevant WebHooks.Custom packages via NuGet so that I can handle a less specific request. I'm able to get into the ExecuteAsync method in my CustomWebHookHandler class and read in the data if it's sent as JSON, but if I change the raw body of the request to XML (along with the content-type in the header) I get the error listed above.
Do .NET Web API projects not handle XML out of the box? All commments I found elsewhere stated that they do handle XML.
If they don't handle XML out of the box how do I change the app to allow XML?
If they do handle XML out of the box why am I getting the error message above?

HTTP Server response - wrong content type?

I'm making a server that should be able to store some images and then send/stream them to a client upon request. I've managed to get the server to respond with an image when I request it from a web browser, but when I send the very same HTTP request to the server from my client application, I'm not sure what exactly happens (it's supposed to become a tile map server at some point, but I'm starting out easy with just a single image here).
If it's of any help, here's an output from my web browser request: http://i.imgur.com/tG04qvS.png
And here the other one is: http://i.imgur.com/GUqdawF.png
Fiddler is saying I'm returning Content-Type: text/html; charset=UTF-8 which in my head sounds horribly wrong when trying to return an image.
I've been digging around a little more and it seems the response is empty. It smells like my server isn't delivering the image properly to the client since I'm just using this piece of code to respond to the request:
if (p.http_url.Equals("/MapServer/tile/0/0/0"))
{
Stream fs = File.Open("../MapServer/tile/0,0,0.png", FileMode.Open);
p.writeSuccess("image/jpeg");
fs.CopyTo(p.outputStream.BaseStream);
p.outputStream.BaseStream.Flush();
fs.Close();
}
I'm using StreamWriter for my stream. Is that the one giving me the content_type problems?
HTTP servers map content type through other mechanisms. A Stream is too low-level to convey that kind of information; it doesn't distinguish between series of bytes for a text file or an image.
The Content-type Saga
Content Negotiation
Configuring MIME Types in IIS 7
Try building your service to return something from the System.Net.Http namespace like HttpResponseMessage. These classes have the ability to provide more information about the type of document being sent.

How to return both stream and file length from WCF Restful json webservice?

Hihi all,
I am able to return stream from my WCF restful json webservice, everything works fine. But when I mixed the stream with another piece of data (both wrap into a custom class), upon consuming the webservice from my client, it gives an error message of "An existing connection was forcibly closed by the remote host".
Any advice how can I achieve the above? What it's required for my webservice is to allow downloading of a file with the file length as an additional piece of information for validation at the client end.
Thanks in advance! :)
There are various restrictions while using Stream in WCF service contracts - as per this MDSN link, only one (output) parameter or return value (of type stream) can be used while streaming.
In another MSDN documentation (this is anyway a good resource, if you want to stream large data using WCF), it has been hinted that one can combine stream and some input/output data by using Message Contract.
For example, see this blog post where author has used explicit message contract to upload both file name & file data. You have to do the similar thing from download perspective.
Finally, if nothing works then you can always push the file length as a custom (or standard such as content-length) HTTP header. If you are hosting in IIS then enable ASP.NET compatibility and use HttpContext.Current.Response to add your custom header.

.net Client consuming Axis2 Web Service

I have an .net 2.0 C# client app that has a web service reference to an Axis2 Java Webservice.
The idea is to send some xml data to the webservice, so it can be parsed and inserted into database.
The WS method accepts a single parameter of type 'xsd:anytype'.
Java web service:
public class JWS{
public Response AddData(Object inputXML) {
return Response;
}
}
C# Client:
JWS client = new JWS();
object inputXML = "<xml>some xml data</xml>";
response = client.AddData(inputXML);
There are 2 issues i am seeing when monitored using fiddler.
1) The request has an additional element '<inputXML>' added before the actual xml data.
<inputXML><xml>some xml data</xml></inputXML>
2) The xml is encoded, so '<' is appearing as "<"
I am not sure if this is how SOAP request's are generated but i would like to remove the <inputXML> tag and also, have the xml appear as is without having to replace the special characters.
Is this possible? Is it got something to do with 'Wrapping'/'UnWrapping' Types?
Also, i have used SoapUI to test the java web service and it works well. However, in the request tab, i had to manually remove the <inputXML> tag and submit for it to work correctly. Please help.
TIA
This is expected behaviour under SOAP and the inputXml variable will be decoded back to the original string when passed to your web service method.
However this may indicate a problem with your design, have you considered constructing an object to send to your web service rather than xml data? (As this object will transparently be converted to xml for the web service call anyway).
I found out that the issue is not with encoding but it was interpreted incorrectly on java side when the message was viewed in axis2. So, it is getting decoded properly. Also, the inputxml is now being handled correctly.

Does WCF automatically URL encode/decode streams?

I'm programming a service for a program that uses HTTP post/get requests, so I handle all incoming requests with a hook method that takes a System.IO.Stream and returns a System.IO.Stream.
When I parse the incoming request (contained in an HTML form) by converting to a string and then using System.Web.HttpUtility.ParseQueryString(string), it seems to automatically URL-decode the data. When I return a file path (a Windows UNC, not going to explain why I do that), I initially URL-encoded the string before converting to a stream and returning it using a return-statement, the client seems to get a doubly-coded string.
So, just to be sure, does WCF automatically URL encode/decode streams for me as part of using System.ServiceModel.WebHttpBinding?
Apparently, it does:
"For RESTful services, WCF provides a binding named System.ServiceModel.WebHttpBinding.
This binding includes pieces that know how to read and write information using the HTTP and HTTPS transports, as well as encode messages suitable for use with HTTP."
from here.

Categories