Une répartition systématique du problème suit. [Réécriture!]Impossible d'utiliser la définition WSDL
Le code client
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
// This is a "sanitized" version of the real deal, of course. In reality I also require to
// sign all incomming and outgoing messages and com. over SSL. The basic model is the same
// though and the sanitized WSDL captures the problem in its minimal form.
namespace MissileDefenseSystem
{
using MissileDefenseSystemServiceReference;
class Program
{
static void Main(string[] args)
{
try
{
var client = new TestPortTypeClient();
var req = "just do it";
Console.WriteLine("request>" + req + "<");
var rsp = client.LaunchMissiles(req);
Console.WriteLine("response>" + rsp + "<");
}
catch (Exception e)
{
Console.WriteLine("exception>" + e.Message + "<");
Console.WriteLine(e.StackTrace);
}
}
}
}
Le WSDL
<?xml version="1.0" encoding="ISO-8859-1"?>
<definitions targetNamespace="java:bla.bla.bla.bla"
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:tns="java:bla.bla.bla.bla"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
<types>
<schema targetNamespace='java:bla.bla.bla.bla' xmlns='http://www.w3.org/2001/XMLSchema'/>
</types>
<message name="TestRequest">
<part name="arg0" type="xsd:string"/>
</message>
<message name="TestResponse">
<part name="return" type="xsd:string"/>
</message>
<portType name="TestPortType">
<operation name="LaunchMissiles">
<input message="tns:TestRequest"/>
<output message="tns:TestResponse"/>
</operation>
<operation name="AbortMission">
<input message="tns:TestRequest"/>
<output message="tns:TestResponse"/>
</operation>
</portType>
<binding name="TestBinding" type="tns:TestPortType">
<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="LaunchMissiles">
<soap:operation soapAction="urn:LaunchMissiles"/>
<input>
<soap:body use="encoded" namespace='urn:Test' encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
</input>
<output>
<soap:body use="encoded" namespace='urn:Test' encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
</output>
</operation>
<operation name="AbortMission">
<soap:operation soapAction="urn:AbortMission"/>
<input>
<soap:body use="encoded" namespace='urn:Test' encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
</input>
<output>
<soap:body use="encoded" namespace='urn:Test' encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
</output>
</operation>
</binding>
<service name="Test">
<documentation>todo</documentation>
<port name="TestPort" binding="tns:TestBinding">
<soap:address location="https://demo.blablablablablabla.com:123/Bla"/>
</port>
</service>
</definitions>
La trace d'erreur
request>just do it<
exception>RPC Message LaunchMissilesRequest in operation AbortMission has an invalid body name LaunchMissiles. It must be AbortMission<
at System.ServiceModel.Description.XmlSerializerOperationBehavior.Reflector.OperationReflector.EnsureMessageInfos()
at System.ServiceModel.Description.XmlSerializerOperationBehavior.Reflector.EnsureMessageInfos()
at System.ServiceModel.Description.XmlSerializerOperationBehavior.Reflector.OperationReflector.get_Request()
at System.ServiceModel.Description.XmlSerializerOperationBehavior.CreateFormatter()
at System.ServiceModel.Description.XmlSerializerOperationBehavior.System.ServiceModel.Description.IOperationBehavior.ApplyClientBehavior(OperationDescription description, ClientOperation proxy)
at System.ServiceModel.Description.DispatcherBuilder.BindOperations(ContractDescription contract, ClientRuntime proxy, DispatchRuntime dispatch)
at System.ServiceModel.Description.DispatcherBuilder.ApplyClientBehavior(ServiceEndpoint serviceEndpoint, ClientRuntime clientRuntime)
at System.ServiceModel.Description.DispatcherBuilder.BuildProxyBehavior(ServiceEndpoint serviceEndpoint, BindingParameterCollection& parameters)
at System.ServiceModel.Channels.ServiceChannelFactory.BuildChannelFactory(ServiceEndpoint serviceEndpoint)
at System.ServiceModel.ChannelFactory.CreateFactory()
at System.ServiceModel.ChannelFactory.OnOpening()
at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
at System.ServiceModel.ChannelFactory.EnsureOpened()
at System.ServiceModel.ChannelFactory`1.CreateChannel(EndpointAddress address, Uri via)
at System.ServiceModel.ChannelFactory`1.CreateChannel()
at System.ServiceModel.ClientBase`1.CreateChannel()
at System.ServiceModel.ClientBase`1.CreateChannelInternal()
at System.ServiceModel.ClientBase`1.get_Channel()
at MissileDefenseSystem.MissileDefenseSystemServiceReference.TestPortTypeClient.MissileDefenseSystem.MissileDefenseSystemServiceReference.TestPortType.LaunchMissiles(LaunchMissilesRequest request) in C:\Users\bra\Documents\Visual Studio 2008\Projects\MissileDefenseSystem\MissileDefenseSystem\Service References\MissileDefenseSystemServiceReference\Reference.cs:line 90
at MissileDefenseSystem.MissileDefenseSystemServiceReference.TestPortTypeClient.LaunchMissiles(String arg0) in C:\Users\bra\Documents\Visual Studio 2008\Projects\MissileDefenseSystem\MissileDefenseSystem\Service References\MissileDefenseSystemServiceReference\Reference.cs:line 96
at MissileDefenseSystem.Program.Main(String[] args) in C:\Users\bra\Documents\Visual Studio 2008\Projects\MissileDefenseSystem\MissileDefenseSystem\Program.cs:line 22
Le a généré le code de proxy à l'aide de Visual Studio 2008 (SvcUtil.exe).
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:2.0.50727.3074
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(Namespace="java:bla.bla.bla.bla", ConfigurationName="TestPortType")]
public interface TestPortType
{
// CODEGEN: Generating message contract since the wrapper namespace (urn:Test) of message LaunchMissilesRequest does not match the default value (java:bla.bla.bla.bla)
[System.ServiceModel.OperationContractAttribute(Action="urn:LaunchMissiles", ReplyAction="*")]
[System.ServiceModel.XmlSerializerFormatAttribute(Style=System.ServiceModel.OperationFormatStyle.Rpc, Use=System.ServiceModel.OperationFormatUse.Encoded)]
LaunchMissilesResponse LaunchMissiles(LaunchMissilesRequest request);
// CODEGEN: Generating message contract since the wrapper namespace (urn:Test) of message AbortMissionRequest does not match the default value (java:bla.bla.bla.bla)
[System.ServiceModel.OperationContractAttribute(Action="urn:AbortMission", ReplyAction="*")]
[System.ServiceModel.XmlSerializerFormatAttribute(Style=System.ServiceModel.OperationFormatStyle.Rpc, Use=System.ServiceModel.OperationFormatUse.Encoded)]
LaunchMissilesResponse AbortMission(LaunchMissilesRequest request);
}
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
[System.ServiceModel.MessageContractAttribute(WrapperName="LaunchMissiles", WrapperNamespace="urn:Test", IsWrapped=true)]
public partial class LaunchMissilesRequest
{
[System.ServiceModel.MessageBodyMemberAttribute(Namespace="", Order=0)]
public string arg0;
public LaunchMissilesRequest()
{
}
public LaunchMissilesRequest(string arg0)
{
this.arg0 = arg0;
}
}
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
[System.ServiceModel.MessageContractAttribute(WrapperName="LaunchMissilesResponse", WrapperNamespace="urn:Test", IsWrapped=true)]
public partial class LaunchMissilesResponse
{
[System.ServiceModel.MessageBodyMemberAttribute(Namespace="", Order=0)]
public string @return;
public LaunchMissilesResponse()
{
}
public LaunchMissilesResponse(string @return)
{
[email protected] = @return;
}
}
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
public interface TestPortTypeChannel : TestPortType, System.ServiceModel.IClientChannel
{
}
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
public partial class TestPortTypeClient : System.ServiceModel.ClientBase<TestPortType>, TestPortType
{
public TestPortTypeClient()
{
}
public TestPortTypeClient(string endpointConfigurationName) :
base(endpointConfigurationName)
{
}
public TestPortTypeClient(string endpointConfigurationName, string remoteAddress) :
base(endpointConfigurationName, remoteAddress)
{
}
public TestPortTypeClient(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) :
base(endpointConfigurationName, remoteAddress)
{
}
public TestPortTypeClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) :
base(binding, remoteAddress)
{
}
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
LaunchMissilesResponse TestPortType.LaunchMissiles(LaunchMissilesRequest request)
{
return base.Channel.LaunchMissiles(request);
}
public string LaunchMissiles(string arg0)
{
LaunchMissilesRequest inValue = new LaunchMissilesRequest();
inValue.arg0 = arg0;
LaunchMissilesResponse retVal = ((TestPortType)(this)).LaunchMissiles(inValue);
return [email protected];
}
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
LaunchMissilesResponse TestPortType.AbortMission(LaunchMissilesRequest request)
{
return base.Channel.AbortMission(request);
}
public string AbortMission(string arg0)
{
LaunchMissilesRequest inValue = new LaunchMissilesRequest();
inValue.arg0 = arg0;
LaunchMissilesResponse retVal = ((TestPortType)(this)).AbortMission(inValue);
return [email protected];
}
}
est d'utiliser le code proxy généré par SvcUtil.exe.
Télécharger le projet Visual Studio fichiers ici:
http://dl.getdropbox.com/u/797094/MissileDefenseSystem.zip
Maintenant, je viens d'essayer de nouveau en utilisant le WSDL.exe. Cela fonctionne mieux, mais maintenant le prochain problème se dresse c'est laide tête. Le fichier app.config pour WCF n'est pas utilisé. J'ai donc besoin de configurer la classe proxy pour utiliser un certificat. Pour WCF Je dis simplement
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="TestBinding"/>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="https://demo.blablablablablabla.com:123/Bla"
binding="basicHttpBinding" bindingConfiguration="TestBinding"
contract="MissileDefenseSystemServiceReference.TestPortType"
name="TestPort">
<identity>
<certificateReference storeLocation="CurrentUser" x509FindType="FindByThumbprint"
findValue="the thumbprint to be used" />
</identity>
</endpoint>
</client>
</system.serviceModel>
</configuration>
OK, en utilisant maintenant un morceau de code pour fournir des signatures
proxy.ClientCertificates.Add(cert);
Ce fonctionne maintenant presque, sauf qu'il ne peut pas décoder la réponse.
pour la clarification sur demande/réponse - voir ma mise à jour pour ce que génère wsdl.exe; semble beaucoup plus raisonnable. Version courte: utilisez wsdl.exe pour cela! –
BTW, je n'étais pas au courant que java: était un espace de noms XML valide. Est-ce que quelqu'un l'a enregistré, et si oui, une URL pour le format? –
Il doit s'agir d'un URI absolu valide, qui est la seule exigence pour tout espace de noms XML. Le schéma URI est propriétaire, mais cela ne devrait pas avoir d'importance. Aucune idée sur les inscriptions possibles. –