Чтобы это работало, вам нужно определить конечную точку с привязкой, совместимой с 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 заключается в том, что свойство ContentTypeMapper не существует в WebHttpBinding, поэтому для этого нужно использовать настраиваемую привязку. Этот код определяетконечная точка использует пользовательский 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<WebMessageEncodingBindingElement>().ContentTypeMapper = new MyRawMapper();
ServiceEndpoint endpoint = this.AddServiceEndpoint(typeof(IUploader), binding, "");
endpoint.Behaviors.Add(new WebHttpBehavior());
}
}
}
}