我花了5个小时才完成这个,而且我已经花了30个小时写这个合约第一个规格(“激进”的截止日期,笨蛋),我看不出我错过了什么。
我不希望单向操作,因为我预计会出现故障。我已经构建了一个简单的WCF服务并检查了它生成的WSDL,并且它 往返于void方法但是我一直在盯着它这么长时间(并且WSDL 1.1非常讨厌最好的时候 - 请点击2.0)我再也看不出魔术是什么了。
任何人都可以提供一些非常简单的WSDL解释魔术吗?我用这个WSDL瞄准了jax-ws 2.2和WCF 3.5 / 4.0。我正在手写WSDL,每次我尝试构建代理(在java或.net中)时,它总是使用返回消息构建一个方法。我输了。
答案 0 :(得分:3)
“void”方法并不一定意味着它是单向操作。以下两个操作是不同的:
[ServiceContract]
public interface ITest
{
[OperationContract(IsOneWay = true)]
void Process1();
[OperationContract]
void Process2();
}
第一个实际上是一个单向操作 - 服务器抛出的任何异常/错误都不会传播到客户端,而在第二个操作中,虽然它没有“返回”任何东西,但是如果服务器抛出例外(例如,FaultException
),异常将返回给调用者。
更新:为了回答标题中提出的问题,如果操作的输出消息的模式是,则WSDL解析器决定生成void操作(至少是WCF使用的操作)空。
例如,在下面的代码中:
public class StackOverflow_8316567
{
[ServiceContract]
public interface ITest
{
[OperationContract(IsOneWay = true)]
void Process1();
[OperationContract]
void Process2();
[OperationContract]
int Add(int x, int y);
}
public class Service : ITest
{
public void Process1() { }
public void Process2() { }
public int Add(int x, int y) { return x + y; }
}
static Binding GetBinding()
{
var result = new BasicHttpBinding();
return result;
}
public static void Test()
{
string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
host.AddServiceEndpoint(typeof(ITest), GetBinding(), "");
host.Description.Behaviors.Add(new ServiceMetadataBehavior { HttpGetEnabled = true });
host.Open();
Console.WriteLine("Host opened");
Console.Write("Press ENTER to close the host");
Console.ReadLine();
host.Close();
}
}
如果您运行它并浏览到http://localhost:8000/service?wsdl,您会看到:
Process1
(在wsdl:portType / wsdl:operation下)只有输入消息Add
和Process2
(r / r操作)都有输入和输出消息现在,这两个操作的输出消息的消息部分在导入的模式(http://localhost:8000/service?xsd=xsd0)中引用它们的模式。你可以看到:
Process2
操作(复杂类型Process2Response
)的响应模式是一个空元素(即空序列)Add
操作(AddResponse
)的响应架构是一个包含一个元素(xs:int
值)的序列。因此处理器将为void
生成Process2
方法(因为它不返回任何内容)和Add
的非空方法。