views:

176

answers:

2

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/%3AIValuationService ----> 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.

+1  A: 

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?

marc_s
How do I get rid of 'Microsoft.Web.Services3.Addressing.Address'? It seems to be "inserting itself. It's nothing I wanted to specifically include.
NealWalters
Solved - see my answer below.
NealWalters
OK, glad you could solve it!
marc_s
+1  A: 

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.

NealWalters