WCF Chunking / Streaming

2019-03-09 03:12发布

问题:

I'm using WCF and want to upload a large file from the client to the server. I have investigated and decided to follow the chunking approach outlined at http://msdn.microsoft.com/en-us/library/aa717050.aspx

However, this approach (just like streaming) restricts the contract to limited method signitures:

[OperationContract(IsOneWay=true)]
[ChunkingBehavior(ChunkingAppliesTo.InMessage)]
void UploadStream(Stream stream);

The sample uses the rather convenient example of uploading a file from a fixed path and saving it to a fixed path on the server. Therefore, my question is how do I pass additional parameters to specify things like filename, filepath etc.

eg. I would like something like:

[OperationContract(IsOneWay=true)]
[ChunkingBehavior(ChunkingAppliesTo.InMessage)]
void UploadStream(Stream stream, String filePath);

Thanks in advance, Mark.

回答1:

This article explains how to use the MessageHeader attribute to force things to be passed in the header, and therefore not count as a parameter. So, instead of passing a stream and other meta data, create a class that has the attribute MessageContract and mark all of the meta data as a MessageHeader. Then, mark the stream as a MessageBodyMember (which the article incorrect calls "MessageBody"). Have your UploadStream method take a single parameter whose type is that of the MessageContract class you've just created. I've done this successfully, but I haven't done it in tandem with chunking. Good luck.



回答2:

You could make your service session-ful and have an initialization method in the contract with the IsInitiating property set to true. Something like:

[OperationContract(IsInitiating = true)]
void InitializeUploadService(string filename);

[OperationContract(IsOneWay = true, IsInitiating = false)]
[ChunkingBehavior(ChunkingAppliesTo.InMessage)]
void UploadStream(Stream stream);

I have never tried it with streaming services but it should basically make WCF enforce that InitializeUploadService is always called before UploadStream.

More documentation can be found here: http://msdn.microsoft.com/en-us/library/system.servicemodel.description.operationdescription.isinitiating.aspx



回答3:

I would look at MessageContracts and add those values as message headers to your object. This should allow you to pass the stream and any values related to the stream as message headers.



回答4:

Setting up the maxItemsInObjectGraph in the Client side and Server side worked for me.

(Dont forget the client side.) http://social.msdn.microsoft.com/Forums/en/wcf/thread/0af69654-2d89-44f3-857a-583b57844ca5