简体   繁体   中英

Converting ASMX contracts to WCF

I have an older webservice I need to convert into a new system which isn't hosted in IIS, so I can't copy it directly. I can create self hosted WCF services so I could put the functionality there instead. However, I can't get the contracts to match up as the client we already have gives the following exception when connecting to the webservice:

The message with action ' http://services.mysite.com/MyService/MyMethod ' cannot be processed at the receiver, due to a ContractFilter mismatch at the EndpointDispatcher.

I read in some other SO posts that I could ensure the contract would be the same by running the following in a command prompt:

wsdl.exe /serverInterface http://oldservices.mysite.com/MyService.asmx?WSDL

This command generates some code which, according to the documentation , "Generates interfaces for server implementation".

I took this code into my new solution and got it to start (after adding some extra attributes, and also prettifying the code), and I can call MyMethod successfully from WebService Studio and get the expected results. However, the old client still complains with the same exception.

What must I do to successfully convert an old ASMX webservice into a fully compatible WCF service?

WSDL of old ASMX webservice @ Pastebin

Generated Server Interface (from wsdl.exe) @ Pastebin

My adjusted interface

[WebServiceBinding(Name = "MyServiceSoap", Namespace = "http://services.mysite.com/MyService")]
[XmlInclude(typeof(Foo))]
[XmlInclude(typeof(Bar))]
[ServiceContract]
[ServiceKnownType(typeof(Foo))]
[ServiceKnownType(typeof(Bar))]
public interface IMyServiceSoap {

    [OperationContract, XmlSerializerFormat(Style = OperationFormatStyle.Document)]
    [WebMethod]
    [SoapDocumentMethod("http://services.mysite.com/MyService/MyMethod", RequestNamespace = "http://services.mysite.com/MyService", ResponseNamespace = "http://services.mysite.com/MyService", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]

    ReturnMessage MyMethod();
}

My adjusted type definitions

[Serializable]
[XmlType(Namespace = "http://services.mysite.com/MyService")]
public class ReturnMessage {
    public ReturnStatus Status { get; set; }
    public object GenericReturn { get; set; }
}

[Serializable]
[XmlType(Namespace = "http://services.mysite.com/MyService")]
public enum ReturnStatus {
}

[Serializable]
[XmlType(Namespace = "http://services.mysite.com/MyService")]
public class Foo {
    public string Text { get; set; }
}

[Serializable]
[XmlType(Namespace = "http://services.mysite.com/MyService")]
public class Bar {
    public int Number{ get; set; }
}

Implementation class

public class MyServiceSoap : IMyServiceSoap {
    public ReturnMessage MyMethod() {
        return new ReturnMessage() { Status = ReturnStatus.OK, GenericReturn = new Foo() };
    }
}

WCF starter

ServiceHost host = new ServiceHost(typeof(MyServiceSoap), new Uri("http://localhost:8080/MyService.asmx"));
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy12;
host.Description.Behaviors.Add(smb);
host.Open();

I finally got a push in the right direction on another forum, which pointed me to this page . What I had previously found about wsdl.exe proved to be incorrect. Instead you have to run the following command:

SvcUtil.exe /serviceContract http://oldservices.mysite.com/MyService.asmx?WSDL

This generates a file you can adjust and prettify (just don't change any of the classnames).

Then start the WCF service as I did above, with one additional line:

smb.ExternalMetadataLocation = new Uri("http://localhost:8080/wsdl/MyService.wsdl");

The WSDL file referred there has to be the same WSDL as your old service generates. Just save the autogenerated WSDL file to your new server and remember to change address locations at the bottom of the file to point to your new service (instead of your old one) and you should be ready to go!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM