WCF中使用MSMQ无法传送自定义对象

在WCF中使用NetMsmqBinding时,若服务协定涉及自定义对象,如MyDataItem,未指定命名空间会导致序列化失败,表现为服务端收到的对象属性全为默认值。解决方法是在自定义对象上添加[DataContract]特性并指定Namespace。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

WCF中使用MSMQ无法传送自定义对象

WCF在底层使用操作系统的MSMQ实现离线的队列操作,并为此提供了一个NetMsmqBinding。

通过精心的设计,在WCF中使用NetMsmqBinding与使用其他绑定的编程方式是一致的。

然而,这里面有一个容易忽视的地方。那就是要注意在服务协定中要使用自定义对象的问题。

一个例子如下所示:

[ServiceContract]
    public interface IWCFMSMQTransactionService
    {
        [OperationContract(IsOneWay=true)]
        void SendMessage(MyDataItem data);
    }

上述服务协定要使用自定义类型MyDataItem ,它的声明如下 :

    [DataContract]
    public class MyDataItem
    {
        [DataMember]
        public int IntValue
        {
            get;
            set;
        }
        [DataMember]
        public string StringValue
        {
            get;
            set;
        }
    }

你会发现,如果使用NetMsmqBinding绑定时,客户端将无法将一个MyDataItem对象序列化并传送到服务端。并且,整个程序不会引发任何异常,只是服务端反序列化出来的MyDataItem对象的属性全部具有默认值。

解决方法很简单:

给MyDataItem加上一个命名空间:

 [DataContract(Namespace="http://www.bit.edu.cn/CS")]
    public class MyDataItem
    {
        [DataMember]
        public int IntValue
        {
            get;
            set;
        }
       //代码略      

    }

则一切工作正常。

原因何在?

其实,这是因为MSMQ的问题。默认设置下,MSMQ使用XmlMessageFormatter序列化对象,对象被转换为XML数据。在这个序列化过程中,如果WCF中的数据对象没有设置命名空间,则MSMQ不会序列化这个对象中各个属性的值,这是可以理解的,XML规范要求必须通过命名空间区分开不同来源的XML数据中可能同名的元素。


本文来自优快云博客,转载请标明出处:http://blog.youkuaiyun.com/bitfan/archive/2009/07/01/4312148.aspx

WCF中配置MSMQ作为输机制通常涉及以下几个步骤: 1. **安装依赖**:首先需要在你的项目中安装`System.Messaging`命名空间,这是MSMQ功能的一部分。如果使用NuGet包管理器,可以在项目中添加`System.Messaging`的引用。 2. **配置服务合同(Contract)**:声明一个接口或者类,这个接口将包含你的消息处理方法。例如: ```csharp [ServiceContract] public interface IMyQueueService { [OperationContract(IsOneWay = true)] void SendMessage(string message); } ``` 3. **创建 MSMQ 消息队列绑定**: ```xml <bindings> <netMsmqBinding> <binding name="MsmqBinding" queueName="MyQueue"> <!-- 添加其他配置项,如身份验证 --> <security mode="None"/> </binding> </netMsmqBinding> </bindings> ``` 4. **配置服务行为**: ```xml <behaviors> <serviceBehaviors> <behavior name="MsmqBehavior"> <serviceMetadata httpGetEnabled="true"/> <serviceDebug includeExceptionDetailInFaults="false"/> <msmqTransport> <queueTransaction/> <useActiveDirectoryForQueueManagement/> </msmqTransport> </behavior> </serviceBehaviors> </behaviors> ``` 5. **服务实现**:在`IMyQueueService`接口的实现类中,你可以使用`MessageQueue`类来操作MSMQ: ```csharp public class MsmqServiceImpl : IMyQueueService { public void SendMessage(string message) { MessageQueue queue = new MessageQueue("MyQueue"); var messageQueueTransaction = new MessageQueueTransaction(); queue.BeginTransaction(messageQueueTransaction); Message messageToBeSent = new Message(message); queue.Send(messageToBeSent, transaction: messageQueueTransaction); messageQueueTransaction.Commit(); } } ``` 6. **启用MSMQ输**:在`<services>`元素下,指定MSMQ绑定到你的服务: ```xml <services> <service behaviorConfiguration="MsmqBehavior" name="MyService"> <endpoint address="" binding="netMsmqBinding" bindingConfiguration="MsmqBinding" contract="IMyQueueService"/> </service> </services> ``` 完成以上配置后,当你调用`SendMessage`方法,消息就会被发送到指定的MSMQ队列。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值