我已经把头发扯了一段时间了。有人可以提供一个非常简单的示例(或工作示例的链接),说明如何将文件上传到 IIS 中托管的 WCF 服务。
我从一些简单的事情开始。我想通过 POST 从客户端调用 URL,传递文件名并发送文件。所以我在契约(Contract)中添加了以下内容:
[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));
}
运行项目时我立即收到错误:
要使上传操作中的请求成为流,该操作必须具有一个类型为 Stream 的参数。
不知道从这里去哪里。希望看到一个实际的工作示例。
附注我在 .NET 4 中使用 WCF 4 执行此操作,看起来简单得多,但我不得不降级。在 .NET 3.5 中,我遗漏了一些东西。
最佳答案
为了使其正常工作,您需要定义一个端点,该端点具有与 WebHttpBinding
兼容的绑定(bind),并且添加了 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 属性,因此您需要为此使用自定义绑定(bind)。此代码使用自定义 ServiceHostFactory
定义端点,但也可以使用配置来定义它。
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<WebMessageEncodingBindingElement>().ContentTypeMapper = new MyRawMapper();
ServiceEndpoint endpoint = this.AddServiceEndpoint(typeof(IUploader), binding, "");
endpoint.Behaviors.Add(new WebHttpBehavior());
}
}
}
}
关于c# - 如何将文件上传到 IIS 中托管的 .NET 3.5 WCF 服务?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6949668/