简体   繁体   中英

How to upload a file to a .NET 3.5 WCF service hosted in IIS?

I've been ripping my hair out for a while now. Can someone provide a really simple example (or a link to a working example) of how to upload a file to a WCF service hosted in IIS.

I've started with something simple. I want to call a URL from a client via POST, pass the name of the file and send the file as well. So I added the following to the contract:

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

The implemented it in the .svc file:

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

Immediately, I get an error upon running the project:

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

Not sure where to go from here. Would love to see an actual working example.

PS I did this in .NET 4 with WCF 4 and it seemed a lot simpler, but I've had to downgrade. In .NET 3.5, I am missing something.

In order for it to work you need to define an endpoint with a binding compatible with WebHttpBinding and which has the WebHttpBehavior added to it. The message may be a red herring, it's an old bug which if you browse to the service base address, and if you have metadata enabled, it will show up. Another issue is that if you want to be able to upload any file type (including JSON and XML), you'll need to define a WebContentTypeMapper to tell WCF not to try to understand your file (more info at http://blogs.msdn.com/b/carlosfigueira/archive/2008/04/17/wcf-raw-programming-model-receiving-arbitrary-data.aspx ).

This is a complete example which does that. The biggest problem with 3.5 is that the ContentTypeMapper property doesn't exist on the WebHttpBinding, so you need to use a custom binding for that. This code defines the endpoint using a custom ServiceHostFactory , but it could be defined using config as well.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM