使用 Web 服务或 Web 服务参考

Posted

技术标签:

【中文标题】使用 Web 服务或 Web 服务参考【英文标题】:Using Web Service or Web Service Reference 【发布时间】:2010-11-15 04:23:05 【问题描述】:

这与 .NET 相关。而且我决定使用 Web 服务参考而不是 Web 服务...我认为虽然我下面的问题确实适用于任何一种情况,但我想尝试了解这一点。

这就是我的问题。让我先解释一下我来自哪里。在过去的一个项目中,我之前通过创建手动类(例如 GetPicturesRequest.cs 和 GetPicturesResponse.cs)与几个 API 进行了交谈,这些类将为我保存状态。我有一个名为 Request.cs 的基类,它实际发送了 api 调用:

Stream requestStream;
Stream responseStream;
XmlDocument doc = new XmlDocument();
doc = CreateRequestXML();

// Determins if API call needs to use a session based URI
string requestURI = UseAuthURI == true ? _requestURIAuthBased + JSessionID : _requestURI;

byte[] data = XmlUtil.DocumentToBytes(doc);

// Create the atual Request instance
HttpWebRequest request = CreateWebRequest(requestURI, data.Length);
request.ContentLength = data.Length;
request.KeepAlive = false;
request.Timeout = 30000;

// Send the Request
requestStream = request.GetRequestStream();
requestStream.Write(data, 0, data.Length);
requestStream.Close();

现在我想使用 Web 服务参考。所以我在 VS 2008 中指出并创建了一个对 https://www.sandbox.paypal.com/wsdl/PayPalSvc.wsdl 的新引用。我现在有了一个 Web 引用。

作为第一次使用 Web 服务的用户,我现在有这些问题,而不是像使用 3rd 方 API 那样手动操作:

1) 如何指定标头参数?例如,某些 API 要求您发送哈希(签名)、会话 ID、用户名、密码,您将其与 API 方法调用请求一起命名。如何使用 Web 服务代理类指定这一点?

2) 请求/响应对象是如何处理的,或者我现在使用 Web 服务/引用不需要担心这一点?我的意思是我还需要创建一个请求对象吗?我将如何接收响应?

3) 当我收到响应时,代理类是否包含它的状态,或者我是否仍然需要创建一个类来保存从 API 方法调用响应返回的数据的状态?网络服务/参考?

4) 我什么时候想要像以前一样只创建自定义代码而不使用 WSDL 的 Web 服务/引用选项?...基本上是创建自己的代理类、请求对象,响应对象,一切?而不是让 VS 吐出基于 WSDL 的 Web 参考?是不是因为它不是基于 SOAP 的第 3 方 API?是不是因为 3rd 方 API 不提供 WSDL,所以你不得不自己手动编写包装器代码?

【问题讨论】:

见msdn.microsoft.com/en-us/netframework/dd939784.aspx 【参考方案1】:

这里有严重的混乱。请大家停下来!

WSE 已过时。不要使用它。

“Web References”与旧的 ASMX Web 服务技术有关。微软现在认为它是“遗留”代码并已停止修复错误。非必要请勿使用。

OP 应该使用“添加服务引用”。我刚刚试了一下,效果很好。


现在,回答您的问题:

    如何指定标头参数?

    由于此服务使用标头,因此代理类已生成为消息契约,它可以具有标头部分和正文部分。例如,RefundTransactionRequest 类有一个RequesterCredentials 属性,它属于CustomSecurityHeaderType 类型。您只需在发送请求之前进行设置。事实上,它已经为RefundTransactionRequest 生成了一个构造函数,该构造函数将header 和body 作为参数,所以这很容易。

    请求/响应对象是如何处理的?

    除了创建类实例和调用方法之外,您无需执行任何操作。所有的序列化都是为你完成的。所有的类创建都是为你完成的。

    当我收到响应时,Proxy 类是否包含它的状态?

    是的。代理类将包含所有消息头和正文部分。当然,只有有输出头才会有头部分。

    我什么时候想要像以前一样只创建自定义代码而不使用 WSDL 的 Web 服务/引用选项?

    从来没有,我想。我从来没有看到这样做的理由。我想唯一的一次是“添加服务引用”中存在错误。


例子:

using (var svc = new PayPalAPIAAInterfaceClient())

    var paypal = (PayPalAPIInterface) svc;
    var credentials = new CustomSecurityHeaderType
                          
                              Credentials =
                                  new UserIdPasswordType
                                      
                                          AppId = "",
                                          Username = "John",
                                          Password = "John"
                                      
                          ;
    var request = new RefundTransactionRequestType
                      
                          Amount =
                              new BasicAmountType
                                  
                                      currencyID = CurrencyCodeType.USD,
                                      Value = "100.00"
                                  ,
                          Memo = "I want my money back",
                          RefundType = RefundType.Full,
                          RefundTypeSpecified = true
                      ;
    var refundRequest = new RefundTransactionReq
                            RefundTransactionRequest = request;
    var result =
        paypal.RefundTransaction(
            new RefundTransactionRequest(credentials, refundRequest));
    var response = result.RefundTransactionResponse1;
    var returnedCredentials = result.RequesterCredentials;

【讨论】:

