2016-04-09 36 views
0

Amacım bir PDF dosyası akışını istemciye geri vermektir.WCF Yayımlanan PDF Yanıtı

Yani WCF tarafında ben:

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; 
     } 
    } 

yapılandırma bölümü aşağıdaki gibidir:

<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> 

Şimdi istemci tarafında (örneğin konsol uygulaması), ben hizmet başvurusu oluştururken, BasicHttpBinding StreamedHttp yapılandırmamı görmeyi beklerdim, ancak bunun yerine şu yapılandırma oluşturulur:

<system.serviceModel> 
     <bindings> 
      <basicHttpBinding> 
       <binding name="BasicHttpBinding_PersonalPropertyService" /> 
      </basicHttpBinding> 
     </bindings> 
     <client> 
      <endpoint address="MyPath/PersonalPropertyService.svc" 
       binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_PersonalPropertyService" 
       contract="TheNamespace.ServiceReference.PersonalPropertyService" 
       name="BasicHttpBinding_PersonalPropertyService" /> 
     </client> 
    </system.serviceModel> 

ve ben çünkü bu nedenle, diyordum bir ProtocolException istisna alıyorum olduğunu hesaba katmak

cevap mesajının içerik türü application/pdf değil maçı bağlayıcı (text/xml içerik türü yapar; karakter kümesi = UTF-8).

İstemciyi WCF tarafında tanımlanan akış yapılandırmasını kabul etmeye nasıl zorlayabilirim?

Teşekkür ederiz

+0

Tarayıcınızda 'http: //....../ GetQuotation' yazdığınızda ne olur? – Eser

+0

Web.config'i tarayıcıyla etkileşimde bulunduğum için değiştirdim ve şimdi http: //..../PersonalPropertyService.svc/GetQuotation, yaptığım zaman: Yönteme izin verilmiyor. – Nostradamus

+0

WCF conf dosyalarını hiçbir zaman okuyamamıştım, ancak ilgileniyorsanız, – Eser

cevap

3

İşte test edilmiş bir konsol uygulaması. Sadece kendi uygulamanızda "Dosyalar" dizinini oluşturun, dosyalarınızı buraya yerleştirin ve bu http://localhost:8088/fileServer/a.pdf gibi bir şeyi tarayıcınıza yapıştırın.

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: Eğer isterseniz, istemci çağcıl sürümü varsa sadece aynı dosyayı yeniden göndermeye değil, kodu modifiye değilse-kaldırabilirsiniz.

+1

teşekkürler çok çok @ @ – Nostradamus