是否可以使用带有MessageContract的WCF流式传输文件,该MessageContract包含另一个在其中包含Stream的MessageContract? 我认为答案是否定的,但我更倾向于将我的文件打包在“Root”消息中,可以这么说。
换句话说,我的设置是这样的:
[MessageContract] public class Transport { [MessageHeader] private readonly Guid fId; [MessageHeader] private readonly DateTime fTimestamp; [MessageBodyMember(Order = 1)] public FileTransferMessage FileTransferMessage { get; set; } } [MessageContract] public class FileTransferMessage : IDisposable { [MessageBodyMember(Order = 1)] public Stream FileByteStream; [MessageHeader(MustUnderstand = true)] public long FileLength; [MessageHeader(MustUnderstand = true)] public string FileName; }请求被发送和接收到服务就好了,但是,看起来Stream没有被正确地反序列化并且作为空引用返回。 我知道我已经在某个地方读过一条规则,该规则在一个带流的MessageContract上声明Stream必须是MessageContract的主体,而我认为这就是现在被侵犯的内容。 我希望FileTransferMessage是Body,然后Stream就是Body的身体是可以接受的。
有人对我能在这做什么有任何建议吗? 我不希望不将Stream / FileName / FileLength添加到我的Transport对象。
Is it possible to stream a file using WCF with a MessageContract that contains another MessageContract that has the Stream inside it? I think the answer is no, but I'd much prefer to package my file inside a "Root" message so to speak.
In otherwords my setup is like this:
[MessageContract] public class Transport { [MessageHeader] private readonly Guid fId; [MessageHeader] private readonly DateTime fTimestamp; [MessageBodyMember(Order = 1)] public FileTransferMessage FileTransferMessage { get; set; } } [MessageContract] public class FileTransferMessage : IDisposable { [MessageBodyMember(Order = 1)] public Stream FileByteStream; [MessageHeader(MustUnderstand = true)] public long FileLength; [MessageHeader(MustUnderstand = true)] public string FileName; }The request is sent and received to the service just fine, however, it appears the Stream is not being deserialized properly and coming back as null reference. I know I've read a rule somewhere that states on a MessageContract with Streaming that the Stream MUST be the Body of the MessageContract, and I'm thinking that is what is being violated right now. I was hoping that the FileTransferMessage being the Body and then the Stream being the Body of that would be acceptable.
Anyone have any suggestions on what I can do here? I'd prefer NOT to add a Stream/FileName/FileLength to my Transport object.
最满意答案
作为参与设计MessageContract的团队的一员,我可以告诉你答案是否定的:) MessageContract恰好代表一个完整的SOAP消息,你不能将它们相互嵌套(你的例子中的FileTransferMessage简单地交给了serializer,它对[MessageContract]属性一无所知并忽略它,并且对任何特殊的Stream行为一无所知。
如果没有创建自定义Message子类(甚至是自定义Stream子类),我想不出一个好的解决方案。 如果fId和fTimestamp在每条消息上,请考虑使用自定义Message Inspector注入这些消息,然后在操作中使用FileTransferMessage。
这里的权威文档是http://msdn.microsoft.com/en-us/library/ms730255.aspx和http://msdn.microsoft.com/en-us/library/ms733742.aspx
As someone who was part of the team designing MessageContract, I can tell you that the answer is no :) MessageContract represents exactly one full SOAP message, you can't nest them in each other (the FileTransferMessage in your example is simply handed to the serializer, which knows nothing about the [MessageContract] attribute and ignores it, and knows nothing about any special Stream behavior).
Short of creating a custom Message subclass (or even a custom Stream subclass), I can't think of a good solution. If fId and fTimestamp are on every message, consider using a custom Message Inspector to inject these, and then just use FileTransferMessage in your operation.
Authoritative documents here are http://msdn.microsoft.com/en-us/library/ms730255.aspx and http://msdn.microsoft.com/en-us/library/ms733742.aspx
更多推荐
发布评论