Click here to Skip to main content
15,884,078 members
Articles / Web Development / ASP.NET

Sending MIME Messages to a Web Service Endpoint from C#

Rate me:
Please Sign up or sign in to vote.
4.67/5 (2 votes)
20 Jan 2017CPOL4 min read 23.6K   2   2
There are legacy web services still out there in the current environment which expects to send request messages to them in the MIME format. This article explains a simpler way of sending messages to legacy web services using the MIME format without using any third party component

Introduction

In one of the projects that I recently worked with we had an opportunity to exchange insurance messages from our application to another application developed by another organization using the ACORD standards (https://www.acord.org/Pages/default.aspx). The partner with whom we were integrating was using an old version of the ACORD standard which was accepting messages to their web service endpoint using multipart - MIME message. Our application was built using C# and Microsoft has adopted a new standard called MTOM and doesn’t support MIME format anymore. So we had to find a way to send messages to our partner and the direction was not to use any third party tool for the same. There are several third party libraries available one such - MIMEKit – which can create MIME messages.

Background

Introduction to MIME Message

MIME – (Multipurpose Internet Mail Extensions) message lets user exchange different kinds of data between client and servers by specifying the type of data in the header. MIME an internet standard that was mainly designed to support some extended functionality to the email in the SMTP Format has been extended and put to use in HTTP as well. The client specifies the type of the data in the header (like plain text, xml, application/ excel etc.) which will let the server select appropriate applications / programs to handle the data. A sample MIME message would look like this

MIME-Version: 1.0
Content-Type: multipart/related; boundary=--=-glZ6jtnXmVAn68ZSF5H6Zw==
 
--=-glZ6jtnXmVAn68ZSF5H6Zw==
Content-Type: text/plain; charset=utf-8
Content-ID: 291169ef-d733-4989-a39f-2a5619d09c97
 
Request from Party A to Party B
 
--=-glZ6jtnXmVAn68ZSF5H6Zw==
 
Content-Type: text/xml
Content-ID: 8365146c-c9bc-47f5-8487-e6b34611d078
 
<ac:Attachments><ac:Attachment><ac:Document><ac:DocumentReference>TS43289061M1</ac:DocumentReference><ac:DocumentVersion>1</ac:DocumentVersion><ac:FileId>Shima Re/Seg Acct QGF001- RECLAM 8971884.xlsx</ac:FileId><ac:FileSize><ac:NumUnits>48</ac:NumUnits><ac:UnitMeasurementCd>KB</ac:UnitMeasurementCd></ac:FileSize><ac:DocumentTypeCd>document_broker_invoice</ac:DocumentTypeCd><ac:Description>Shima Re/Seg Acct QGF001- RECLAM 8971884</ac:Description></ac:Document></ac:Attachment></ac:Attachments>

/9j/4AAQSkZJRgABAQEAYABgAAD/4QBoRXhpZgAASUkqAAgAAAAEABoBBQABAAAAPgAAABsBBQABAAAARgAAACgBAwABAAAAAgAAADEBAgASAAAATgAAAAAAAABgAAAAAQAAAGAAAAABAAAAU 

--=-glZ6jtnXmVAn68ZSF5H6Zw==
Content-Type: application/octect-stream
Content-ID: e49c391b-57ca-4d1b-afd2-c109dbc624d6
--=-glZ6jtnXmVAn68ZSF5H6Zw==--

As you can see it begins with the Header – MIME-Version which specifies which version of the MIME message is being used. Then comes the Content-Type, there are multiple content-types supported by MIME (https://msdn.microsoft.com/en-us/library/ms527355(v=exchg.10).aspx – contains a list of content-type). The sample message above has the content-type: multipart/related which conveys to the server that the message is split into multi-parts and the message becomes meaningful once the all the parts are stitched together.

Introduction to ACORD

ACORD is a non-profit organization that provides data standards and implementation guidelines for the global insurance industry. ACORD schemas have been widely used and supported by major insurance industries.

Even though ACORD has updated its standards to start using MTOM and other latest technologies in transferring the messages, we had to retort to using Multi-part MIME message as the partner whom we were integrating with were sticking to the older version of the ACORD standard.

According to ACORD a sample POST request with an attachment would look something like this

POST http://partner-test.com/api/request HTTP/1.1
MIME-Version: 1.0
Content-Type: Multipart/Related; boundary= MIME_boundary1234
; type=text/xml; start=xxxxx
Host: partner-test.com
Content-Length: nnnn
SOAPAction: " PostRq"

HTTP Header

--MIME_boundary1234
Content-ID: xxxx
Content-Type: text/xml; charset=”utf-8”
Content-Length: nnnn

MIME Part #1 Header

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope" SOAPENV:
encodingStyle="http://schemas.xmlsoap.org/soap/encoding">
<SOAP-ENV:Body>

SOAP

<ac:PostRq xmlns="http://www.ACORD.org/Standards/AcordMsgSvc/Inbox"
xmlns:ac="http://www.ACORD.org/Standards/AcordMsgSvc/1.4.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.ACORD.org/Standards/AcordMsgSvc/1.4.0
AcordMsgSvc_v-1-4-0.xsd">
<ac:Sender>
<ac:PartyId>urn:duns:123456789</ac:PartyId>
<ac:PartyRoleCd>Broker</ac:PartyRoleCd>
</ac:Sender> …….. </ac:PostRq

Business ACORD Message

--MIME_boundaryB0R9532143182121
Content-ID: <A01EFAE7-5490-43D0-AB6B-DAEF1671CDCC>
Content-Length: nnn
Content-Type: application/octect-stream; charset=”utf-8”

MIME Part # 2 Header

<<Binary Content of the file>>

Binary Attachment

-- MIME_boundary1234==

MIME Boundary End

Using the Code

Before we get into the code, there are several ways to get the SOAP request from C#(lots of articles are available in code project and other sites), hence the payload part which we need to create using the schema shared by ACORD can be done using those methods.

Now to create the rest of the Part of the message, we do the following

Import library

using System.Net.Http;

that provides programming interfaces for sending HTTP requests and receiving HTTP responses from a resource URL

Next set the properties like endpointURL where we need to post the request and MIME boundary which would be used to specify the different parts of the message.

static string _endPointURL = "http://avalidwebservice.com";
static string _boundary = "=-glZ6jtnXmVAn68ZSF5H6Zw==";
Uri _endpoint = new Uri(_endPointURL);
HttpRequestMessage _requestMessage = new HttpRequestMessage(HttpMethod.Post, _endpoint);

Create a HTTP Request Message and Mark the HTTP Method as POST.

Create a MultipartContent object by passing the content type as "related" and specify the boundary that we have set. Next is to create a httpContent pass the soap message that we have captured / any other xml payload that we would like to send in the constructor of the HttpContent.

Set the Headers of the HttpContent by using the Headers property in the HTTPContent Object. Few important properties that we need to set are "Content-Type" based on the content that we send we can specify the Media Type.

MultipartContent _multiPartcontent = new MultipartContent("Related",boundary);
HttpContent _xmlContent = new StringContent("")  -- here you can pass the xml stored as string / 
 
_xmlContent.Headers.ContentType = new MediaTypeHeaderValue("text/xml");
_xmlContent.Headers.Add("Content-ID",Guid.NewGuid().ToString());
 
//Add any other content headers that you want to add here  
//_xmlContent.Header.Add("key""value");
 
_multiPartContent.Add(_xmlContent);

For the list of complete set of Content-Type - https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Complete_list_of_MIME_types. Any other Headers that the receiver is expecting can be set in the Headers Property as it expects a key value to be present. Some of the commonly used Headers are

  • Content-Transfer-Encoding - used to specify the encoding technique base64, 8 bit, 16bit etc
  • Content-Description – used to specify any description that we need to send to the receiver
  • Content-Disposition – used to specify content in-line or as attachment

Now set the multiPartContent to the HttpRequestMessage. Create a HttpClient object call the send asyc method to send the request message. Set the HttpCompletionOption.ResponseContentRead and CancellationToken.None

HttpCompletionOption.ResponseContentRead – makes sure that the operation would be completed after reading the entire response including the content.

CancellationToken.None – makes sure that the operation cannot be cancelled.

_requestMessage.Content = _multiPartContent;                

HttpClient httpClient = new HttpClient();

Task<HttpResponseMessage> httpRequest = httpClient.SendAsync(requestMessage, HttpCompletionOption.ResponseContentRead, CancellationToken.None);

HttpResponseMessage httpResponse = httpRequest.Result;

These code snippets are good enough to be able to send a MIME message to a web service endpoint using C#.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionObject reference error when using this code Pin
Member 1094189327-Jul-22 7:49
Member 1094189327-Jul-22 7:49 
QuestionSample Project Pin
JeanFourie24-Oct-17 1:00
JeanFourie24-Oct-17 1:00 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.