2

我正在尝试为 WSE3/ASMX Web 服务编写 WCF 包装器 Web 服务。[丑陋的原因是第 3 方供应商不支持 SSL,而这正是 BizTalk 2009 WCF 适配器与 WS-Security 一起工作所需要的。因此,如果供应商没有改变 - 我需要调用本地 WCF Web 服务...]

我按照这篇文章获得了 VS2008 内置的 WSE3 代理构建器:http: //blogs.imeta.co.uk/jyoung/archive/2008/08/29/345.aspx 我对供应商的.asmx 远程网络服务。

我在本地构建和发布我的 web 服务,然后尝试在浏览器中打开它,然后得到这个错误:

System.InvalidOperationException:在调用 WSDL 导出扩展时引发异常:System.ServiceModel.Description.DataContractSerializerOperationBehavior 合同: http ://tempuri.org/:IValuationService ----> System.Runtime.Serialization.InvalidDataContractException:类型'Microsoft.Web.Services3.Addressing.Address' 无法序列化。考虑使用 DataContractAttribute 属性对其进行标记,并使用 DataMemberAttribute 属性标记您想要序列化的所有成员。有关其他支持的类型,请参阅 Microsoft .NET Framework 文档。

如何使我没有编写的对象('Microsoft.Web.Services3.Addressing.Address')可序列化?有可能完成我正在尝试的事情吗?

谢谢,

尼尔·沃尔特斯


附加信息 - 2009 年 11 月 16 日星期一:


[ServiceContract]
public interface IValuationService
{
    [OperationContract]
    ExpressLync.ValuationServiceWse GetPropertyInfoSourceRecordPolicyNum(string PolicyNumber);
}
// end of interface 

// here is part of reference.cs...
public partial class ValuationServiceWse : Microsoft.Web.Services3.WebServicesClientProtocol {
...

当我对 Microsoft.Web.Services3.WebServicesClientProtocol 进行“转到定义”时,我唯一能在元数据上找到对“Microsoft.Web.Services3.Addressing.Address”的任何引用的地方

using Microsoft.Web.Services3.Addressing;
using Microsoft.Web.Services3.Design;
using System;
using System.Net;
using System.Web.Services.Protocols;
using System.Xml;

namespace Microsoft.Web.Services3
{
    public class WebServicesClientProtocol : SoapHttpClientProtocol
    {
        public WebServicesClientProtocol();

        public EndpointReference Destination { get; set; }
        public Pipeline Pipeline { get; set; }
        public SoapContext RequestSoapContext { get; }
        public bool RequireMtom { get; set; }
        public SoapContext ResponseSoapContext { get; }
        public string Url { get; set; }
        public bool UseDefaultCredentials { get; set; }

        public TSecurityToken GetClientCredential<TSecurityToken>() where TSecurityToken : Microsoft.Web.Services3.Security.Tokens.SecurityToken;
        protected override XmlReader GetReaderForMessage(SoapClientMessage message, int bufferSize);
        public TSecurityToken GetServiceCredential<TSecurityToken>() where TSecurityToken : Microsoft.Web.Services3.Security.Tokens.SecurityToken;
        protected override WebRequest GetWebRequest(Uri uri);
        protected override WebResponse GetWebResponse(WebRequest request);
        protected override WebResponse GetWebResponse(WebRequest request, IAsyncResult result);
        protected override XmlWriter GetWriterForMessage(SoapClientMessage message, int bufferSize);
        public void SetClientCredential<TSecurityToken>(TSecurityToken clientToken) where TSecurityToken : Microsoft.Web.Services3.Security.Tokens.SecurityToken;
        public void SetPolicy(Policy policy);
        public void SetPolicy(string policyName);
        public void SetServiceCredential<TSecurityToken>(TSecurityToken serviceToken) where TSecurityToken : Microsoft.Web.Services3.Security.Tokens.SecurityToken;
    }
}

换句话说,我如何摆脱“Microsoft.Web.Services3.Addressing.Address”?EndpointReference 似乎在“Microsoft.Web.Services3.Addressing.Address”对象中。因此,如果我使用 WSE3 生成的代码,它会尝试对其进行序列化。

所以我认为解决方案将是编写另一个 WSE3 免费的包装器 - 并通过 WCF 公开它。但诀窍在于,供应商的 Web 服务有许多大而复杂的对象——现在它们都继承自 Microsoft.Web.Services3.WebServicesClientProtocol(因为我使用的是 WS3 代码生成器)。我真的不想再次手动构建所有这些。在上面的示例中,“ValuationService”只是此类对象之一。

4

2 回答 2

1

您不能“事后”制作可序列化的东西。问题是:你需要那个“地址”做什么?

您能否更改您的 WCF 包装器,以便将地址(如果我怀疑这是一个 URL)作为字符串从您的客户端传递到您的 WCF 服务,然后在您的 WCF 服务类中创建一个“地址”实例?

于 2009-11-14T13:07:42.397 回答
1

好的,这就是问题所在。我对这个应用程序的复杂性感到有些不知所措,它公开了 4 个服务和数十种方法,并且是第一次使用 WCF 中的 WSE3。

错误是因为我编写的包装器试图返回 ValuationService 本身。那是个愚蠢的错误。ValuationService 确实实现了 Microsoft.Web.WebServices3.WebServicesClientProtocol,其中包括导致问题的 Addressing 类。

包装器应该使用 ValuationService 作为客户端,并且只返回 Valuation(或 ValuationResult)。估值结果当然只是一个由字符串、小数、布尔值等组成的对象……可以序列化。

于 2009-11-16T15:44:31.703 回答