如何在使用.NET的C#中以编程方式向Web服务发送信息?

7
我知道这有点像重复造轮子,但我需要了解如何通过http/soap/xml和web消息与Web服务通信。原因是我需要与第三方Web服务进行工作通信,但WSDL或其他内容存在问题,使用.NET向其连接时无法正常工作。
那么,有人能给我提供一个过程/简单示例/等等来说明如何做到这一点,或者有人能给我提供一个解释它的链接吗?我不太熟悉Web请求和响应。
我该如何构建和发送请求?我该如何解析响应?
这是一个简单Web服务的代码。假设.asmx的地址为“http://www.mwebb.com/TestSimpleService.asmx”:
using System;
using System.Data;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;

namespace TestSimpleService
{
    [WebService]
    public class Soap : System.Web.Services.WebService
    {
        [WebMethod]
        public string SayHello(string name)
        {
            return "Hello " + name + "!";
        }
    }
}

我该如何调用这个方法?

非常感谢您的帮助。

编辑

我只是想知道如何将数据发送到Web服务。我可以获取所有方法/SOAP操作/URL数据,并解析响应数据。我只是不知道要使用哪些对象或如何使用它们。

如果有人知道一些简单的.NET soap客户端,就像Python中的SUDS一样,那也会很有帮助。


@Mike,你不需要在VS内部使用WSDL;如果您可以通过浏览器访问WSDL并将WSDL下载到本地磁盘,则可以使用wsdl.exe http://msdn.microsoft.com/en-us/library/7h3ystb6(v=VS.100).aspx。 - Aaron McIver
如果您需要一种无需使用Visual Studio的方法来消费Web服务:http://notepad-webservices.blogspot.com/2006/04/web-services-no-source-code-on-server.html,但仍然使用WSDL。 - Michael Buen
WSDL出了点问题,所以我无法使用它。在.NET中,一定有一种使用HTTP/SOAP请求/响应对象发送/接收数据的方法。或者像Python中的Suds一样,必须有一个简单的库来完成这个任务。 - Mike Webb
Visual Studio会告诉你关于WSDL有什么问题吗? - rossisdead
这个 Web 服务是否以某种形式进行了安全保护 - 例如,如果它是一个使用 WSE 2.0 的旧 .net 1.1 Web 服务,那么使用 WCF 的后续版本将会出现互操作问题。 - Kris C
当您尝试在VS中添加Web引用时,您遇到了什么错误?您能否浏览到?wsdl页面或.asmx页面? - Kris C
4个回答

7
如果您想直接通信,我建议使用HTTPWebRequest,因为最终webservice调用只是使用HTTP POST发送的XML。以下链接提供了一些示例:http://geekswithblogs.net/marcel/archive/2007/03/26/109886.aspx
在使用.NET编程程序联系外部webservice之前,可以使用测试工具(例如SOAPUI)来生成您认为需要发布到webservice的确切XML,并使用该工具手动发送它以测试webservice。然后您可以开发.NET等效代码。
编辑-这是一个快速示例,基于上面的链接,调用您的示例服务(使用SOAP1.2)。
        {
            string soap = @"<?xml version=""1.0"" encoding=""utf-8""?>
<soap:Envelope xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" 
   xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" 
   xmlns:soap=""http://www.w3.org/2003/05/soap-envelope"">
  <soap:Body>
    <SayHello xmlns=""http://tempuri.org/"">
      <name>My Name Here</name>
    </SayHello>
  </soap:Body>
</soap:Envelope>";

            HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://localhost:2439/Soap.asmx");
            req.ContentType = "application/soap+xml;";
            req.Method = "POST";

            using (Stream stm = req.GetRequestStream())
            {
                using (StreamWriter stmw = new StreamWriter(stm))
                {
                    stmw.Write(soap);
                }
            }

            WebResponse response = req.GetResponse(); 
            Stream responseStream = response.GetResponseStream();

            // Do whatever you need with the response
            Byte[] myData = ReadFully(responseStream);
            string s = System.Text.ASCIIEncoding.ASCII.GetString(myData);
        }

ReadFully方法来自http://www.yoda.arachsys.com/csharp/readbinary.html,看起来它是由Jon Skeet创作的。


1
在响应周围使用“Using”语句? - Matt Mitchell

1
选定答案的代码对我没有起作用。我不得不在头部添加SOAPAction并更改ContentType。以下是整个代码:
var strRequest = @"<soap12:Envelope> 
                    ... 
                    </soap12:Envelope>";

string webServiceUrl = "http://localhost:8080/AccontService.svc";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(webServiceUrl);

request.Method = "POST";
request.ContentType = "text/xml;charset=UTF-8";         
request.Accept = "text/xml";
request.Headers.Add("SOAPAction", "http://tempuri.org/IAccountService/UpdateAccount");

byte[] data = Encoding.UTF8.GetBytes(strRequest);

request.ContentLength = data.Length;
Stream requestStream = request.GetRequestStream();
requestStream.Write(data, 0, data.Length);
requestStream.Close();

HttpWebResponse response = (HttpWebResponse)request.GetResponse();
StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
string responseXmlString = reader.ReadToEnd();

return new HttpResponseMessage()
{
    Content = new StringContent(responseXmlString, Encoding.UTF8, "application/xml")
};

0

XML-RPC.NET,可以动态创建绑定。

例如(来自他们网站的示例):

[XmlRpcUrl("http://betty.userland.com/RPC2")]
public interface IStateName : IXmlRpcProxy
{
    [XmlRpcMethod("examples.getStateName")]
    string GetStateName(int stateNumber); 
}

噢,我没意识到有所不同。这说明我在这个主题上的知识有限 :) 是啊,我试过了,但它没起作用。猜想那就是原因。 - Mike Webb
所以不能通过这个XML RPC库来使用SOAP吗?http://weblog.masukomi.org/writings/xml-rpc_vs_soap.htm - Uwe Keim

0
如果您的服务真的像您的示例那样简单,那么只需使用“添加服务引用”并使用代理即可。
如果这不起作用,请使用命令行 svcutil.exe 程序并发布它打印的错误消息。
除非别无选择,否则不要使用 WSDL.EXE。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接