您的位置:首页 > 其它

转载来的wcf学习笔记04

2008-05-28 16:46 411 查看
WCF 的一切都是围绕着 Message 进行,那么 Message 究竟是什么样子?

[ServiceContract]

public interface ICalculate

{

[OperationContract]

double Add(double a, double b);

}

public class CalculateService : ICalculate

{

public double Add(double a, double b)

{

Message msg = OperationContext.Current.RequestContext.RequestMessage;

Console.WriteLine(msg);

return a + b;

}

}

public class WcfTest

{

public static void Test()

{

AppDomain.CreateDomain("Server").DoCallBack(delegate

{

ServiceHost host = new ServiceHost(typeof(CalculateService));

host.AddServiceEndpoint(typeof(ICalculate), new BasicHttpBinding(),

"http://localhost:8080/calc");

host.Open();

});

ChannelFactory<ICalculate> factory = new ChannelFactory<ICalculate>(new BasicHttpBinding(),

"http://localhost:8080/calc");

ICalculate o = factory.CreateChannel();

Console.WriteLine(o.Add(1, 2));

}

}

输出
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">

<s:Header>

<To s:mustUnderstand="1" xmlns="http://...">http://localhost:8080/calc</To>

<Action s:mustUnderstand="1" xmlns="http://...">http://tempuri.org/ICalculate/Add</Action>

</s:Header>

<s:Body>

<Add xmlns="http://tempuri.org/">

<a>1</a>

<b>2</b>

</Add>

</s:Body>

</s:Envelope>

事实上我们可以直接基于 Message Layer 进行编程,利用 OperationContract.Action 捕获特定 Action 的消息。

[ServiceContract]

public interface ICalculate

{

[OperationContract(Action = "Add", ReplyAction="Add")]

Message ProcessMessage(Message m);

}

public class CalculateService : ICalculate

{

public Message ProcessMessage(Message m)

{

Data d = m.GetBody<Data>();

Console.WriteLine(d.I);

return Message.CreateMessage(MessageVersion.Soap11, "Add", new Data(9999));

}

}

[DataContract]

public class Data

{

[DataMember]

public int I;

public Data(int i)

{

this.I = i;

}

}

public class WcfTest

{

public static void Test()

{

AppDomain.CreateDomain("Server").DoCallBack(delegate

{

ServiceHost host = new ServiceHost(typeof(CalculateService));

host.AddServiceEndpoint(typeof(ICalculate), new BasicHttpBinding(),

"http://localhost:8080/calc");

host.Open();

});

ChannelFactory<IRequestChannel> factory = new ChannelFactory<IRequestChannel>(

new BasicHttpBinding(), "http://localhost:8080/calc");

IRequestChannel channel = factory.CreateChannel();

channel.Open();

Message request = Message.CreateMessage(MessageVersion.Soap11, "Add", new Data(1234));

Message reply = channel.Request(request);

Console.WriteLine("-------------------");

Console.WriteLine(reply);

channel.Close();

factory.Close();

}

}

输出:
1234

-------------------

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">

<s:Header />

<s:Body>

<Data xmlns="http://..." xmlns:i="http://...">

<I>9999</I>

</Data>

</s:Body>

</s:Envelope>


如上面所看到的,所有的调用都被转换成消息后发送。这也符合 SOA 的规范,完全隔离,清晰的边界。(调用
"m.GetBody<Data>()" 后,会导致 Message.State 变更,再次访问会出错,有关详细信息请参考 MSDN
文档。)

我们还可以使用 MessageContractAttribute / MessageHeaderAttribute
来控制消息格式,这比 DataContractAttribute
要更加灵活。我们可以设置消息标头、消息体,包括是否对其中某些进行签名和加密处理。

[ServiceContract]

public interface ICalculate

{

[OperationContract]

void Add(Data d);

}

public class CalculateService : ICalculate

{

public void Add(Data d)

{

Console.WriteLine(OperationContext.Current.RequestContext.RequestMessage);

Console.WriteLine("----------------");

Console.WriteLine("{0}/{1}", d.a, d.b);

}

}

[MessageContract]

public class Data

{

[MessageHeader]

public double a = 1;

[MessageBodyMember]

public double b = 2;

}

public class WcfTest

{

public static void Test()

{

AppDomain.CreateDomain("Server").DoCallBack(delegate

{

ServiceHost host = new ServiceHost(typeof(CalculateService));

host.AddServiceEndpoint(typeof(ICalculate), new BasicHttpBinding(),

"http://localhost:8080/calc");

host.Open();

});

ChannelFactory<ICalculate> factory = new ChannelFactory<ICalculate>(new BasicHttpBinding(),

"http://localhost:8080/calc");

ICalculate o = factory.CreateChannel();

Data d = new Data();

d.a = 1234;

d.b = 5678;

o.Add(d);

}

}

输出:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">

<s:Header>

<h:a xmlns:h="http://tempuri.org/">1</h:a>

<To s:mustUnderstand="1" xmlns="http://s...">http://localhost:8080/calc</To>

<Action s:mustUnderstand="1" xmlns="http://...">http://tempuri.org/ICalculate/Add</Action>

</s:Header>

<s:Body>

<Data xmlns="http://tempuri.org/">

<b>2</b>

</Data>

</s:Body>

</s:Envelope>

----------------

1234/5678

有关 Message 更详细的信息,可以参考 MSDN (Microsoft Windows SDK) 文档。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: