Source code for the AS2 Client C# example program posted at EDIINT AS2. A detailed explanation of the algorithm can be read at "Creating an AS2 Client in Stages".

private void cmdSend_Click(object sender, EventArgs e)
 {
 Cursor = Cursors.WaitCursor;
 int nMdnResult = -1;
 string sErrorMsg = "";
 txtNotification.Text = "";
 txtNotification.Refresh();
 try
 {
 // Get internet mail document object
 mailDocument oMailDocument = oEdiDoc.GetMailDocument();
 //Setting so that syntax for the field "Disposition-Notification-To" is not validated, but treated as a text field
 oMailDocument.AddDefinedHeader("Disposition-Notification-To", MailMessageHeaderTypeConstants.HeaderType_FieldText, RequirementTypeConstants.Requirement_Optional);
 mailMessage oSubjMsg = oMailDocument.GetMessageContent();
 Label1.Text = "importing EDI...";
 Label1.Refresh();
 // For speed, import the EDI file instead of processing.
 if (oSubjMsg.Import(sPath + cmbFile.Text) != 1)
 {
 MessageBox.Show("Failed to load document");
 }
 else 
 {
 //specify content type of mesage
 oSubjMsg.set_HeaderFieldValue("Content-Type", txtContentType.Text);
 // Configure the security of this message.
 ediSecurity oSecurity = oSubjMsg.GetSecurity();
 // Specify the type of encryption and signing algorithm to use
 oSecurity.EncryptionAlgorithm = sEncryptAlgorithm;
 oSecurity.AssuranceAlgorithm = sSigningHash;
 // Recipient's certificate to encrypt message.
 oSecurity.SetCertSubjectNameByLocation(sRecCertSubjName, sRecCertStoreLocation, sRecCertStoreName, sRecServiceProvider);
 // Sender's certificate to sign message.
 oSecurity.SetCertSignerNameByLocation(sSignCertSubjName, sSignCertStoreLocation, sSignCertStoreName, sSignServiceProvider);
 if (ckSendEncrypted.Checked == true)
 {
 oSecurity.EnableEncryption = true;
 }
 else
 {
 oSecurity.EnableEncryption = false;
 }
 if (ckSendSigned.Checked == true)
 {
 oSecurity.EnableAssurance = true;
 }
 else
 {
 oSecurity.EnableAssurance = false;
 }
 if (ckCompression.Checked == true)
 {
 oSecurity.EnableCompression = true;
 }
 else
 {
 oSecurity.EnableCompression = false;
 }
 //This is how the content of the file looks like before it is prepared with all
 //the security configuration. This is also how your trading partner would see
 //the content of your file after he decrypts the AS2 message you send him.
 //(This is the garbled section of the "Sent_SampleEdiX12_850.x12)"
 oMailDocument.Save(sPath + "Output\\MessageContent.txt");
 // Calculate the MIC value from the original message.
 // string sSubjMicValue;
 if (oSecurity.EnableEncryption || oSecurity.EnableAssurance)
 {
 //RFC4130: For any signed messages, the MIC to be returned is calculated
 //on the RFC1767/RFC3023 MIME header and content.
 //Canonicalization on the MIME headers MUST be performed before
 //the MIC is calculated, since the sender requesting the signed
 //receipt was also REQUIRED to canonicalize.
 //RFC4130: For encrypted, unsigned messages, the MIC to be returned is
 //calculated on the decrypted RFC 1767/RFC3023 MIME header and
 //content. The content after decryption MUST be canonicalized
 //before the MIC is calculated.
 sSubjMicValue = oSubjMsg.GenerateDigest(MailMessagePartTypeConstants.Message_All, EncodingMechanismTypeConstants.EncodeType_Base64);
 }
 else
 {
 //'RFC4130: For unsigned, unencrypted messages, the MIC MUST be calculated
 //'over the message contents without the MIME or any other RFC
 //'2822 headers, since these are sometimes altered or reordered by
 //'Mail Transport Agents (MTAs).
 sSubjMicValue = oSubjMsg.GenerateDigest(MailMessagePartTypeConstants.Message_Body, EncodingMechanismTypeConstants.EncodeType_Base64);
 }
 txtMIC.Text = sSubjMicValue;
 txtMIC.Refresh();
 // Prepare the message with the imported EDI file so that the security configurations
 // can be applied.
 if (oSubjMsg.Prepare() != 1)
 {
 MessageBox.Show("Failed to prepare Message");
 }
 else
 {
 if (ckBase64.Checked == true)
 {
 oMailDocument.Save(sPath + "Output\\After_PrepBeforeBase64.txt");
 oSubjMsg.set_HeaderFieldValue("Content-Transfer-Encoding", "base64");
 oSubjMsg.Prepare();
 }
 // Put globally unique ID as Message-ID.
 oSubjMsg.set_HeaderFieldValue("Message-ID", "1234567890@evalusercompany.com"); //txtMessageID.Text
 // Put AS2 version.
 oSubjMsg.set_HeaderFieldValue("AS2-Version", "1.0");
 // Put AS2-To header value.
 oSubjMsg.set_HeaderFieldValue("AS2-To", txtAs2To.Text);
 // Put AS2-From header value.
 oSubjMsg.set_HeaderFieldValue("AS2-From", txtAS2From.Text);
 if (ckAsynchronous.Checked == true)
 {
 // For asynchronous, must set a syntactically correct URI at 'Receipt-delivery-option'.
 oSubjMsg.set_HeaderFieldValue("Receipt-delivery-option", txtReceiptDeliveryOption.Text);
 }
 if (ckReceiveMdn.Checked == true)
 {
 // Request Acknowledgment by adding "Disposition-Notification-To" header.
 // Value must be present but holds no meaning in an AS2 environment.
 oSubjMsg.set_HeaderFieldValue("Disposition-Notification-To", txtDispositionNotificationTo.Text);
 if (ckReceiveSigned.Checked == true) 
 {
 // Request the MDN to be signed.
 string sDnOpts;
 sDnOpts = "signed-receipt-protocol=optional,pkcs7-signature;";
 sDnOpts = sDnOpts + "signed-receipt-micalg=optional,sha1";
 oSubjMsg.set_HeaderFieldValue("Disposition-Notification-Options", sDnOpts);
 }
 } //ckReceiveMdn.Value = 1
 //' Save the document before sending.
 if (oMailDocument.Save(sPath + "Output\\Sent_File.txt") != 1)
 {
 MessageBox.Show("Failed to save message");
 }
 else
 {
 // Get the transports object for internet mail documents.
 ediTransports oTransports = oMailDocument.GetTransports();
 // Create a transport token, and set the information of the
 // HTTP server where to send the file.
 ediTransport oTransport = oTransports.CreateTransport();
 oTransport.SetHTTP();
 // *** Note that FREDI requires the forward-slash (/) at the end of the HTTP URI for posting
 oTransport.InternetUrl = cmbUrl.Text;
 oTransport.TimeOut = 7200;
 // Configure the ISAPI information in the HTTP config object. These settings are specific
 // only to the FREDI ISAPI extension and the ActiveX components that it drives.
 ediHttpCfg oHttpCfg = oTransport.GetHttpCfg(); 
 oHttpCfg.SendVerb = "POST";
 // If there are no errors received from the HTTP server and data is
 // received, we want that data to be processed.
 oHttpCfg.EnableProcessResponse = true;
 // Specify the file name to save the received raw data from the server.
 // The raw data is saved only if the transfer is successful.
 oHttpCfg.ResponseOutput = sPath + "output\\Receive.Mime.Txt";
 // Send the file to the server. If it's a synchronous connection, then
 // wait for incoming data from the server.
 // Execution on the server side may take several minutes
 // which means that the Send() statement will be blocked for the
 // same period until processing the file has been completed and
 // then received, or if an error has occurred.
 Label1.Text = "sending...";
 Label1.Refresh();
 oTransport.Send(cmbFile.Text);
 if (ckReceiveMdn.Checked == true && ckAsynchronous.Checked == false ) //synchronous
 {
 // If the send is successful, we expect an MDN to be received from the server
 // during the Send call. This is because this session is a synchronous session
 // and the MDN must be received in the same HTTP connection that the message
 // itself was sent. Since the MDN is already received, get the MDN message and save
 // the MDN to an external file.
 mailMessage oMDN = oMailDocument.GetMDN();
 txtNotification.Text = oMDN.GetMsgString();
 txtNotification.Refresh();
 mailMessages oMdnMsgs = oMDN.GetMessages();
 //Reading the MDN
 for (int ii=1; ii <= oMdnMsgs.Count; ii++)
 {
 mailMessage oMdnMsg = oMdnMsgs.GetMessageContent(ii);
 mailContentType oContentType = oMdnMsg.GetContentType();
 if (oContentType.MediaType == "message" && oContentType.SubType == "disposition-notification")
 {
 mailMessages oSubMessages = oMdnMsg.GetMessages();
 mailMessage oDisposition = oSubMessages.GetMessageContent(1);
 if (oDisposition != null)
 {
 mailHeaders oHeaders = oDisposition.GetHeaders();
 string sHeaders = "";
 sErrorMsg = "";
 mailHeader oHeader = null; 
 for (int i = 1; i <= oHeaders.Count; i++)
 {
 mailHeader.Set(ref oHeader, oHeaders.GetHeaderByIndex(i)); //oHeader = oHeaders.GetHeaderByIndex(i)
 sHeaders = sHeaders + oHeader.Name + " : " + oHeader.Value + "\r\n";
 if (oHeader.Name.ToLower() == "disposition" )
 {
 nMdnResult = 0;
 }
 else if ( oHeader.Name.ToLower() == "warning")
 {
 nMdnResult = 1;
 sErrorMsg = sErrorMsg + oHeader.Value + "\r\n";
 }
 else if (oHeader.Name.ToLower() == "error")
 {
 nMdnResult = 2;
 sErrorMsg = sErrorMsg + oHeader.Value + "\r\n";
 }
 } //Each oHeader In oHeaders
 // Verify MIC from the receiver.
 mailHeader.Set(ref oHeader, oHeaders.GetHeaderByName("Received-Content-MIC"));
 if (oHeader != null)
 {
 string sRecvMicFldValue;
 sRecvMicFldValue = oHeader.Value;
 int lPos;
 lPos = sRecvMicFldValue.IndexOf(",");
 if (lPos == 0 && sRecvMicFldValue.Length > 0)
 {
 MessageBox.Show("Invalid Received-Content-MIC field value");
 }
 else
 {
 string sMicValue;
 string sMicAlg;
 sMicValue = sRecvMicFldValue.Substring(0, lPos);
 sMicAlg = sRecvMicFldValue.Substring(lPos);
 // Compare the MIC of the subject document to MIC received by received.
 if (sMicValue != sSubjMicValue )
 {
 MessageBox.Show("Recipient received invalid document. Subject MIC=" + sSubjMicValue + ", Recv MIC=" + sMicValue);
 }
 } //lPos == 0 && Len(sRecvMicFldValue) > 0
 oHeader.Dispose();
 } //oHeader != null
 oHeaders.Dispose();
 } //oDisposition != null
 oDisposition.Dispose();
 oSubMessages.Dispose();
 } //oContentType.MediaType 
 oContentType.Dispose();
 oMdnMsg.Dispose();
 } // for ii
 oMDN.Save(sPath + "Output\\Received_MDN.Txt");
 oMdnMsgs.Dispose();
 oMDN.Dispose();
 } //ckReceiveMdn.Value = 1 And ckAsynchronous.Value = 0
 Label1.Text = "";
 Label1.Refresh();
 if (nMdnResult == 0 )
 {
 MessageBox.Show("Successfully sent.");
 }
 else if ( nMdnResult == 1 )
 {
 MessageBox.Show("The message was successfully sent but there were warnings.");
 MessageBox.Show(sErrorMsg, "MDN Warning");
 }
 else if (nMdnResult == 2 )
 {
 MessageBox.Show("An error occurred during transmission");
 MessageBox.Show(sErrorMsg, "MDN Error");
 }
 oHttpCfg.Dispose();
 oTransport.Dispose();
 oTransports.Clear();
 oTransports.Dispose();
 } //oMailDocument.Save(sPath + "Output\Sent_File.txt") != 1
 } //oSubjMsg.Prepare != 1
 } //oSubjMsg.Import(sPath + cmbFile.Text) != 1
 oSubjMsg.Dispose();
 oMailDocument.Dispose();
 oEdiDoc.Close();
 Cursor = Cursors.Default;
 }
 catch( System.Exception ex)
 {
 txtNotification.Text = txtNotification.Text + "\r\n" + "Severe error. " + ex.Message;
 txtNotification.Refresh();
 }
 Cursor = Cursors.Default;
 }

Click here to download a trial version of the Framework EDI


AltStyle によって変換されたページ (->オリジナル) /