我的目标是将PDF文件流返回给客户端。
所以在WCF方面我有:
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;
}
}
配置部分如下:
<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>
现在在客户端(例如控制台应用程序),当我创建服务引用时,我希望看到我的basicHttpBinding StreamedHttp配置,而是生成以下配置:
<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>
我认为由于这个原因,我得到一个ProtocolException异常说
响应消息的内容类型application / pdf没有 匹配绑定的内容类型(text / xml; charset = utf-8)。
如何强制客户端接受WCF端定义的流配置?
谢谢
答案 0 :(得分:4)
这是经过测试的控制台应用。只需创建&#34;文件&#34;可执行文件中的目录,将文件放入其中,然后将此类http://localhost:8088/fileServer/a.pdf
粘贴到您的浏览器中。
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:如果需要,您可以删除 if-not-modified 代码,如果客户端有 uptodate 版本,则不会重新发送同一文件。