【问题标题】:implementing XML request into .NET web application在 .NET Web 应用程序中实现 XML 请求
【发布时间】:2013-04-10 22:05:01
【问题描述】:

我一直在阅读和阅读,但我越走越困惑。我正在用 C# 构建一个 ASP.NET 4.0 Web 应用程序。我正在尝试实施信用卡处理。我使用的公司提供了一个示例 XML SOAP 请求和响应,但我不知道该怎么做。我是一名新手开发人员,对这一切都很陌生。我只是不知道从哪里开始。非常感谢任何帮助,我也必须通过 SSL 发送,但这可能是另一个问题。

这是 SOAP 请求

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
  <soapenv:Body>
    <v1:SendTranRequest xmlns:v1="http://postilion/realtime/merchantframework/xsd/v1/">
      <v1:merc>
        <v1:id>9000</v1:id>
        <v1:regKey>RegistrationKey</v1:regKey>
        <v1:inType>1</v1:inType>
        <v1:prodType>5</v1:prodType>
      </v1:merc>
      <v1:tranCode>1</v1:tranCode>
      <v1:card>
        <v1:pan>411111******1111</v1:pan>
        <v1:xprDt>1312</v1:xprDt>
      </v1:card>
      <v1:contact>
        <v1:id>1234567</v1:id>
        <v1:fullName>John Doe</v1:fullName>
        <v1:coName>Ajax Intl.</v1:coName>
        <v1:title>CEO</v1:title>
        <v1:phone>
          <v1:type>3</v1:type>
          <v1:nr>5555555555</v1:nr>
        </v1:phone>
        <v1:addrLn1>123 1st St.</v1:addrLn1>
        <v1:city>Somewhere</v1:city>
        <v1:state>CO</v1:state>
        <v1:zipCode>80021</v1:zipCode>
        <v1:ctry>US</v1:ctry>
        <v1:email>email@email.com</v1:email>
        <v1:ship>
          <v1:fullName>John Doe</v1:fullName>
          <v1:addrLn1>123 1st St.</v1:addrLn1>
          <v1:city>Somewhere</v1:city>
          <v1:state>CO</v1:state>
          <v1:zipCode>80021</v1:zipCode>
          <v1:phone>5555555555</v1:phone>
          <v1:email>email@email.com</v1:email>
        </v1:ship>
      </v1:contact>
      <v1:reqAmt>099</v1:reqAmt>
      <v1:usrDef>
        <v1:name>firstname</v1:name>
        <v1:val>John</v1:val>
      </v1:usrDef>
      <v1:indCode>1</v1:indCode>
      <v1:tranFlags>
        <v1:dupChkTmPrd>6000</v1:dupChkTmPrd>
        <v1:convFeeAcptd>N</v1:convFeeAcptd>
      </v1:tranFlags>
      <v1:tax>
        <v1:idcr>0</v1:idcr>
      </v1:tax>
    </v1:SendTranRequest>
  </soapenv:Body>
</soapenv:Envelope>

这是我的创建请求和读取响应

 WebRequest webRequest = WebRequest.Create("url");
 HttpWebRequest httpRequest = (HttpWebRequest)webRequest;
 httpRequest.Method = "POST";
 httpRequest.ContentType = "text/xml; charset=utf-8";
 httpRequest.Headers.Add("SOAPAction: http://tempuri.org/");
 httpRequest.ProtocolVersion = HttpVersion.Version11;
 httpRequest.Credentials = CredentialCache.DefaultCredentials;

 //build xml

 var xmlWriterSettings = new XmlWriterSettings
    {
        NewLineHandling = NewLineHandling.None,
        Encoding = Encoding.ASCII
    };

    using (var requestStream = httpRequest.GetRequestStream())
    using (var writer = XmlWriter.Create(requestStream, xmlWriterSettings))
    {
        xml.WriteTo(writer);
    }
    //Get the Response    
    HttpWebResponse wr = (HttpWebResponse)httpRequest.GetResponse();
    StreamReader srd = new StreamReader(wr.GetResponseStream());
    string resulXmlFromWebService = srd.ReadToEnd();

【问题讨论】:

  • 您使用的是哪个支付服务提供商?如果他们没有在 ASP.NET 中给出示例,我会感到惊讶。

标签: c# .net xml service web


【解决方案1】:

