locked
How do I set Content-Length header from an IDataServiceStreamProvider RRS feed

  • Question

  • Hi,

    I have my own implementation of IDataServiceStreamProvider. How do I set the Content-Length response header from my GetReadStream implementation. It has no effect doing

    operationContext.ResponseHeaders.Add(HttpResponseHeader.ContentLength, length);

    I would actually expect the header to be set automatically by the framework to the value of my the Stream's Length property, but this is not happening.

    Regards

    Uffe

    Monday, April 23, 2012 8:22 AM

Answers

  • Well what do you know...

    For those interessted:

    It seems that setting the Content-Length via HttpContext.Current.Response.Headers.Add("Content-Length", myStream.Length.ToString()) does the trick when I set it in my IDataServiceStreamProvider implementation of GetReadStream().

    Now IE is displaying a nice progress bar :-)

    Regards

    Uffe

    • Marked as answer by Uffe Lauesen Thursday, May 10, 2012 10:07 AM
    Thursday, May 10, 2012 10:07 AM

All replies

  • Hi,

    Assuming you're using true streaming mode in WCF then the content length can't really be set. The headers must be set before the first byte of the response is written, but since the real length is only known once all the bytes are written, it can't be done. So truly streaming services sometimes don't set the header.

    Why do you need the header to be set on the response. Clients should be able to consume the response without the header.

    Thanks,


    Vitek Karas [MSFT]

    Monday, April 23, 2012 10:25 AM
    Moderator
  • Hi Vitek,

    Maybe you are correct, but...

    I do know the length of the document beforehand.

    I would like to add the header to have a client like IE display a nice progress bar of the download progress.

    The headers are not sent to the client before the GetReadStream is called. I can add other headers with success - like the Content-Disposition header to have a proper file name in IE.

    I just do not understand why I can't add the Content-Length header - it doesn't fail, but is not being sent to the client.

    Regards

    Uffe


    Monday, April 23, 2012 10:37 AM
  • Anyone know if it can be done and how or why not?
    Tuesday, April 24, 2012 9:49 PM
  • Hi,

    I verified that GetReadStream is called during the request processing stage, that is you should be able to set response headers still. I don't know why setting it the way you do above doesn't work. It might be that WCF ignores the header in the response header collection. I don't have a stream provider implementation handy I could play with right now. Maybe try to set different custom header just to verify that setting the headers works at all (I would expect it to work).

    Thanks,


    Vitek Karas [MSFT]

    Wednesday, April 25, 2012 8:15 AM
    Moderator
  • Hi Vitek,

    I already have the Content-Disposition header set - and that successfully is sent to the client.

    Uffe

    Wednesday, April 25, 2012 10:12 AM
  • Hi,

    I just found this...

    https://connect.microsoft.com/VisualStudio/feedback/details/366324/support-non-chunked-streamed-responses-on-wcf-httptransport#details

    Reported on .net 3.5 SP1 - looks like it is still not fixed in .net 4.0.

    Overall it looks like it is a bug in WCF part of .net framework.

    Anyone have any idea if/when it is going to be fixed?

    Uffe

    Wednesday, April 25, 2012 10:25 AM
  • Are there any workarounds for this?

    Currently clients will have no way of knowing if they got the whole document or it was truncated due to an error (network or service related) unless I can specify the Content-Length.

    Also: If i provoke an exception from my server stream during reading the exception is sent on the stream (note I have UserVerboseErrors set to true) - this can't be right. I know it can't send status 500 - the heaaders are already sent.

    This is driving me crazy.
    Thursday, May 3, 2012 1:09 PM
  • Is it just me that is concerned about this?

    I think it is a rather severe problem.

    1. Clients have no way of knowing if an error occured during streaming of the document ($values GET requests).

    2. Exceptions details is returned in the end of the Stream if an error occurs at the server. The Client treats that as part of the document.

    How can i make streaming of documents ($value) GET requests reliable in my DS custom provider?

    Regards

    Uffe

    Wednesday, May 9, 2012 6:09 AM
  • Hi,

    I honestly don't know the answer to this scenario. It's an HTTP wide problem. Once you wrote the headers there's nothing in HTTP which lets you specify an error state. And since the data you're transferring don't have such ability (since it's binary), that's it. I think that most clients will recognize if the server forcibly closes the connection though, but I haven't tried that.

    Thanks,


    Vitek Karas [MSFT]

    Wednesday, May 9, 2012 10:54 AM
    Moderator
  • Thanks Vitek,

    I will try to see what happens if I do that. At least it seems that IE recognises an error occured if kill the w3wp process servicing the request, so maybe there is hope.

    I will update this thread once I find out if this can be provoked from code and if it works.

    Regards

    Uffe

    Wednesday, May 9, 2012 11:16 AM
  • Well what do you know...

    For those interessted:

    It seems that setting the Content-Length via HttpContext.Current.Response.Headers.Add("Content-Length", myStream.Length.ToString()) does the trick when I set it in my IDataServiceStreamProvider implementation of GetReadStream().

    Now IE is displaying a nice progress bar :-)

    Regards

    Uffe

    • Marked as answer by Uffe Lauesen Thursday, May 10, 2012 10:07 AM
    Thursday, May 10, 2012 10:07 AM
  • Cool - thanks a lot for trying it sharing the workaround!

    Vitek Karas [MSFT]

    Thursday, May 10, 2012 12:48 PM
    Moderator