谢谢。我通常在 MSDN 上找不到这些答案……您刚才所说的推断部分。 我不知道我必须使用他们的对象 (PayPal) 来创建请求并获得响应。我认为这将使用 .NET 对象来完成。现在我明白了。例如,我并没有真正意识到我必须使用 CustomSecurityHeaderType 和 RequesterCredential,因为我的大脑仍在考虑手动模式与 wsdl 上的 Web 服务 约翰只是好奇。我查看了他们的 API。在查看 RefundTransactionRequest 的 API 参考时,您在哪里看到了凭证参数。实际上,您在他们的 API 文档中从哪里看到有关 CustomSecurityHeaderType 或 UserIdPasswordType 的任何信息? 我想知道如果我可以创建任何类来从中提取任何冗余。否则,我认为不需要创建任何东西,只需开始在我的代码中使用代理类即可。我只是想我可以创建一些辅助方法和一个实用程序类,以某种方式抽象出每次我想在我的代码隐藏中使用它时都必须创建和设置 CustomSecurityHeaderType 的冗余 我刚刚查看了 Reference.cs 文件。如果您在解决方案资源管理器中单击您的项目,然后单击解决方案资源管理器工具栏中的“显示所有文件”按钮,您会发现许多文件旁边以及服务引用旁边的“+”号。单击“+”号展开服务参考。最终,您会看到一个 Reference.cs 文件,这是一个 非常 大的文件,其中包含代理类。即使使用 ReSharper 也不是很愉快,而且我不了解显式接口实现的使用,但它得到了上面的代码进行编译。【参考方案2】:

我假设您为此使用了网络参考。在大多数情况下,使用 Web 服务应该像使用本地对象一样简单。 .NET 在幕后处理所有管道。有时这很有效——其他时候则不然。

当您向 PayPal Web 服务添加 Web 引用时,Visual Studio 将在 Web 引用的子文件夹中创建一个名为 reference.cs 的文件,该文件是代理类(默认情况下 VS 2008 隐藏它——您必须“显示所有文件”以查看它)。

对于您的具体情况,PayPal 似乎正在使用自定义 SOAP 标头来传输所有安全上下文信息。查看 CustomSecurityHeaderType 和 UserIdPasswordType 类型以了解更多详细信息。此外,来自 PayPal 的一些文档可能会有所帮助。 :)

要使用该服务,您必须执行以下操作:

    PayPalAPISoapBinding payPal = new PayPalAPISoapBinding();

    CustomSecurityHeaderType customSecurity = new CustomSecurityHeaderType();
    customSecurity.eBayAuthToken = "The Auth Token";

    UserIdPasswordType userId = new UserIdPasswordType();
    userId.Password = "PWD";
    userId.Username = "JIMMY";

    customSecurity.Credentials = userId;

    payPal.RequesterCredentials = customSecurity;

    RefundTransactionReq request = new RefundTransactionReq();

    RefundTransactionResponseType response = payPal.RefundTransaction(request); 

我不熟悉 PayPal 服务,但我认为它应该是这样工作的。

【讨论】:

是的,我将在 .NET 3.5 中使用 Web 引用 有趣,所以你必须使用它们的类型。我不能只创建一个 HTtpWebRequest 和 HttpWebResponse。同样,您正在使用他们的对象来创建作为肥皂头信息传递的内容。 这真的对我有很大帮助。我只是找不到任何例子,所以我求助于在这里发帖。太糟糕了,这意味着我不能只将 .nET 对象完全用于请求/响应属性。 这不像:我可以使用他们的类型。 :( 更像是:是的!我可以使用 他们的 类型。:)【参考方案3】:

1) 在您的情况下,签名、用户名和密码在soap 标头中传输。您需要安装WSE 3.0,在您的VS项目中激活它并再次生成代理。

2) 请求创建和响应解析由 WSE 内部进行。只需创建代理,设置标头并调用代理上的方法。

3) 应该有非常充分的理由来创建代理的自定义实现。 WSE 涵盖 SOAP 场景和 WS-* 规范的一部分。除了 SOAP,WCF 还涵盖 TCP、管道和 MSMQ 传输。即使服务不提供 WSDL,你仍然可以自己指定契约,让框架来做传输工作。

【讨论】:

在 #1 中,所以我必须安装它才能在我的 API 调用中获取一些标头信息? #2,好的,那么如何从响应中检索数据?我不明白你所说的 WSE 内部是什么意思,它在幕后为我做这件事?好的,但我仍然如何获取 x 方法调用的响应数据? 我没有找到任何关于这方面的好文章。我发现的任何东西都是非常***的。我对 WSE 3.0 一无所知,我不明白为什么我需要安装这样的东西作为附加组件来添加 SOAP 标头。如果他们调用外部网络服务,大多数人是否都不需要开箱即用? 绝对不是 WSE 3.0 已过时!除非没有其他选择,否则不应使用它。 我同意,最好在 WCF 学习上投入更多时间并保持最新状态。

以上是关于使用 Web 服务或 Web 服务参考的主要内容,如果未能解决你的问题,请参考以下文章

服务参考与 Web 参考

在 Web 服务中解析数据 Json 或 XML 哪个更快?

如何从 ashx 或 web 服务呈现用户控件?

WSDL 能否指示 Web 服务的 SOAP 版本(1.1 或 1.2)?

Visual Studio/SOAP -“添加服务引用”与“添加 Web 服务引用”

为啥在 Web 服务中使用 complexType?