我建议查看 HttpWebRequest 和 HttpWebResponse 类。 HttpWebRequest 类将允许您设置请求的主体、标头、凭据和其他内容。 HttpWebResponse 应该允许您阅读所需的任何信息。

希望这对某些人有所帮助,但您的问题不清楚您需要做什么。但以下代码将从您已将请求 XML 发布到的提供的端点下载 XML 文档。

var requestXml = new XmlDocument();

// build XML request 

var httpRequest = HttpWebRequest.Create("https://www.website.com/");
httpRequest.Method = "POST";
httpRequest.ContentType = "text/xml";

// set appropriate headers

using (var requestStream = httpRequest.GetRequestStream())
{
    requestXml.Save(requestStream);
}

using (var response = (HttpWebResponse)httpRequest.GetResponse())
using (var responseStream = response.GetResponseStream())
{
    // may want to check response.StatusCode to
    // see if the request was successful

    var responseXml = new XmlDocument();
    responseXml.Load(responseStream);
}

至于处理通过 SSL/TLS 做的事情,你很幸运,.NET 会为你解决这个问题,你只需要在你提供给 @ 的 URL 中指定 https 而不是 http 987654342@.


您可以通过多种方式构建 XML,其中一种方法是使用 System.Xml.Linq 命名空间中的 XElement、XAttribute 和 XNamespace 对象。除非您至少不能使用 .NET 3.5,否则我建议您使用。由于您是在 APS.NET 4.0 中创建应用程序,这应该不是问题。

当您创建 XElement 并需要指定命名空间时,您需要首先创建一个 XNamespace 对象。

var ns = XNamespace.Get("http://tempuri.com");
var root = new XElement(ns + "Root", "Body");

这将产生以下 XML:

<Root xmlns="http://tempuri.com">Body</Root>

但是,您需要能够指定命名空间前缀。为此,您需要将XAttribute 对象添加到您首先使用前缀的XElement,并通过构造函数指定前缀。

var ns = XNamespace.Get("http://tempuri.com");
var root = new XElement(ns + "Root",
    new XAttribute(XNamespace.Xmlns + "prefix", ns)
    "Body"
);

这将产生以下 XML:

<prefix:Root xmlns:prefix="http://tempuri.com">Body</prefix:Root>

这是使用这些对象构建的 XML 的一部分。

var id = 9000;
var regKey = "RegistrationKey";
var inType = 1;
var prodType = 5;
var tranCode = 1;

var soapNs = XNamespace.Get("http://schemas.xmlsoap.org/soap/envelope/");
var v1Ns = XNamespace.Get("http://postilion/realtime/merchantframework/xsd/v1/");

var xml= new XElement(soapNs + "Envelope",
    new XAttribute(XNamespace.Xmlns + "soapenv", soapNs),
    new XElement(soapNs + "Body",
        new XElement(v1Ns + "SendTranRequest",
            new XAttribute(XNamespace.Xmlns + "v1", v1Ns),
            new XElement(v1Ns + "merc",
                new XElement(v1Ns + "id", id),
                new XElement(v1Ns + "regKey", regKey),
                new XElement(v1Ns + "inType", inType),
                new XElement(v1Ns + "prodType", prodType)
            ),
            new XElement(v1Ns + "tranCode", tranCode)
        )
    )
);

这会产生以下 XML:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
    <soapenv:Body>
        <v1:SendTranRequest xmlns:v1="http://postilion/realtime/merchantframework/xsd/v1/">
            <v1:merc>
                <v1:id>9000</v1:id>
                <v1:regKey>RegistrationKey</v1:regKey>
                <v1:inType>1</v1:inType>
                <v1:prodType>5</v1:prodType>
            </v1:merc>
            <v1:tranCode>1</v1:tranCode>
        </v1:SendTranRequest>
    </soapenv:Body>
</soapenv:Envelope>

要将 XML 包含到您的 HttpWebRequest 的正文中,请执行以下操作:

var xmlWriterSettings = new XmlWriterSettings
{
    NewLineHandling = NewLineHandling.None
};

using (var requestStream = httpRequest.GetRequestStream())
using (var writer = XmlWriter.Create(requestStream, xmlWriterSettings))
{
    xml.WriteTo(writer);
}

这里要注意的一点是XmlWriter 与XmlWriterSettings 的创建,这允许您在XML 元素之间不包含任何空格。如果你需要空格,你可以通过调用XmlWriter.Create(stream)来创建XmlWriter


