Asp.net WCF流媒体,带返回字节数组的消息协定

Asp.net WCF流媒体,带返回字节数组的消息协定,asp.net,wcf,.net-4.0,streaming,Asp.net,Wcf,.net 4.0,Streaming,我一直在寻找答案,但什么也没找到。我想我遗漏了一些简单的东西,但我不知道是什么 我已经在我们的一个WCF服务中添加了一个方法,该方法应该作为消息契约的一部分返回流。但是,当我在客户端添加服务引用时,消息协定的流部分是字节数组,而不是流。我添加了基本相同的方法,没有消息契约(这将不是一个选项),并且该方法是客户端的流 服务合同 消息契约 服务代码 在客户端将其配置为返回字节数组: [FaultContract( typeof( ServiceException ), Name = "Service

我一直在寻找答案,但什么也没找到。我想我遗漏了一些简单的东西,但我不知道是什么

我已经在我们的一个WCF服务中添加了一个方法,该方法应该作为消息契约的一部分返回流。但是,当我在客户端添加服务引用时,消息协定的流部分是字节数组,而不是流。我添加了基本相同的方法,没有消息契约(这将不是一个选项),并且该方法是客户端的流

服务合同 消息契约 服务代码 在客户端将其配置为返回字节数组:

[FaultContract( typeof( ServiceException ), Name = "ServiceException", Namespace = "http://services.mycompanycom/Common/" )]
public FileStreamResponse GetFileStream( FileIDMessage message ) {
    CheckRights( message.AuthTicket, message.FileID, EntityEnum.Blob );

    var blob = new BlobBroker( ).GetByPk( message.GetSecurityTicket( ), message.FileID );
    if( blob.PkBlob == 0 || blob.BlobData == null )
        throw ServiceUtilities.LogError( "File record not found.", "File record not found.", MethodBase.GetCurrentMethod( ) );
    var response = new FileStreamResponse {
                                              FileName = blob.FileName,
                                              IsZip = blob.IsZip,
                                              Length = blob.BlobData.Length,
                                              FileByteStream = new MemoryStream( blob.BlobData )
                                          };
    response.FileByteStream.Position = 0;
    return response;
}
在客户端将其配置为流:

[FaultContract( typeof( ServiceException ), Name = "ServiceException", Namespace = "http://services.mycompanycom/Common/" )]
public Stream GetFileStream2( AuthTicket ticket, int FileID ) {
    var f = new FileIDMessage {
                                  FileID = FileID,
                                  AuthTicket = ticket
                              };
    return this.GetFileStream( f ).FileByteStream;
}
服务器配置
显然,这就是问题所在(不是上面代码的一部分,而是传递给GetFileStream方法的类):


如果我删除(IsWrapped=false),它将返回一个流而不是一个字节数组。

能否显示客户端代码以及为每种情况生成的客户端代理代码。您使用的是svcutil还是类似的工具?如果是这样,您将使用哪些选项来生成客户端代理?生成的代码现在就在那里。所有尝试都已通过VS2012添加服务引用。这次我只是接受了默认设置,尽管我已经使用了选中/取消选中允许生成异步操作并始终生成消息协定。我强烈建议您使用svcutil或wscfblue而不是VSQUANGE。。。在生成的客户端代理中,我想知道PropertyChanged事件变量是否导致了问题。由于流必须是消息约定中唯一的参数……我使用svcuti(除名称空间外没有其他选项)重新生成了它,虽然它没有添加INotifyPropertyChanged代码,但它仍然以字节数组而不是流的形式生成属性。但是,当我查看由?singleWsdl生成的wsdl时,两者都列为StreamBody类型。我目前遇到(几乎)相同的问题,但我无法删除IsWrapped=false标志。有没有别的办法克服这个问题?没有,对不起。这是我找到的唯一解决办法。也就是说,一旦我发现了,我就不再寻找了。
[FaultContract( typeof( ServiceException ), Name = "ServiceException", Namespace = "http://services.mycompanycom/Common/" )]
public FileStreamResponse GetFileStream( FileIDMessage message ) {
    CheckRights( message.AuthTicket, message.FileID, EntityEnum.Blob );

    var blob = new BlobBroker( ).GetByPk( message.GetSecurityTicket( ), message.FileID );
    if( blob.PkBlob == 0 || blob.BlobData == null )
        throw ServiceUtilities.LogError( "File record not found.", "File record not found.", MethodBase.GetCurrentMethod( ) );
    var response = new FileStreamResponse {
                                              FileName = blob.FileName,
                                              IsZip = blob.IsZip,
                                              Length = blob.BlobData.Length,
                                              FileByteStream = new MemoryStream( blob.BlobData )
                                          };
    response.FileByteStream.Position = 0;
    return response;
}
[FaultContract( typeof( ServiceException ), Name = "ServiceException", Namespace = "http://services.mycompanycom/Common/" )]
public Stream GetFileStream2( AuthTicket ticket, int FileID ) {
    var f = new FileIDMessage {
                                  FileID = FileID,
                                  AuthTicket = ticket
                              };
    return this.GetFileStream( f ).FileByteStream;
}
<system.serviceModel>
    <services>
        <service behaviorConfiguration="BasicServiceBehavior" name="MyCompany.Web.MyServices.FileService">
            <endpoint address="" behaviorConfiguration="secureEndpointBehavior"
                binding="basicHttpBinding" bindingConfiguration="StreamingBinding"
                contract="MyCompany.Web.MyServices.IFileService" />
        </service>
    </services>
    <bindings>
        <basicHttpBinding>
            <binding name="StreamingBinding" receiveTimeout="00:10:00"
                 sendTimeout="00:10:00" maxBufferSize="65536" maxReceivedMessageSize="2147483647" transferMode="StreamedResponse"
                 textEncoding="utf-8">
                <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
                     maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
                <security mode="None">
                    <transport clientCredentialType="None" />
                </security>
            </binding>
        </basicHttpBinding>
        <webHttpBinding>
            <binding name="webHttpBindingWithCrossDomain"/>
        </webHttpBinding>
    </bindings>
    <behaviors>
        <endpointBehaviors>
            <behavior name="secureEndpointBehavior" >
                <dataContractSerializer maxItemsInObjectGraph="2147483646" />
                <authorizationInspector /> 
                <operationLogger />
                <wsdlExtras location="http://localservices.mycompany.com/" exportXmlComments="false" singleFile="false" />
            </behavior>
        </endpointBehaviors>
        <serviceBehaviors>
            <behavior name="BasicServiceBehavior">
                <dataContractSerializer maxItemsInObjectGraph="2147483646" />
                <serviceMetadata httpGetEnabled="true" httpsGetEnabled="false" />
                <!-- need to update in build script -->
                <serviceDebug includeExceptionDetailInFaults="true" />
                <secureMetadata locationUrl="http://localservices.mycompany.com/" />
                <exceptionHandler />
            </behavior>
        </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
</system.serviceModel>
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.0.30319.18033")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://services.mycompany.com/Data/")]
public partial class FileStreamResponse : object, System.ComponentModel.INotifyPropertyChanged {

