Wcf: Empty MemoryStream #1758

Created on 26 Sep 2017  路  10Comments  路  Source: dotnet/wcf

I am having the exact same issue from #1758 and I cannot seem to figure out a solution. Is there a proper fix to this? I have been trying for the past three days to get my .NET Core app working as the Full .NET Framework, but with no luck, the stream keeps being empty no matter what solution found online I implement. Any ideas on what I might be doing wrong? I have a Class Library targeting Core1.1 and Framework 4.5.

bug tooling

Most helpful comment

@AuroraBrignola @hristo-georgiev It looks like this is because MemoryStream isn't marked with the [Serializable] attribute in core, so we're failing to deserialize it correctly. I opened issue dotnet/coreclr#17460 in coreclr for this issue.

To work around this for now there are two options:
1) If you control the service you could change the operation to return a Stream instead of a MemoryStream and used TransferMode.Streamed.

2) If you're unable to modify the service you could create a local MemoryStream class that is marked as serializable and modify the generated Reference.cs file to use your local MemoryStream instead of System.IO.MemoryStream. That way the value will get deserialized into the class you defined, then you can convert it into a real MemoryStream to use in your client. The class could look something like this:
MemoryStream.txt

All 10 comments

Hi @AuroraBrignola can you please share the WSDL file and we can take a further look?

Hi @zhenlan here's the WSDL
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsa10="http://www.w3.org/2005/08/addressing" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsap="http://schemas.xmlsoap.org/ws/2004/08/addressing/policy" xmlns:msc="http://schemas.microsoft.com/ws/2005/12/wsdl/contract" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://tempuri.org/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" name="Service" targetNamespace="http://tempuri.org/"> <wsdl:types> <xsd:schema targetNamespace="http://tempuri.org/Imports"> <xsd:import schemaLocation="http://localhost:8733/Design_Time_Addresses/DwarfsWCF/Service/?xsd=xsd0" namespace="http://tempuri.org/"/> <xsd:import schemaLocation="http://localhost:8733/Design_Time_Addresses/DwarfsWCF/Service/?xsd=xsd1" namespace="http://schemas.microsoft.com/2003/10/Serialization/"/> <xsd:import schemaLocation="http://localhost:8733/Design_Time_Addresses/DwarfsWCF/Service/?xsd=xsd2" namespace="http://schemas.datacontract.org/2004/07/System.IO"/> <xsd:import schemaLocation="http://localhost:8733/Design_Time_Addresses/DwarfsWCF/Service/?xsd=xsd3" namespace="http://schemas.datacontract.org/2004/07/System"/> </xsd:schema> </wsdl:types> <wsdl:message name="IService_GetStream_InputMessage"> <wsdl:part name="parameters" element="tns:GetStream"/> </wsdl:message> <wsdl:message name="IService_GetStream_OutputMessage"> <wsdl:part name="parameters" element="tns:GetStreamResponse"/> </wsdl:message> <wsdl:message name="IService_GetString_InputMessage"> <wsdl:part name="parameters" element="tns:GetString"/> </wsdl:message> <wsdl:message name="IService_GetString_OutputMessage"> <wsdl:part name="parameters" element="tns:GetStringResponse"/> </wsdl:message> <wsdl:portType name="IService"> <wsdl:operation name="GetStream"> <wsdl:input wsaw:Action="http://tempuri.org/IService/GetStream" message="tns:IService_GetStream_InputMessage"/> <wsdl:output wsaw:Action="http://tempuri.org/IService/GetStreamResponse" message="tns:IService_GetStream_OutputMessage"/> </wsdl:operation> <wsdl:operation name="GetString"> <wsdl:input wsaw:Action="http://tempuri.org/IService/GetString" message="tns:IService_GetString_InputMessage"/> <wsdl:output wsaw:Action="http://tempuri.org/IService/GetStringResponse" message="tns:IService_GetString_OutputMessage"/> </wsdl:operation> </wsdl:portType> <wsdl:binding name="BasicHttpBinding_IService" type="tns:IService"> <soap:binding transport="http://schemas.xmlsoap.org/soap/http"/> <wsdl:operation name="GetStream"> <soap:operation soapAction="http://tempuri.org/IService/GetStream" style="document"/> <wsdl:input> <soap:body use="literal"/> </wsdl:input> <wsdl:output> <soap:body use="literal"/> </wsdl:output> </wsdl:operation> <wsdl:operation name="GetString"> <soap:operation soapAction="http://tempuri.org/IService/GetString" style="document"/> <wsdl:input> <soap:body use="literal"/> </wsdl:input> <wsdl:output> <soap:body use="literal"/> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:service name="Service"> <wsdl:port name="BasicHttpBinding_IService" binding="tns:BasicHttpBinding_IService"> <soap:address location="http://localhost:8733/Design_Time_Addresses/DwarfsWCF/Service/"/> </wsdl:port> </wsdl:service> </wsdl:definitions>

Thanks, @AuroraBrignola. @hongdai, can you please take a look?

@AuroraBrignola The wsdl file is not usable as it does not have all the schemas needed. Could you use
?singlewsdl option to produce a full wsdl that contains all necessary types?

Thanks,
Hong Dai

@hongdai Thank you
singleWSDL.txt

Hello
Do you have any progress with this issue?
I have the same problem, i'm using the contract which is generated with full .Net Framework and the MemoryStream is not wrapped in other object.

Hi @hristo-georgiev
We will be investigating this issue soon.

cc: @dasetser

@AuroraBrignola @hristo-georgiev It looks like this is because MemoryStream isn't marked with the [Serializable] attribute in core, so we're failing to deserialize it correctly. I opened issue dotnet/coreclr#17460 in coreclr for this issue.

To work around this for now there are two options:
1) If you control the service you could change the operation to return a Stream instead of a MemoryStream and used TransferMode.Streamed.

2) If you're unable to modify the service you could create a local MemoryStream class that is marked as serializable and modify the generated Reference.cs file to use your local MemoryStream instead of System.IO.MemoryStream. That way the value will get deserialized into the class you defined, then you can convert it into a real MemoryStream to use in your client. The class could look something like this:
MemoryStream.txt

@AuroraBrignola @hristo-georgiev It looks like this is because MemoryStream isn't marked with the [Serializable] attribute in core, so we're failing to deserialize it correctly. I opened issue dotnet/coreclr#17460 in coreclr for this issue.

To work around this for now there are two options:

  1. If you control the service you could change the operation to return a Stream instead of a MemoryStream and used TransferMode.Streamed.
  2. If you're unable to modify the service you could create a local MemoryStream class that is marked as serializable and modify the generated Reference.cs file to use your local MemoryStream instead of System.IO.MemoryStream. That way the value will get deserialized into the class you defined, then you can convert it into a real MemoryStream to use in your client. The class could look something like this:
    MemoryStream.txt

modify the generated Reference.cs file ---- which file need to modify

@mageshsankar If you're using dotnet-svcutil or the WCF Web Service Reference Provider you should have a file called Reference.cs inside a "Service Reference" folder. That's the file you would need to modify for this workaround.

Was this page helpful?
0 / 5 - 0 ratings