如果您不能使用 .NET 3.5 或更高版本,您可以使用 System.Xml 命名空间中的 XmlDocument 和 XmlElement 对象。

出于您的目的,使用XmlDocument 和XmlElement 构建所需的XML 将很容易,但代码会更多。要创建XmlElement,您需要XmlDocument 来创建对象。 XmlDocument.CreateElement 函数有一个重载,允许您同时指定命名空间前缀和命名空间,这样会更直接一些。

使用XmlDocument 和XmlElement 需要注意的一点是,您需要在构造完成后手动将XmlElement 附加到适当的对象。另一件事是您也不能在构造过程中指定 XmlElement 的主体,因此也需要在创建后完成。

以这种方式构造 XML 的操作顺序无关紧要。主要是确保您将XmlElement 附加到正确的父级,并将InnerText 设置在右侧的XmlElement 对象上。

var soapPrefix = "soapenv";
var soapNs = "http://schemas.xmlsoap.org/soap/envelope/";

var v1Prefix = "v1";
var v1Ns = "http://postilion/realtime/merchantframework/xsd/v1/";

var xmlDoc = new XmlDocument();

var envelope = xmlDoc.CreateElement(soapPrefix, "Envelope", soapNs);
xmlDoc.AppendChild(envelope);

var body = xmlDoc.CreateElement(soapPrefix, "Body", soapNs);
envelope.AppendChild(body);

var sendTranRequest = xmlDoc.CreateElement(v1Prefix, "SendTranRequest", v1Ns);
body.AppendChild(sendTranRequest);

var merc = xmlDoc.CreateElement(v1Prefix, "merc", v1Ns);
sendTranRequest.AppendChild(merc);

var idElement = xmlDoc.CreateElement(v1Prefix, "id", v1Ns);
idElement.InnerText = id.ToString();
merc.AppendChild(idElement);

var regKeyElement = xmlDoc.CreateElement(v1Prefix, "regKey", v1Ns);
regKeyElement.InnerText = regKey;
merc.AppendChild(regKeyElement);

var inTypeElement = xmlDoc.CreateElement(v1Prefix, "inType", v1Ns);
inTypeElement.InnerText = inType.ToString();
merc.AppendChild(inTypeElement);

var prodTypeElement = xmlDoc.CreateElement(v1Prefix, "prodType", v1Ns);
prodTypeElement.InnerText = prodType.ToString();
merc.AppendChild(prodTypeElement);

var tranCodeElement = xmlDoc.CreateElement(v1Prefix, "tranCode", v1Ns);
tranCodeElement.InnerText = tranCode.ToString();
sendTranRequest.AppendChild(tranCodeElement);

这会产生与上面相同的 XML。

当使用XmlDocument 构造您的XML 请求时,有两个XmlDocument.Save 函数可以用于您的目的。一个接受Stream,另一个接受XmlWriter。如果您可以省略空格,请使用接受 XmlWriter 的重载并将其添加到 HttpWebRequest 将是:

using (var requestStream = httpRequest.GetRequestStream())
using (var writer = XmlWriter.Create(requestStream, xmlWriterSettings))
{
    xmlDoc.Save(writer);
}

如果您需要包含空格,请使用:

using (var requestStream = httpRequest.GetRequestStream())
{
    xmlDoc.Save(requestStream);
}

【讨论】:

  • 谢谢,我会试试看会发生什么。付款提供商并没有提供多大帮助,但这就是这家公司想要使用的人,所以我会看看我能做些什么。
  • @user1740003 我相信是这样,但这需要更多的工作。看看stackoverflow.com/questions/5396671/…
  • 好吧,JG 那篇文章很有道理,但有些评论说不要使用字符串构建 xml。根据我的阅读,您无法使用 XML 编写器构建 SOAP 请求。如何构建 SOAP 请求?
  • @user1740003 您可以使用字符串构建 XML,但建议使用 XML API(XDocument、XmlDocument、XmlWriter 等)之一构建 XML,以避免使用字符串时可能发生的任何错误.如果您发布 SOAP XML 请求的示例,我可以帮助您编写构建 XML 的代码。
  • 我在上面发布了肥皂请求。感谢您的帮助。
猜你喜欢
  • 2018-08-04
  • 1970-01-01
  • 1970-01-01
  • 2014-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-24
  • 1970-01-01
相关资源
最近更新 更多