    private byte[] fileByteStreamField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(DataType="base64Binary", Order=0)]
    public byte[] FileByteStream {
        get {
            return this.fileByteStreamField;
        }
        set {
            this.fileByteStreamField = value;
            this.RaisePropertyChanged("FileByteStream");
        }
    }

    public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;

    protected void RaisePropertyChanged(string propertyName) {
        System.ComponentModel.PropertyChangedEventHandler propertyChanged = this.PropertyChanged;
        if ((propertyChanged != null)) {
            propertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
        }
    }
}

[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
[System.ServiceModel.MessageContractAttribute(IsWrapped=false)]
public partial class FileStreamResponse1 {

    [System.ServiceModel.MessageHeaderAttribute(Namespace="http://services.mycompany.com/Data/")]
    [System.Xml.Serialization.XmlElementAttribute(IsNullable=true)]
    public string FileName;

    [System.ServiceModel.MessageHeaderAttribute(Namespace="http://services.mycompany.com/Data/")]
    public bool IsZip;

    [System.ServiceModel.MessageHeaderAttribute(Namespace="http://services.mycompany.com/Data/")]
    public long Length;

    [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://services.mycompany.com/Data/", Order=0)]
    public ServiceTest.MyCompanyServices.FileStreamResponse FileStreamResponse;

    public FileStreamResponse1() {
    }

    public FileStreamResponse1(string FileName, bool IsZip, long Length, ServiceTest.MyCompanyServices.FileStreamResponse FileStreamResponse) {
        this.FileName = FileName;
        this.IsZip = IsZip;
        this.Length = Length;
        this.FileStreamResponse = FileStreamResponse;
    }
}

[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
[System.ServiceModel.MessageContractAttribute(WrapperName="GetFileStream2Response", WrapperNamespace="http://services.mycompany.com/Data/", IsWrapped=true)]
public partial class GetFileStream2Response {

    [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://services.mycompany.com/Data/", Order=0)]
    public System.IO.Stream GetFileStream2Result;

    public GetFileStream2Response() {
    }

    public GetFileStream2Response(System.IO.Stream GetFileStream2Result) {
        this.GetFileStream2Result = GetFileStream2Result;
    }
}
class Program {
    static void Main( string[ ] args ) {
        var svc = new FileServiceClient( );
        Console.WriteLine( "Logging in..." );
        var ticket = svc.Logon( "userid", "password" );
        Console.WriteLine( "Calling service..." );
        FileStreamResponse fsr;
        bool isZip;
        long size;
        string filename = svc.GetFileStream( ticket, 51575, out isZip, out size, out fsr );
        if( fsr != null && fsr.FileByteStream != null ) { // fsr.FileByteStream is byte[]
            Console.WriteLine( "Filename: {0}", filename );
            Console.WriteLine( "Zip: {0}", isZip );
            Console.WriteLine( "Length: {0}", size );
            Console.WriteLine( "Saving file..." );
            using( var fs = new FileStream( Path.Combine( @"c:\temp", filename ), FileMode.OpenOrCreate, FileAccess.Write ) ) {
                const int bufferSize = 65536;
                var buffer = new byte[ bufferSize ];
                //var bytesRead = response.FileStreamResponse.FileByteStream.
            }
        }
        Console.WriteLine( "Press ENTER to exit." );
        Console.ReadLine( );
    }
}
[MessageContract(IsWrapped = false)]
public class FileIDMessage : SecureMessageBase
{
    [MessageBodyMember]
    public int FileID;
}