WCF REST自托管400错误请求

时间:2013-03-29 14:55:34

标签: wcf rest self-hosting

我遇到了自托管WCF REST服务的问题。

当我尝试通过浏览器或Fiddler发出GET时,我收到400 Bad Request。跟踪报告XmlException的内部异常“无法读取消息正文,因为它是空的。”

我在app.config中没有任何配置(我需要吗?)。我已经尝试将WebServiceHost更改为ServiceHost,并返回WSDL,但操作仍然返回400.

我在这里缺少什么?

// Add Reference to System.ServiceModel and System.ServiceModel.Web
using System;
using System.Diagnostics;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.ServiceModel.Web;

namespace WCFRESTTest
{
    class Program
    {
        static void Main(string[] args)
        {
            var baseAddress = new Uri("http://localhost:8000/");
            var host = new WebServiceHost(typeof(RestService), baseAddress);

            try
            {
                host.AddServiceEndpoint(typeof(IRestService), new WSHttpBinding(), "RestService");

                var smb = new ServiceMetadataBehavior();
                smb.HttpGetEnabled = true;
                host.Description.Behaviors.Add(smb);

                host.Open();
                Console.WriteLine("Service Running.  Press any key to stop.");
                Console.ReadKey();
            }
            catch(CommunicationException ce)
            {
                host.Abort();
                throw;
            }
        }
    }

    [ServiceContract]
    public interface IRestService
    {
        [OperationContract]
        [WebGet(UriTemplate = "Test")]
        bool Test();
    }

    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
    public class RestService : IRestService
    {
        public bool Test()
        {
            Debug.WriteLine("Test Called.");
            return true;
        }
    }
}

1 个答案:

答案 0 :(得分:3)

当您使用WebServiceHost时,通常不需要添加服务端点 - 它将添加一个具有使其成为“Web HTTP”(也称为REST)端点所需的所有行为的端点(即,不使用SOAP的端点,您可以使用Fiddler等工具轻松使用,这似乎是您想要的。此外,Web HTTP endpoints aren't exposed in the WSDL,因此您无需添加ServiceMetadataBehavior

现在为什么它不起作用 - 向http://localhost:8000/Test发送GET请求应该有效 - 并且在下面的代码中也是如此。尝试运行此代码,并发送您之前发送给Fiddler的请求,以查看差异。这应该指出你有什么问题。

public class StackOverflow_15705744
{
    [ServiceContract]
    public interface IRestService
    {
        [OperationContract]
        [WebGet(UriTemplate = "Test")]
        bool Test();
    }

    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
    public class RestService : IRestService
    {
        public bool Test()
        {
            Debug.WriteLine("Test Called.");
            return true;
        }
    }

    public static void Test()
    {
        var baseAddress = new Uri("http://localhost:8000/");
        var host = new WebServiceHost(typeof(RestService), baseAddress);

        // host.AddServiceEndpoint(typeof(IRestService), new WSHttpBinding(), "RestService");

        // var smb = new ServiceMetadataBehavior();
        // smb.HttpGetEnabled = true;
        // host.Description.Behaviors.Add(smb);

        host.Open();

        WebClient c = new WebClient();
        Console.WriteLine(c.DownloadString(baseAddress.ToString().TrimEnd('/') + "/Test"));

        Console.WriteLine("Service Running.  Press any key to stop.");
        Console.ReadKey();
    }
}