1

我在使用自托管 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;
        }
    }
}
4

1 回答 1

4

当您使用 时WebServiceHost,您通常不需要添加服务端点 - 它会添加一个具有使其成为“Web HTTP”(又名 REST)端点(即不使用 SOAP 和您可以使用 Fiddler 等工具轻松消费,这似乎是您想要的)。此外,Web HTTP 端点未在 WSDL 中公开,因此您无需添加ServiceMetadataBehavior任何一个。

现在解释为什么它不起作用 - 发送一个 GET 请求http://localhost:8000/Test应该起作用 - 在下面的代码中它确实起作用。尝试运行此代码,并使用 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();
    }
}
于 2013-03-29T15:27:56.403 回答