热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

[WCF学习笔记]4.消息操作

WCF的一切都是围绕着Message进行,那么Message究竟是什么样子?[ServiceContract]publicinterfaceICalcu

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 factory = new ChannelFactory(new BasicHttpBinding(),
      "http://localhost:8080/calc");
    ICalculate o = factory.CreateChannel();
    Console.WriteLine(o.Add(1, 2));
  }
}

 

输出


  
    http://localhost:8080/calc
    http://tempuri.org/ICalculate/Add
  

  
    
      1
      2
    

  



事实上我们可以直接基于 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();
    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 factory = new ChannelFactory(
      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
-------------------

  
  
    
      9999
    

  



正 如上面所看到的,所有的调用都被转换成消息后发送。这也符合 SOA 的规范,完全隔离,清晰的边界。(调用 "m.GetBody()" 后,会导致 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 factory = new ChannelFactory(new BasicHttpBinding(),
      "http://localhost:8080/calc");
    ICalculate o = factory.CreateChannel();

    Data d = new Data();
    d.a = 1234;
    d.b = 5678;
    o.Add(d);
  }
}


输出:


  
    1
    http://localhost:8080/calc
    http://tempuri.org/ICalculate/Add
  

  
    
      2
    

  


----------------
1234/5678


有关 Message 更详细的信息,可以参考 MSDN (Microsoft Windows SDK) 文档。


推荐阅读
  • 本文提供了一个Android应用中用于抓取网页信息并下载图片的示例代码。通过该代码,开发者可以轻松实现从指定URL获取网页内容及其中的图片资源。 ... [详细]
  • 使用EF Core在.Net Core控制台应用中操作SQLite数据库
    本文介绍如何利用Visual Studio 2019和Windows 10环境,通过Entity Framework Core(EF Core)实现对SQLite数据库的读写操作。项目源代码可从百度网盘下载。 ... [详细]
  • 设计模式系列-原型模式
    一、上篇回顾上篇创建者模式中,我们主要讲述了创建者的几类实现方案,和创建者模式的应用的场景和特点,创建者模式适合创建复杂的对象,并且这些对象的每个组成部分的详细创建步骤可以是动态的变化的,但 ... [详细]
  • 本文探讨了在Node.js环境中如何有效地捕获标准输出(stdout)的内容,并将其存储到变量中。通过具体的示例和解决方案,帮助开发者解决常见的输出捕获问题。 ... [详细]
  • 本文深入探讨了JLine库中的ConsoleReader.drawBuffer()方法的使用场景和具体实现,通过多个实际代码示例,帮助开发者更好地理解和应用此方法。 ... [详细]
  • 微信小程序支付官方参数小程序中代码后端发起支付代码支付回调官方参数文档地址:https:developers.weixin.qq.comminiprogramdeva ... [详细]
  • 万事起于配置开发环境
    万事起于配置开发环境 ... [详细]
  • 深入解析轻量级数据库 SQL Server Express LocalDB
    本文详细介绍了 SQL Server Express LocalDB,这是一种轻量级的本地 T-SQL 数据库解决方案,特别适合开发环境使用。文章还探讨了 LocalDB 与其他轻量级数据库的对比,并提供了安装和连接 LocalDB 的步骤。 ... [详细]
  • 为什么会崩溃? ... [详细]
  • 本文介绍了一个基本的同步Socket程序,演示了如何实现客户端与服务器之间的简单消息传递。此外,文章还概述了Socket的基本工作流程,并计划在未来探讨同步与异步Socket的区别。 ... [详细]
  • 本文介绍了如何通过创建自定义 XML 文件来修改 Android 中 Spinner 的项样式,包括颜色和大小的调整。 ... [详细]
  • Lua字符串1.字符串常见形式字符串或串(String)是由数字、字母、下划线组成的一串字符。Lua语言中字符串可以使用以下三种方式来表示:•单引号间的一串字符。 ... [详细]
  • java datarow_DataSet  DataTable DataRow 深入浅出
    本篇文章适合有一定的基础的人去查看,最好学习过一定net编程基础在来查看此文章。1.概念DataSet是ADO.NET的中心概念。可以把DataSet当成内存中的数据 ... [详细]
  • 在AngularJS中,有时需要在表单内包含某些控件,但又不希望这些控件导致表单变为脏状态。例如,当用户对表单进行修改后,表单的$dirty属性将变为true,触发保存对话框。然而,对于一些导航或辅助功能控件,我们可能并不希望它们触发这种行为。 ... [详细]
  • ArcBlock 发布 ABT 节点 1.0.31 版本更新
    2020年11月9日,ArcBlock 区块链基础平台发布了 ABT 节点开发平台的1.0.31版本更新,此次更新带来了多项功能增强与性能优化。 ... [详细]
author-avatar
x47608476
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有