XLST를 사용하여 XML을 SOAP로 래핑하여이 문제를 해결할 수있었습니다.
내 작업 테스트 앱 코드는 다음과 같습니다.
using System;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.Xml.XPath;
using System.Xml.Xsl;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
GetBasicData getBasicData = new GetBasicData();
getBasicData.CONO = "1";
getBasicData.CUNO = "201702";
XPathDocument requestXPathDocument;
if (SerializeIntoRequestXPathDocument(getBasicData, out requestXPathDocument))
{
XmlDocument requestXmlDocument;
if (CreateRequestXMLDocument(requestXPathDocument, @"Z:\Darice\M3 SOAP\GetBasicData.xsl", out requestXmlDocument))
{
XmlDocument responseXmlDocument;
if (ExecuteRequestSoap(requestXmlDocument, out responseXmlDocument))
{
MemoryStream unwrappedMemoryStream;
if (UnwrapSoapResponseXmlDocumentIntoMemoryStream(responseXmlDocument, out unwrappedMemoryStream))
{
GetBasicDataResponse getBasicDataResponse;
if (!DeserializeResponseMemoryStream(unwrappedMemoryStream, out getBasicDataResponse))
{
Debug.WriteLine("FAIL");
}
}
}
}
}
Console.ReadLine();
}
//STATIC FUNCTIONS
private static Boolean CreateRequestXMLDocument(XPathDocument xPathDocument, String xslPath, out XmlDocument xmlDocument)
{
try
{
using (MemoryStream memoryStream = new MemoryStream())
{
using (StreamWriter streamWriter = new StreamWriter(memoryStream))
{
XmlWriter xmlWriter = XmlWriter.Create(streamWriter);
XsltSettings xsltSettings = new XsltSettings();
xsltSettings.EnableScript = true;
XslCompiledTransform xslCompiledTransform = new XslCompiledTransform();
xslCompiledTransform.Load(xslPath, xsltSettings, null);
xslCompiledTransform.Transform(xPathDocument, xmlWriter);
memoryStream.Position = 0;
using (StreamReader streamReader = new StreamReader(memoryStream))
{
XmlReader xmlReader = XmlReader.Create(streamReader);
xmlDocument = new XmlDocument();
xmlDocument.Load(xmlReader);
}
}
}
}
catch (Exception exception)
{
Debug.WriteLine(exception);
xmlDocument = null;
return false;
}
return true;
}
private static Boolean DeserializeResponseMemoryStream<T>(MemoryStream memoryStream, out T xmlObject)
{
try
{
using (StreamReader streamReader = new StreamReader(memoryStream))
{
XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
using (XmlReader xmlReader = XmlReader.Create(streamReader))
{
xmlObject = (T)xmlSerializer.Deserialize(xmlReader);
}
}
}
catch (Exception exception)
{
Debug.WriteLine(exception);
xmlObject = default(T);
return false;
}
return true;
}
private static Boolean ExecuteRequestSoap(XmlDocument requestXmlDocument, out XmlDocument responseXmlDocument)
{
try
{
Byte[] byteArray = UTF8Encoding.UTF8.GetBytes(requestXmlDocument.OuterXml);
WebRequest webRequest = WebRequest.Create(Properties.Resources.SoapServerAddress);
webRequest.ContentLength = byteArray.Length;
webRequest.ContentType = @"text/xml; charset=utf-8";
webRequest.Headers.Add("SOAPAction", @"http://schemas.xmlsoap.org/soap/envelope/");
webRequest.Method = "POST";
using (Stream requestStream = webRequest.GetRequestStream())
{
requestStream.Write(byteArray, 0, byteArray.Length);
using (WebResponse webResponse = webRequest.GetResponse())
{
using (Stream responseStream = webResponse.GetResponseStream())
{
using (StreamReader streamReader = new StreamReader(responseStream))
{
responseXmlDocument = new XmlDocument();
responseXmlDocument.LoadXml(streamReader.ReadToEnd());
}
}
}
}
}
catch (Exception exception)
{
Debug.WriteLine(exception);
responseXmlDocument = null;
return false;
}
return true;
}
private static Boolean SerializeIntoRequestXPathDocument<T>(T dataObject, out XPathDocument xPathDocument)
{
try
{
XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
using (MemoryStream memoryStream = new MemoryStream())
{
using (StreamWriter streamWriter = new StreamWriter(memoryStream))
{
xmlSerializer.Serialize(streamWriter, dataObject);
memoryStream.Position = 0;
using (StreamReader streamReader = new StreamReader(memoryStream))
{
memoryStream.Position = 0;
xPathDocument = new XPathDocument(streamReader);
}
}
}
}
catch (Exception exception)
{
Debug.WriteLine(exception);
xPathDocument = null;
return false;
}
return true;
}
private static Boolean UnwrapSoapResponseXmlDocumentIntoMemoryStream(XmlDocument responseXmlDocument, out MemoryStream memoryStream)
{
try
{
XmlNamespaceManager xmlNamespaceManager = new XmlNamespaceManager(responseXmlDocument.NameTable);
xmlNamespaceManager.AddNamespace("tns", "CRS610MI");
xmlNamespaceManager.AddNamespace("SOAP", @"http://schemas.xmlsoap.org/soap/envelope/");
XmlNode xmlNode = responseXmlDocument.SelectSingleNode(@"/SOAP:Envelope/SOAP:Body/tns:GetBasicDataResponse", xmlNamespaceManager);
memoryStream = new MemoryStream(UTF8Encoding.UTF8.GetBytes(xmlNode.OuterXml));
}
catch (Exception exception)
{
Debug.WriteLine(exception);
memoryStream = null;
return false;
}
return true;
}
}
}
그리고 여기에 XSL 코드가 있습니다.
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:crs="CRS610MI" exclude-result-prefixes="crs">
<xsl:output method="xml"/>
<xsl:template match="/">
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<soap:Body>
<xsl:apply-templates select="node()|@*"/>
</soap:Body>
</soap:Envelope>
</xsl:template>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
-------------------서비스 제공 업체가 WSDL을 제공하지 않는 경우 해당 서비스 제공 업체와 거래해서는 안됩니다. 이것은 로켓 과학이 아니며 SOAP 웹 서비스가 작동하는 표준 방식입니다. 10 년 넘게 표준이었습니다. 이 서비스 제공자가 무능한 다른 방식으로 진지하게 궁금합니다.
무능한 비즈니스 파트너와 거래 할 수밖에 없다면
- 행운을 빕니다
- 당신 만들기 자신의 자신의 서비스에 맞게 WSDL을, 다음 서비스와 통신하는 데 필요한 프록시 클래스를 생성하는 "서비스 참조 추가"를 사용합니다.
SOAP 용 MessageContract로 클래스를 표시해야합니다.
[MessageContract]
public class ExampleResponse
{
private string _myResponse = String.Empty;
[MessageBodyMember(Name = "ResponseToGive", Namespace = "http://myserver:8888")]
public string ResponseToGive
{
get { return _myResponse; }
set { _myResponse = value; }
}
}
-------------------일부는 왜 그렇게 단호하여 WSDL을 사용해야하는지 이해할 수 없습니다. WSDL은 단순히 메서드를 호출하고 해당 엔터티를 사용할 수 있도록하기위한 것이며 선택 사항입니다.
https://something.com/SomeService/TheService.asmx?method=DoSomething 과 같은 서비스의 정확한 URL로 이동하여 작동하도록했습니다.
그리고 SOAP 봉투를 포함하여 API가 정의하는 정확한 헤더와 XML을 분석합니다. 첫 번째 섹션은 헤더 정보 여야하며 그 아래에는 XML이 있어야합니다. 봉투 태그를 포함하여 지정된 방식으로 XML을 작성하십시오. 헤더의 경우 : POST, Host, Content-Type 및 SOAPAction이 가장 중요합니다. 일부 서버는 API에 나열되어 있지만 Content-Length가 필요하지 않습니다.
다음은 몇 가지 샘플 코드입니다.
public void PostXMLData(string serviceUrl, XDocument requestXML)
{
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(serviceUrl);
req.Method = "POST";
req.Host = "SOMETHING";
req.ContentType = "text/xml; charset=utf-8";
req.Headers.Add("SOAPAction", "SOMETHING");
req.Accept = "text/xml";
using (Stream stream = req.GetRequestStream())
{
requestXML.Save(stream);
}
using (WebResponse resp = req.GetResponse())
{
using (StreamReader rd = new StreamReader(resp.GetResponseStream()))
{
var result = rd.ReadToEnd();
if (result.Contains("error"))
{
throw new Exception($"XML Submission Failed: {result}");
}
}
}
}
출처
https://stackoverflow.com/questions/22079839