“Microsoft.Web.Services3.Addressing.Address”无法序列化
我正在尝试为 WSE3/ASMX Web 服务编写 WCF 包装器 Web 服务。 [丑陋的原因是第三方供应商不支持 SSL,而这正是 BizTalk 2009 WCF 适配器与 WS-Security 配合使用所需要的。因此,如果供应商没有改变 - 我需要调用本地 WCF Web 服务...]
我按照这篇文章将 WSE3 代理构建器内置到 VS2008: http://blogs.imeta.co.uk/ jyoung/archive/2008/08/29/345.aspx 我对供应商的 .asmx 远程 Web 服务进行了 Web 引用。
我在本地构建并发布我的网络服务,然后尝试在浏览器中启动它,并收到此错误:
System.InvalidOperationException:一个 调用时抛出异常 WSDL 导出扩展: System.ServiceModel.Description.DataContractSerializerOperationBehavior 合同: http://tempuri.org/:IValuationService ----> System.Runtime.Serialization.InvalidDataContractException: 类型 'Microsoft.Web.Services3.Addressing.Address' 无法序列化。考虑标记 它与 DataContractAttribute 属性,并标记其所有 您想要序列化的成员 DataMemberAttribute 属性。看 微软.NET框架 其他受支持的文档 类型。
如何使我没有编写的对象(“Microsoft.Web.Services3.Addressing.Address”)可序列化?有可能完成我正在尝试的事情吗?
谢谢,
尼尔·沃尔特斯
Additional Info - Monday Nov 16, 2009:
[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”只是此类对象之一。
I'm trying to write a WCF wrapper web service for a WSE3/ASMX web service.
[The ugly reason why is that a 3rd party vendor won't support SSL and that is what's needed for BizTalk 2009 WCF adapter to work with WS-Security. So if the vendor doesn't change - I need to call a local WCF web service...]
I followed this article to get the WSE3 proxy-builder built-in to VS2008:
http://blogs.imeta.co.uk/jyoung/archive/2008/08/29/345.aspx
I make a web reference to the vendor's .asmx remote web service.
I build and publish my webservice locally, and just try to bring it up in the browser, and get this error:
System.InvalidOperationException: An
exception was thrown in a call to a
WSDL export extension:
System.ServiceModel.Description.DataContractSerializerOperationBehavior
contract:
http://tempuri.org/:IValuationService
----> System.Runtime.Serialization.InvalidDataContractException:
Type
'Microsoft.Web.Services3.Addressing.Address'
cannot be serialized. Consider marking
it with the DataContractAttribute
attribute, and marking all of its
members you want serialized with the
DataMemberAttribute attribute. See
the Microsoft .NET Framework
documentation for other supported
types.
How can I make an object that I didn't write ('Microsoft.Web.Services3.Addressing.Address') serializeable? Is it possible to accomplish what I am trying?
Thanks,
Neal Walters
Additional Info - Monday Nov 16, 2009:
[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 {
...
The only place I can find any reference what-so-ever to 'Microsoft.Web.Services3.Addressing.Address'
is here, on the metadata when I do a "go to definition" of the 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;
}
}
So in other words, how do I get rid of 'Microsoft.Web.Services3.Addressing.Address'?
It seems that EndpointReference is in the 'Microsoft.Web.Services3.Addressing.Address' object. So if I use the WSE3 generated code, it tries to serialize it.
So I think the solution will be to write yet another wrapper that is WSE3 free - and expose it via WCF. But the trick is that the vendors web services has numerous large and complex objects - which now all inherit from Microsoft.Web.Services3.WebServicesClientProtocol (since I'm using the WS3 code generator). I really don't want to manually build all of them again. In the example above, "ValuationService" is just one of such objects.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
你不能“事后”让某些东西可序列化。问题是:您需要这个“地址”做什么?
您是否可以更改 WCF 包装器,以便将地址(如果我怀疑是 URL)作为字符串从客户端传递到 WCF 服务,然后在 WCF 服务类中创建“Address”的实例?
You can't make something serializable "after the fact". The question is: what do you need that "Address" for?
Could you possibly change your WCF wrapper so that you'd be passing an address (if that's an URL as I suspect) as a string from your client to your WCF service, and then create an instance of "Address" inside your WCF service class?
好吧,问题就在这里。我对这个应用程序的复杂性感到有点困惑,它公开了 4 个服务和数十个方法,并且是第一次使用 WCF 的 WSE3。
该错误是因为我编写的包装器试图返回 ValuationService 本身。那是一个愚蠢的错误。 ValuationService 确实实现了 Microsoft.Web.WebServices3.WebServicesClientProtocol,其中包括导致问题的 Addressing 类。
包装器应该使用 ValuationService 作为客户端,并且仅返回 Valuation(或 ValuationResult)。 valuationResult 当然只是一个由字符串、小数、布尔值等组成的对象......可以序列化。
Okay, here was the problem. I was getting a little cloudy and lost in the complexity of this application which exposes 4 services and dozens of methods, and the first time to ever use WSE3 from WCF.
The error was because the wrapper I wrote was trying to return the ValuationService itself. That was a dumb mistake. The ValuationService did implement the Microsoft.Web.WebServices3.WebServicesClientProtocol which included the Addressing class which was causing the problem.
The wrapper was supposed to use the ValuationService as a client, and return only the Valuation (or ValuationResult). The valuationResult is of course just an object consisting of strings, decimals, booleans, etc... which can be serialized.