c# - 如何将文件上传到 IIS 中托管的 .NET 3.5 WCF 服务?

标签 c# wcf iis .net-3.5 file-upload

我已经把头发扯了一段时间了。有人可以提供一个非常简单的示例(或工作示例的链接),说明如何将文件上传到 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/

相关文章:

c# - 对 ref T 的 TypedReference 抛出 BadImageFormatException

C#:获取设备实例句柄时出错

c# - 如何限制编码的 UI 测试控件搜索

c# - 自托管 WCF 服务

WCF - 处理来自多个客户端的请求

iis - Umbraco 6 部署到生产环境,页面呈现空白

c# - 如何在 C# 中使用 List 的范围?

c# - 测试 WCF Web 服务

iis - 在 WiX 中如何通过名称选择 IIS 网站?

css - IIS - 浏览文件时拒绝访问