答えを探しましたが、何も見つかりませんでした。単純なものが欠けていると思いますが、それが何であるかわかりません。
メッセージ コントラクトの一部としてストリームを返すメソッドを、WCF サービスの 1 つに追加しました。ただし、クライアント側でサービス参照を追加すると、メッセージ コントラクトのストリーム部分はストリームではなくバイト配列になります。メッセージ コントラクト (これはオプションではありません) なしで本質的に同じメソッドを追加しました。これはクライアント側のストリームです。
サービス契約
[ServiceContract(Name = "FileService", Namespace = "http://services.mycompanycom/Data/")]
public interface IFileService : IServiceBase
{
[OperationContract( IsOneWay = false )]
[FaultContract( typeof( ServiceException ), Name = "ServiceException", Namespace = "http://services.mycompanycom/Common/" )]
FileStreamResponse GetFileStream( FileIDMessage message );
[OperationContract( IsOneWay = false )]
[FaultContract( typeof( ServiceException ), Name = "ServiceException", Namespace = "http://services.mycompanycom/Common/" )]
Stream GetFileStream2( AuthTicket ticket, int FileID );
}
メッセージ コントラクト
[MessageContract]
public sealed class FileStreamResponse {
[MessageHeader( MustUnderstand = true )]
public string FileName { get; set; }
[MessageHeader( MustUnderstand = true )]
public bool IsZip { get; set; }
[MessageHeader( MustUnderstand = true )]
public long Length { get; set; }
[MessageBodyMember( Order = 1 )]
public Stream FileByteStream;
}
サービスコード
これは、バイト配列を返すようにクライアント側で構成されます。
[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( );
}
}