2016-04-09 8 views
0

Mein Ziel ist es, einen PDF-Datei-Stream zurück zum Client zu senden.WCF Streamed PDF Antwort

So in WCF Seite habe ich:

public interface IPersonalPropertyService 
    { 
     [OperationContract] 
     Stream GetQuotation(); 
    } 

public class PersonalPropertyService : IPersonalPropertyService 
    { 
     public Stream GetQuotation() 
     { 
      var filePath = HostingEnvironment.ApplicationPhysicalPath + @"Quotation.pdf"; 
      var fileInfo = new FileInfo(filePath); 
      // check if exists 
      if (!fileInfo.Exists) 
       throw new FileNotFoundException("File not found"); 
      FileStream stm = File.Open(filePath, FileMode.Open); 
      WebOperationContext.Current.OutgoingResponse.ContentType = "application/pdf"; 
      return stm; 
     } 
    } 

Der Konfigurationsteil ist wie folgt:

<system.serviceModel> 
    <client> 
     <endpoint 
     binding="basicHttpBinding" 
     bindingConfiguration="StreamedHttp" 
     contract="IPersonalPropertyService" > 
     </endpoint> 
    </client> 
    <bindings> 
     <basicHttpBinding> 
     <binding name="StreamedHttp" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647" 
      transferMode="Streamed"> 
      <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" 
      maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" /> 
     </binding> 
     </basicHttpBinding> 
    </bindings> 

    <behaviors> 
     <serviceBehaviors> 
     <behavior> 
      <!-- To avoid disclosing metadata information, set the values below to false before deployment --> 
      <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/> 
      <!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information --> 
      <serviceDebug includeExceptionDetailInFaults="false"/> 
     </behavior> 
     </serviceBehaviors> 
    </behaviors> 
    </system.serviceModel> 

nun auf der Client-Seite (zB Konsole app), wenn ich den Dienstverweis erstellen, Ich würde erwarten, meine basicHttpBinding StreamedHttp-Konfiguration zu sehen, aber stattdessen wird die folgende Konfiguration generiert:

und ich rechne damit, dass wegen diesem Grund sage ich eine Ausnahme Protocol bekommen

Der Inhaltstyp application/pdf der Antwortnachricht nicht Spiel der Inhaltstyp der Bindung (text/xml; charset = utf-8).

Wie kann ich den Client zwingen, die auf der WCF-Seite definierte gestreamte Konfiguration zu akzeptieren?

Vielen Dank

+0

Was erhalten Sie, wenn Sie in Browsern "http: //....../ GetQuotation" eingeben? – Eser

+0

Ich habe die web.config geändert, um mit dem Browser zu interagieren, und jetzt, wenn ich http: //..../PersonalPropertyService.svc/GetQuotation mache, bekomme ich: Methode nicht erlaubt. – Nostradamus

+0

Ich konnte nie WCF Conf-Dateien lesen, aber wenn Sie interessiert sind, kann ich einen selbst gehosteten WCF-Server basierend auf WebServiceHost, der Dateien – Eser

Antwort

3

Hier ist eine getestete Konsole App. Erstellen Sie einfach das Verzeichnis "Files" in Ihrer ausführbaren Datei, fügen Sie Ihre Dateien ein und fügen Sie etwas wie dieses http://localhost:8088/fileServer/a.pdf in Ihren Browser ein.

using System; 
using System.Collections.Generic; 
using System.IO; 
using System.Linq; 
using System.Net; 
using System.ServiceModel; 
using System.ServiceModel.Channels; 
using System.ServiceModel.Web; 
using System.Text; 
using System.Web; 

namespace SampleWCFConsoleApplication 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      FileServer.Start(); 
     } 
    } 

    [ServiceContract] 
    public class FileServer 
    { 
     static WebServiceHost _Host; 
     public static void Start() 
     { 
      _Host = new WebServiceHost(typeof(FileServer), new Uri("http://0.0.0.0:8088/FileServer")); 
      _Host.Open(); 
      Console.ReadLine(); 
     } 

     [OperationContract, WebGet(UriTemplate = "*")] 
     public Message Get() 
     { 
      var ctx = WebOperationContext.Current; 

      var fileName = Path.Combine("Files", String.Join("/", WebOperationContext.Current.IncomingRequest.UriTemplateMatch.RelativePathSegments)); 

      var fInfo = new FileInfo(fileName); 

      var eTag = ctx.IncomingRequest.Headers[HttpRequestHeader.IfNoneMatch]; 
      if (!string.IsNullOrEmpty(eTag)) 
      { 
       if (GetETag(fInfo) == eTag) 
       { 
        ctx.OutgoingResponse.StatusCode = HttpStatusCode.NotModified; 
        return ctx.CreateTextResponse(""); 
       } 
      } 

      if (fInfo.Exists == false) return ReturnError(ctx, HttpStatusCode.NotFound); 
      return ReturnFile(ctx, fInfo); 
     } 

     static string GetETag(FileInfo fInfo) 
     { 
      return Convert.ToBase64String(Encoding.UTF8.GetBytes(fInfo.Name).Concat(BitConverter.GetBytes(fInfo.LastWriteTime.Ticks)).ToArray()); 
     } 

     public static Message ReturnError(WebOperationContext ctx, HttpStatusCode statusCode) 
     { 
      ctx.OutgoingResponse.StatusCode = statusCode; 
      return ctx.CreateTextResponse(statusCode.ToString(), "text/html"); 
     } 

     static Message ReturnFile(WebOperationContext ctx, FileInfo fInfo, HttpStatusCode statusCode = HttpStatusCode.OK) 
     { 
      ctx.OutgoingResponse.StatusCode = statusCode; 
      ctx.OutgoingResponse.ETag = GetETag(fInfo); 

      return ctx.CreateStreamResponse(File.OpenRead(fInfo.FullName), MimeMapping.GetMimeMapping(fInfo.Name)); 
     } 
    } 
} 

BTW: Wenn Sie möchten, können Sie entfernen Code if-nicht-modifizierte, es ist einfach nicht die gleiche Datei erneut zu senden, wenn der Client uptodate Version hat.

+1

danke sehr, sehr viel @ – Nostradamus

Verwandte Themen