我正在尝试为WSE3 / ASMX Web服务编写WCF包装器Web服务。 [丑陋的原因是第三方供应商不支持SSL,这是BizTalk 2009 WCF适配器与WS-Security一起使用所需的。因此,如果供应商没有改变 - 我需要调用本地WCF Web服务...]
我按照这篇文章来获取VS2008内置的WSE3代理构建器: http://blogs.imeta.co.uk/jyoung/archive/2008/08/29/345.aspx 我对供应商的.asmx远程Web服务进行了Web引用。
我在本地构建并发布我的webservice,并尝试在浏览器中显示它,并收到此错误:
System.InvalidOperationException:An 在调用a时抛出了异常 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')serializeable?是否有可能实现我的目标?
谢谢,
Neal Walters
<小时/> 附加信息 - 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.Addressing.Address” 在这里,当我对Microsoft.Web.Services3.WebServicesClientProtocol进行“定义”时的元数据
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”只是这样的对象之一。
答案 0 :(得分:1)
你不能在“事后”制作可序列化的东西。问题是:你需要什么“地址”?
你是否可以更改你的WCF包装器,以便你将一个地址(如果那是我怀疑的URL)作为从客户端到你的WCF服务的字符串传递,然后在你的内部创建一个“地址”实例WCF服务类?
答案 1 :(得分:1)
好的,这是问题所在。我变得有点混乱,迷失在这个应用程序的复杂性中,它暴露了4个服务和几十个方法,并且第一次使用来自WCF的WSE3。
错误是因为我写的包装器试图返回ValuationService本身。那是一个愚蠢的错误。 ValuationService确实实现了Microsoft.Web.WebServices3.WebServicesClientProtocol,其中包含导致问题的Addressing类。
包装器应该使用ValuationService作为客户端,并仅返回Valuation(或ValuationResult)。 valuResult当然只是一个由字符串,小数,布尔值等组成的对象......可以序列化。