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

在WCF中使用NetMsmqBinding时,若服务协定涉及自定义对象,如MyDataItem,未设置命名空间会导致MSMQ无法正确序列化对象属性。解决方法是在自定义对象上指定一个唯一的命名空间。

摘要生成于 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数据中可能同名的元素。

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队列。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值