如何将文件上载到IIS中托管的.NET 3.5 WCF服务?

我已经把头发拉了一段时间了。 有人可以提供一个非常简单的示例(或工作示例的链接),说明如何将文件上载到IIS中托管的WCF服务。

我从简单的事情开始。 我想通过POST从客户端调用URL,传递文件名并发送文件。 所以我在合同中添加了以下内容:

[OperationContract] [WebInvoke(Method = "POST", UriTemplate = "/UploadFile?fileName={fileName}")] void Upload(string fileName, Stream stream); 

在.svc文件中实现它:

 public void Upload(string fileName, Stream stream) { Debug.WriteLine((fileName)); } 

我立即在运行项目时遇到错误:

For request in operation Upload to be a stream the operation must have a single parameter whose type is Stream.

不知道从哪里开始。 很想看到一个真实的工作示例。

PS我在.NET 4中用WCF 4做了这个,它看起来简单得多,但我不得不降级。 在.NET 3.5中,我遗漏了一些东西。

为了使它能够工作,您需要使用与WebHttpBinding兼容的绑定定义端点,并添加WebHttpBehavior 。 该消息可能是一个红色的鲱鱼,这是一个旧的错误,如果您浏览到服务基地址,并且如果您启用了元数据,它将显示。 另一个问题是,如果您希望能够上传任何文件类型(包括JSON和XML),则需要定义WebContentTypeMapper以告知WCF不要尝试理解您的文件(更多信息请访问http:// blogs。 msdn.com/b/carlosfigueira/archive/2008/04/17/wcf-raw-programming-model-receiving-arbitrary-data.aspx )。

这是一个完整的例子。 3.5的最大问题是WebHttpBinding上不存在ContentTypeMapper属性,因此您需要使用自定义绑定。 此代码使用自定义ServiceHostFactory定义端点,但也可以使用config定义端点。

Service.svc

 <%@ ServiceHost Language="C#" Debug="true" Service="MyNamespace.MyService" Factory="MyNamespace.MyFactory" %> 

Service.cs

 using System; using System.Diagnostics; using System.IO; using System.ServiceModel; using System.ServiceModel.Activation; using System.ServiceModel.Channels; using System.ServiceModel.Description; using System.ServiceModel.Web; public class MyNamespace { [ServiceContract] public interface IUploader { [OperationContract] [WebInvoke(Method = "POST", UriTemplate = "/UploadFile?fileName={fileName}")] void Upload(string fileName, Stream stream); } public class Service : IUploader { public void Upload(string fileName, Stream stream) { Debug.WriteLine(fileName); } } public class MyFactory : ServiceHostFactory { protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses) { return new MyServiceHost(serviceType, baseAddresses); } class MyRawMapper : WebContentTypeMapper { public override WebContentFormat GetMessageFormatForContentType(string contentType) { return WebContentFormat.Raw; } } public class MyServiceHost : ServiceHost { public MyServiceHost(Type serviceType, Uri[] baseAddresses) : base(serviceType, baseAddresses) { } protected override void OnOpening() { base.OnOpening(); CustomBinding binding = new CustomBinding(new WebHttpBinding()); binding.Elements.Find().ContentTypeMapper = new MyRawMapper(); ServiceEndpoint endpoint = this.AddServiceEndpoint(typeof(IUploader), binding, ""); endpoint.Behaviors.Add(new WebHttpBehavior()); } } } }